Merge from vendor branch LIBSTDC++:
[dragonfly.git] / contrib / sendmail / libsm / t-shm.c
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 */