xref: /freebsd/contrib/sendmail/libsm/t-shm.c (revision b52b9d56d4e96089873a75f9e29062eec19fabba)
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