bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / test / testshm.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr_shm.h"
18 #include "apr_errno.h"
19 #include "apr_general.h"
20 #include "apr_lib.h"
21 #include "apr_strings.h"
22 #include "apr_time.h"
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #if APR_HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29
30 #if APR_HAS_SHARED_MEMORY
31
32 typedef struct mbox {
33     char msg[1024]; 
34     int msgavail; 
35 } mbox;
36 mbox *boxes;
37
38 #define N_BOXES 10
39 #define N_MESSAGES 100
40 #define SHARED_SIZE (apr_size_t)(N_BOXES * sizeof(mbox))
41 #define SHARED_FILENAME "/tmp/apr.testshm.shm"
42
43 static void msgwait(int sleep_sec, int first_box, int last_box)
44 {
45     int i;
46     apr_time_t start = apr_time_now();
47     apr_interval_time_t sleep_duration = apr_time_from_sec(sleep_sec);
48     while (apr_time_now() - start < sleep_duration) {
49         for (i = first_box; i < last_box; i++) {
50             if (boxes[i].msgavail) {
51                 fprintf(stdout, "received a message in box %d, message was: %s\n", 
52                         i, boxes[i].msg); 
53                 boxes[i].msgavail = 0; /* reset back to 0 */
54             }
55         }
56         apr_sleep(apr_time_make(0, 10000)); /* 10ms */
57     }
58     fprintf(stdout, "done waiting on mailboxes...\n");
59 }
60
61 static void msgput(int boxnum, char *msg)
62 {
63     fprintf(stdout, "Sending message to box %d\n", boxnum);
64     apr_cpystrn(boxes[boxnum].msg, msg, strlen(msg));
65     boxes[boxnum].msgavail = 1;
66 }
67
68 static apr_status_t test_anon(apr_pool_t *parpool)
69 {
70     apr_status_t rv;
71     apr_pool_t *pool;
72     apr_shm_t *shm;
73     apr_size_t retsize;
74     pid_t pid;
75     int cnt, i, exit_int;
76
77     rv = apr_pool_create(&pool, parpool);
78     if (rv != APR_SUCCESS) {
79         fprintf(stderr, "Error creating child pool\n");
80         return rv;
81     }
82
83     printf("Creating anonymous shared memory block (%"
84            APR_SIZE_T_FMT " bytes)........", SHARED_SIZE); 
85     rv = apr_shm_create(&shm, SHARED_SIZE, NULL, pool);
86     if (rv != APR_SUCCESS) { 
87         fprintf(stderr, "Error allocating shared memory block\n");
88         return rv;
89     }
90     fprintf(stdout, "OK\n");
91
92     printf("Checking size...%" APR_SIZE_T_FMT " bytes...",
93             retsize = apr_shm_size_get(shm));
94     if (retsize != SHARED_SIZE) {
95         fprintf(stderr, "Error allocating shared memory block\n");
96         return rv;
97     }
98     fprintf(stdout, "OK\n");
99
100     printf("Allocating shared mbox memory for %d boxes ..............",
101            N_BOXES); 
102     boxes = apr_shm_baseaddr_get(shm);
103     if (boxes == NULL) { 
104         fprintf(stderr, "Error creating message boxes.\n");
105         return rv;
106     }
107     fprintf(stdout, "OK\n");
108
109     printf("Shared Process Test (child/parent)\n");
110     pid = fork();
111     if (pid == 0) { /* child */
112         msgwait(5, 0, N_BOXES);
113         exit(0);
114     }
115     else if (pid > 0) { /* parent */
116         i = N_BOXES;
117         cnt = N_MESSAGES;
118         while (--cnt > 0) {
119             if ((i-=3) < 0) {
120                 i += N_BOXES; /* start over at the top */
121             }
122             msgput(i, "Sending a message\n");
123             apr_sleep(apr_time_make(0, 10000));
124         }
125     }
126     else {
127         printf("Error creating a child process\n");
128         return errno;
129     }
130     /* wait for the child */
131     printf("Waiting for child to exit.\n");
132     if (waitpid(pid, &exit_int, 0) < 0) {
133         return errno;
134     }
135
136     printf("Destroying shared memory segment...");
137     rv = apr_shm_destroy(shm);
138     if (rv != APR_SUCCESS) {
139         printf("FAILED\n");
140         return rv;
141     }
142     printf("OK\n");
143
144     apr_pool_destroy(pool);
145
146     return APR_SUCCESS;
147 }
148
149 static apr_status_t test_named(apr_pool_t *parpool)
150 {
151     apr_status_t rv;
152     apr_pool_t *pool;
153     apr_shm_t *shm;
154     apr_size_t retsize;
155     pid_t pidproducer, pidconsumer;
156     int exit_int;
157
158     rv = apr_pool_create(&pool, parpool);
159     if (rv != APR_SUCCESS) {
160         fprintf(stderr, "Error creating child pool\n");
161         return rv;
162     }
163
164     printf("Creating named shared memory block (%"
165            APR_SIZE_T_FMT " bytes)........", SHARED_SIZE); 
166     rv = apr_shm_create(&shm, SHARED_SIZE, SHARED_FILENAME, pool);
167     if (rv != APR_SUCCESS) { 
168         fprintf(stderr, "Error allocating shared memory block\n");
169         return rv;
170     }
171     fprintf(stdout, "OK\n");
172
173     printf("Checking size...%" APR_SIZE_T_FMT " bytes...",
174             retsize = apr_shm_size_get(shm));
175     if (retsize != SHARED_SIZE) {
176         fprintf(stderr, "Error allocating shared memory block\n");
177         return rv;
178     }
179     fprintf(stdout, "OK\n");
180
181     printf("Allocating shared mbox memory for %d boxes ..............",
182            N_BOXES); 
183     boxes = apr_shm_baseaddr_get(shm);
184     if (boxes == NULL) { 
185         fprintf(stderr, "Error creating message boxes.\n");
186         return rv;
187     }
188     fprintf(stdout, "OK\n");
189
190     printf("fork()ing and exec()ing children:\n");
191     pidproducer = fork();
192     if (pidproducer == 0) { /* child */
193         /* FIXME: exec a producer */
194         printf("starting consumer.....\n");
195         if (execlp("testshmconsumer", "testshmconsumer", (char*)0) < 0) {
196             return errno;
197         }
198     }
199     else if (pidproducer > 0) { /* parent */
200         /* fork another child */
201         pidconsumer = fork();
202         if (pidconsumer == 0) { /* child */
203             /* FIXME: exec a producer */
204             printf("starting producer.....\n");
205             if (execlp("testshmproducer", "testshmproducer", (char*)0) < 0) {
206                 return errno;
207             }
208         }
209         else if (pidconsumer < 0) { /* parent */
210             printf("Error creating a child process\n");
211             return errno;
212         }
213     }
214     else {
215         printf("Error creating a child process\n");
216         return errno;
217     }
218     /* wait for the child */
219     printf("Waiting for producer to exit.\n");
220     if (waitpid(pidconsumer, &exit_int, 0) < 0) {
221         return errno;
222     }
223     if (!WIFEXITED(exit_int)) {
224         printf("Producer was unsuccessful.\n");
225         return APR_EGENERAL;
226     }
227     printf("Waiting for consumer to exit.\n");
228     if (waitpid(pidproducer, &exit_int, 0) < 0) {
229         return errno;
230     }
231     if (!WIFEXITED(exit_int)) {
232         printf("Consumer was unsuccessful.\n");
233         return APR_EGENERAL;
234     }
235
236     printf("Destroying shared memory segment...");
237     rv = apr_shm_destroy(shm);
238     if (rv != APR_SUCCESS) {
239         printf("FAILED\n");
240         return rv;
241     }
242     printf("OK\n");
243
244     apr_pool_destroy(pool);
245
246     return APR_SUCCESS;
247 }
248
249 int main(void)
250 {
251     apr_status_t rv;
252     apr_pool_t *pool;
253     char errmsg[200];
254
255     apr_initialize();
256     
257     printf("APR Shared Memory Test\n");
258     printf("======================\n\n");
259
260     printf("Initializing the pool............................"); 
261     if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
262         printf("could not initialize pool\n");
263         exit(-1);
264     }
265     printf("OK\n");
266
267     rv = test_anon(pool);
268     if (rv != APR_SUCCESS) {
269         if (rv == APR_ENOTIMPL) {
270             printf("Anonymous shared memory unavailable on this platform.\n");
271         }
272         else {
273             printf("Anonymous shared memory test FAILED: [%d] %s\n",
274                    rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
275             exit(-2);
276         }
277     }
278     printf("Anonymous shared memory test passed!\n");
279
280     if ((rv = test_named(pool)) != APR_SUCCESS) {
281         printf("Name-based shared memory test FAILED: [%d] %s \n",
282                rv, apr_strerror(rv, errmsg, sizeof(errmsg)));
283         exit(-3);
284     }
285     printf("Named shared memory test passed!\n");
286
287     return 0;
288 }
289
290 #else /* APR_HAS_SHARED_MEMORY */
291 #error shmem is not supported on this platform
292 #endif /* APR_HAS_SHARED_MEMORY */
293