1 /* 2 * Copyright (c) 2000-2002, 2004 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.20 2004/08/03 20:51:36 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, 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 ++*shm; 78 } 79 if (*shm != SHM_MAX + t) 80 fprintf(stderr, "error: %d != %d\n", 81 *shm, SHM_MAX + t); 82 break; 83 case 'v': 84 printf("shmval: %d\n", *shm); 85 break; 86 } 87 } 88 return sm_shmstop((void *) shm, shmid, owner); 89 } 90 91 92 /* 93 ** SHMBIG -- testing of shared memory 94 ** 95 ** Parameters: 96 ** owner -- create segment. 97 ** size -- size of segment. 98 ** 99 ** Returns: 100 ** 0 on success 101 ** < 0 on failure. 102 */ 103 104 int shmbig __P((bool, int)); 105 106 int 107 shmbig(owner, size) 108 bool owner; 109 int size; 110 { 111 int *shm, shmid; 112 int i; 113 114 shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner); 115 if (shm == (int *) 0) 116 { 117 perror("shminit failed"); 118 return -1; 119 } 120 121 for (i = 0; i < size / sizeof(int); i++) 122 shm[i] = i; 123 for (i = 0; i < size / sizeof(int); i++) 124 { 125 if (shm[i] != i) 126 { 127 fprintf(stderr, "failed at %d: %d", i, shm[i]); 128 } 129 } 130 131 return sm_shmstop((void *) shm, shmid, owner); 132 } 133 134 135 /* 136 ** SHMTEST -- test of shared memory 137 ** 138 ** Parameters: 139 ** owner -- create segment. 140 ** 141 ** Returns: 142 ** 0 on success 143 ** < 0 on failure. 144 */ 145 146 # define MAX_CNT 10 147 148 int shmtest __P((int)); 149 150 int 151 shmtest(owner) 152 int owner; 153 { 154 int *shm, shmid; 155 int cnt = 0; 156 157 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 158 if (shm == (int *) 0) 159 { 160 perror("shminit failed"); 161 return -1; 162 } 163 164 if (owner) 165 { 166 int r; 167 168 *shm = 1; 169 while (*shm == 1 && cnt++ < MAX_CNT) 170 sleep(1); 171 SM_TEST(cnt <= MAX_CNT); 172 173 /* release and re-acquire the segment */ 174 r = sm_shmstop((void *) shm, shmid, owner); 175 SM_TEST(r == 0); 176 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 177 SM_TEST(shm != (int *) 0); 178 } 179 else 180 { 181 while (*shm != 1 && cnt++ < MAX_CNT) 182 sleep(1); 183 SM_TEST(cnt <= MAX_CNT); 184 *shm = 2; 185 186 /* wait a momemt so the segment is still in use */ 187 sleep(2); 188 } 189 return sm_shmstop((void *) shm, shmid, owner); 190 } 191 192 int 193 main(argc, argv) 194 int argc; 195 char *argv[]; 196 { 197 bool interactive = false; 198 bool owner = false; 199 int big = -1; 200 int ch; 201 int r = 0; 202 int status; 203 extern char *optarg; 204 205 # define OPTIONS "b:io" 206 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 207 { 208 switch ((char) ch) 209 { 210 case 'b': 211 big = atoi(optarg); 212 break; 213 214 case 'i': 215 interactive = true; 216 break; 217 218 case 'o': 219 owner = true; 220 break; 221 222 default: 223 break; 224 } 225 } 226 227 if (interactive) 228 r = shminter(owner); 229 else if (big > 0) 230 r = shmbig(true, big); 231 else 232 { 233 pid_t pid; 234 extern int SmTestNumErrors; 235 236 if ((pid = fork()) < 0) 237 { 238 perror("fork failed\n"); 239 return -1; 240 } 241 242 sm_test_begin(argc, argv, "test shared memory"); 243 if (pid == 0) 244 { 245 /* give the parent the chance to setup data */ 246 sleep(1); 247 r = shmtest(false); 248 } 249 else 250 { 251 r = shmtest(true); 252 (void) wait(&status); 253 } 254 SM_TEST(r == 0); 255 if (SmTestNumErrors > 0) 256 printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n"); 257 return sm_test_end(); 258 } 259 return r; 260 } 261 #else /* SM_CONF_SHM */ 262 int 263 main(argc, argv) 264 int argc; 265 char *argv[]; 266 { 267 printf("No support for shared memory configured on this machine\n"); 268 return 0; 269 } 270 #endif /* SM_CONF_SHM */ 271