1 /* 2 * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 */ 9 10 #include <sm/gen.h> 11 SM_RCSID("@(#)$Id: t-shm.c,v 1.18 2002/01/31 04:11:41 ca Exp $") 12 13 #include <stdio.h> 14 15 #if SM_CONF_SHM 16 # include <stdlib.h> 17 # include <unistd.h> 18 # include <sys/wait.h> 19 20 # include <sm/heap.h> 21 # include <sm/string.h> 22 # include <sm/test.h> 23 # include <sm/shm.h> 24 25 # define SHMSIZE 1024 26 # define SHM_MAX 6400000 27 # define T_SHMKEY 21 28 29 30 /* 31 ** SHMINTER -- interactive testing of shared memory 32 ** 33 ** Parameters: 34 ** owner -- create segment. 35 ** 36 ** Returns: 37 ** 0 on success 38 ** < 0 on failure. 39 */ 40 41 int shminter __P((bool)); 42 43 int 44 shminter(owner) 45 bool owner; 46 { 47 int *shm, shmid; 48 int i, j, t; 49 50 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 51 if (shm == (int *) 0) 52 { 53 perror("shminit failed"); 54 return -1; 55 } 56 57 while ((t = getchar()) != EOF) 58 { 59 switch (t) 60 { 61 case 'c': 62 *shm = 0; 63 break; 64 case 'i': 65 ++*shm; 66 break; 67 case 'd': 68 --*shm; 69 break; 70 case 's': 71 sleep(1); 72 break; 73 case 'l': 74 t = *shm; 75 for (i = 0; i < SHM_MAX; i++) 76 { 77 j += i; 78 ++*shm; 79 } 80 if (*shm != SHM_MAX + t) 81 fprintf(stderr, "error: %d != %d\n", 82 *shm, SHM_MAX + t); 83 break; 84 case 'v': 85 printf("shmval: %d\n", *shm); 86 break; 87 } 88 } 89 return sm_shmstop((void *) shm, shmid, owner); 90 } 91 92 93 /* 94 ** SHMBIG -- testing of shared memory 95 ** 96 ** Parameters: 97 ** owner -- create segment. 98 ** size -- size of segment. 99 ** 100 ** Returns: 101 ** 0 on success 102 ** < 0 on failure. 103 */ 104 105 int shmbig __P((bool, int)); 106 107 int 108 shmbig(owner, size) 109 bool owner; 110 int size; 111 { 112 int *shm, shmid; 113 int i; 114 115 shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner); 116 if (shm == (int *) 0) 117 { 118 perror("shminit failed"); 119 return -1; 120 } 121 122 for (i = 0; i < size / sizeof(int); i++) 123 shm[i] = i; 124 for (i = 0; i < size / sizeof(int); i++) 125 { 126 if (shm[i] != i) 127 { 128 fprintf(stderr, "failed at %d: %d", i, shm[i]); 129 } 130 } 131 132 return sm_shmstop((void *) shm, shmid, owner); 133 } 134 135 136 /* 137 ** SHMTEST -- test of shared memory 138 ** 139 ** Parameters: 140 ** owner -- create segment. 141 ** 142 ** Returns: 143 ** 0 on success 144 ** < 0 on failure. 145 */ 146 147 # define MAX_CNT 10 148 149 int 150 shmtest(owner) 151 int owner; 152 { 153 int *shm, shmid; 154 int cnt = 0; 155 156 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 157 if (shm == (int *) 0) 158 { 159 perror("shminit failed"); 160 return -1; 161 } 162 163 if (owner) 164 { 165 int r; 166 167 *shm = 1; 168 while (*shm == 1 && cnt++ < MAX_CNT) 169 sleep(1); 170 SM_TEST(cnt <= MAX_CNT); 171 172 /* release and re-acquire the segment */ 173 r = sm_shmstop((void *) shm, shmid, owner); 174 SM_TEST(r == 0); 175 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 176 SM_TEST(shm != (int *) 0); 177 } 178 else 179 { 180 while (*shm != 1 && cnt++ < MAX_CNT) 181 sleep(1); 182 SM_TEST(cnt <= MAX_CNT); 183 *shm = 2; 184 185 /* wait a momemt so the segment is still in use */ 186 sleep(2); 187 } 188 return sm_shmstop((void *) shm, shmid, owner); 189 } 190 191 int 192 main(argc, argv) 193 int argc; 194 char *argv[]; 195 { 196 bool interactive = false; 197 bool owner = false; 198 int big = -1; 199 int ch; 200 int r = 0; 201 int status; 202 extern char *optarg; 203 204 # define OPTIONS "b:io" 205 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 206 { 207 switch ((char) ch) 208 { 209 case 'b': 210 big = atoi(optarg); 211 break; 212 213 case 'i': 214 interactive = true; 215 break; 216 217 case 'o': 218 owner = true; 219 break; 220 221 default: 222 break; 223 } 224 } 225 226 if (interactive) 227 r = shminter(owner); 228 else if (big > 0) 229 r = shmbig(true, big); 230 else 231 { 232 pid_t pid; 233 extern int SmTestNumErrors; 234 235 if ((pid = fork()) < 0) 236 { 237 perror("fork failed\n"); 238 return -1; 239 } 240 241 sm_test_begin(argc, argv, "test shared memory"); 242 if (pid == 0) 243 { 244 /* give the parent the chance to setup data */ 245 sleep(1); 246 r = shmtest(false); 247 } 248 else 249 { 250 r = shmtest(true); 251 (void) wait(&status); 252 } 253 SM_TEST(r == 0); 254 if (SmTestNumErrors > 0) 255 printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n"); 256 return sm_test_end(); 257 } 258 return r; 259 } 260 #else /* SM_CONF_SHM */ 261 int 262 main(argc, argv) 263 int argc; 264 char *argv[]; 265 { 266 printf("No support for shared memory configured on this machine\n"); 267 return 0; 268 } 269 #endif /* SM_CONF_SHM */ 270