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.19 2004/04/20 23:14:21 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 149 shmtest(owner) 150 int owner; 151 { 152 int *shm, shmid; 153 int cnt = 0; 154 155 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 156 if (shm == (int *) 0) 157 { 158 perror("shminit failed"); 159 return -1; 160 } 161 162 if (owner) 163 { 164 int r; 165 166 *shm = 1; 167 while (*shm == 1 && cnt++ < MAX_CNT) 168 sleep(1); 169 SM_TEST(cnt <= MAX_CNT); 170 171 /* release and re-acquire the segment */ 172 r = sm_shmstop((void *) shm, shmid, owner); 173 SM_TEST(r == 0); 174 shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); 175 SM_TEST(shm != (int *) 0); 176 } 177 else 178 { 179 while (*shm != 1 && cnt++ < MAX_CNT) 180 sleep(1); 181 SM_TEST(cnt <= MAX_CNT); 182 *shm = 2; 183 184 /* wait a momemt so the segment is still in use */ 185 sleep(2); 186 } 187 return sm_shmstop((void *) shm, shmid, owner); 188 } 189 190 int 191 main(argc, argv) 192 int argc; 193 char *argv[]; 194 { 195 bool interactive = false; 196 bool owner = false; 197 int big = -1; 198 int ch; 199 int r = 0; 200 int status; 201 extern char *optarg; 202 203 # define OPTIONS "b:io" 204 while ((ch = getopt(argc, argv, OPTIONS)) != -1) 205 { 206 switch ((char) ch) 207 { 208 case 'b': 209 big = atoi(optarg); 210 break; 211 212 case 'i': 213 interactive = true; 214 break; 215 216 case 'o': 217 owner = true; 218 break; 219 220 default: 221 break; 222 } 223 } 224 225 if (interactive) 226 r = shminter(owner); 227 else if (big > 0) 228 r = shmbig(true, big); 229 else 230 { 231 pid_t pid; 232 extern int SmTestNumErrors; 233 234 if ((pid = fork()) < 0) 235 { 236 perror("fork failed\n"); 237 return -1; 238 } 239 240 sm_test_begin(argc, argv, "test shared memory"); 241 if (pid == 0) 242 { 243 /* give the parent the chance to setup data */ 244 sleep(1); 245 r = shmtest(false); 246 } 247 else 248 { 249 r = shmtest(true); 250 (void) wait(&status); 251 } 252 SM_TEST(r == 0); 253 if (SmTestNumErrors > 0) 254 printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n"); 255 return sm_test_end(); 256 } 257 return r; 258 } 259 #else /* SM_CONF_SHM */ 260 int 261 main(argc, argv) 262 int argc; 263 char *argv[]; 264 { 265 printf("No support for shared memory configured on this machine\n"); 266 return 0; 267 } 268 #endif /* SM_CONF_SHM */ 269