*** empty log message ***
[arla.git] / lwp / testlwp.c
blob13ee4799d09fe0b399851ec4d4e0e195a4960869
1 /*
2 * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
35 * testlwp
37 * Checks if lwp seems to work, and demostrates how to use lwp. Give
38 * multiple commands on the command line to run several tests at the
39 * same time.
41 * $Id$
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <err.h>
49 #include <lwp.h>
50 #include <lock.h>
51 #include <unistd.h>
52 #include <sys/time.h>
54 static void Producer(void *foo) ;
55 static void Consumer(void *foo) ;
57 #ifndef AFS_LWP_MINSTACKSIZE
58 #define LWPTEST_STACKSIZE (16*1024)
59 #else
60 #define LWPTEST_STACKSIZE AFS_LWP_MINSTACKSIZE
61 #endif
64 * Classic Producer Consumer thread testing
66 * Observe the use of SignalNoYield, you can't signal anything
67 * that isn't sleeping.
70 static char pcfoo = 'a' - 1;
72 static void
73 Producer(void *foo)
75 while (1) {
76 LWP_WaitProcess((char *)Producer);
77 pcfoo++;
78 if (pcfoo > 'z')
79 pcfoo = 'a';
80 printf("[producer] creating %c\n", pcfoo);
81 LWP_NoYieldSignal ((char *)Consumer);
85 static void
86 Consumer(void *foo)
88 LWP_NoYieldSignal ((char *)Producer);
89 while (1) {
90 LWP_WaitProcess((char *)Consumer);
91 printf("[consumer] eating %c\n", pcfoo);
92 LWP_NoYieldSignal ((char *)Producer);
96 static int
97 startPCtest(void)
99 PROCESS consumer, producer;
101 if (LWP_CreateProcess (Producer, LWPTEST_STACKSIZE, 1,
102 NULL, "producer", &consumer))
103 errx (1, "Cannot create producer process");
105 if (LWP_CreateProcess (Consumer, LWPTEST_STACKSIZE, 1,
106 NULL, "consumer", &producer))
107 errx (1, "Cannot create consumer process");
108 return 0;
112 * Test the LWP_Sleep() function
115 static void
116 MrSleepy(void *foo)
118 printf("[mrsleepy] I'm going to bed\n");
119 while (1) {
120 IOMGR_Sleep(1);
121 printf("[mrsleepy] yawn\n");
125 static int
126 putMrSleeptoBed(void)
128 PROCESS mrsleepy;
130 if (LWP_CreateProcess (MrSleepy, LWPTEST_STACKSIZE, 1,
131 NULL, "mrsleepy", &mrsleepy))
132 errx (1, "Cannot create consumer process");
133 return 0;
137 * The Producer Consumer thingy done over a pipe
140 int pipa[2] = { -1, -1 };
142 static void
143 SelectProducer(void *foo)
145 char *str = (char *) foo;
146 int len ;
148 if (str == NULL)
149 str = "foo";
150 len = strlen (str) ;
152 while(1) {
153 IOMGR_Sleep(1) ;
154 printf("[selprodu] %s\n", str);
158 static void
159 SelectConsumer(void *foo)
161 char str[200];
162 int len ;
163 fd_set readset;
165 while(1) {
166 FD_ZERO(&readset);
167 if (pipa[0] >= FD_SETSIZE)
168 errx (1, "fd too large");
170 FD_SET(pipa[0], &readset);
171 IOMGR_Select(pipa[0] + 1, &readset, NULL, NULL, NULL);
172 len = read(pipa[0], str, 199);
173 if (len < 0)
174 err(1, "read");
175 str[len] = '\0';
176 printf("[selcomsu] %s\n", str);
180 static void
181 startSelectPC (char *progname)
183 int pid;
184 PROCESS consumer;
186 if (pipa[0] == -1) {
187 if (pipe(pipa))
188 err(1, "pipe");
190 if (LWP_CreateProcess (SelectConsumer, LWPTEST_STACKSIZE, 1,
191 NULL, "selconsu", &consumer))
192 errx (1, "Cannot create select consumer process");
195 pid = fork();
196 switch (pid) {
197 case -1: /* error */
198 err(1, "fork");
199 case 0: /* child */
200 close(0);
201 if (dup2(pipa[1], 0) == -1)
202 err(1, "dup2");
203 close(pipa[1]);
204 execl(progname, "testlwp", "selectproducer", NULL);
205 err(1, "execl");
206 default:
207 break;
212 * Test cancel
215 static void
216 onStrike(void *foo)
218 while (1) {
219 printf("[onstrike] I'll never quit, block, block, block\n");
220 IOMGR_Select(0, NULL, NULL, NULL, NULL);
221 printf("[onstrike] Bah, you will never pay enough\n");
225 static void
226 freeEnterprise(void *foo)
228 PROCESS *pid = (PROCESS *) foo;
230 while(1) {
231 IOMGR_Sleep(1);
232 printf("[enterpri] Raise salery\n");
233 IOMGR_Cancel(*pid);
237 static void
238 yaEndlessLoop(void)
240 static PROCESS worker, enterprise;
242 if (LWP_CreateProcess (onStrike, LWPTEST_STACKSIZE, 1,
243 NULL, "worker", &worker))
244 errx (1, "Cannot create worker process");
246 if (LWP_CreateProcess (freeEnterprise, LWPTEST_STACKSIZE, 1,
247 (void *)&worker, "enterprise", &enterprise))
248 errx (1, "Cannot create enterprise process");
251 static void
252 deadlock_write (void)
254 struct Lock lock;
256 Lock_Init (&lock);
257 ObtainWriteLock(&lock);
258 ObtainWriteLock(&lock);
261 static void
262 deadlock_read (void)
264 struct Lock lock;
266 Lock_Init (&lock);
267 ObtainWriteLock(&lock);
268 ObtainReadLock(&lock);
271 static void
272 deadlock_read2 (void)
274 struct Lock lock;
276 Lock_Init (&lock);
277 ObtainReadLock(&lock);
278 ObtainWriteLock(&lock);
282 * the terms overrun and underrun stack are used somewhat wrong here,
283 * in what direction do your stack grow
287 * when testing if the stack thingy work, it might not be so smart to
288 * use the stack (automatic variables) for storage :)
291 int stack_i, stack_printed = 0;
293 static void
294 overrun_stack (void *arg)
296 char foo[10];
297 int stack_i, stack_printed = 0;
299 for (stack_i = 10; stack_i > -LWPTEST_STACKSIZE * 2; stack_i--) {
300 if (stack_i < -LWPTEST_STACKSIZE - 100 && !stack_printed) {
301 printf("hum overrun stack now\n");
302 stack_printed = 1;
304 foo[stack_i] = 0x4e;
309 static void
310 underrun_stack (void *arg)
312 char foo[10];
314 for (stack_i = 0; stack_i < LWPTEST_STACKSIZE * 2; stack_i++) {
315 if (stack_i > LWPTEST_STACKSIZE + 100&& !stack_printed) {
316 printf("hum underrun stack now\n");
317 stack_printed = 1;
319 foo[stack_i] = 0xe4;
325 * Usage
328 static void
329 usage(char *progname)
331 fprintf(stderr, "usage: %s cmd ...\nWhere cmd is one of:\n", progname);
332 fprintf(stderr,
333 "pc\t\tProducer Consumer test\n"
334 "sleep\t\tSleeptest\n"
335 "selectconsumer\tSelect consumer\n"
336 "selectproducer\t(special case, just print a string on stdout repeatally)\n"
337 "cancel\t\tTest iomgr cancel\n"
338 "deadlock-write\tdeadlockdetection\n"
339 "deadlock-read\tdeadlockdetection\n"
340 "deadlock-read2\tdeadlockdetection\n"
341 "overrun-stack\tover run the stack\n"
342 "underrun-stack\tunder run the stack\n"
343 "version\t\tPrint version\n");
345 printf("Use several of these tests together to test their interopability\n");
346 exit(1);
349 int main(int argc, char **argv)
351 PROCESS pid;
352 char *progname = strdup(argv[0]);
354 if (progname == NULL)
355 progname = "foo";
357 if (argc <= 1 )
358 usage(progname);
360 printf("starting LWP support\n");
361 if (LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid))
362 errx(1, "LWP_InitializeProcessSupport()\n");
364 printf("starting IOMGR support\n");
365 if (IOMGR_Initialize())
366 errx(1, "IOMGR_Initialize()\n");
368 while (argv[1]) {
369 if (strcasecmp("pc", argv[1]) == 0) {
370 startPCtest();
371 } else if (strcasecmp("sleep", argv[1]) == 0) {
372 putMrSleeptoBed();
373 } else if (strcasecmp("selectproducer", argv[1]) == 0) {
374 SelectProducer(NULL);
375 exit(1); /* Special case */
376 } else if (strcasecmp("selectconsumer", argv[1]) == 0) {
377 startSelectPC (progname);
378 } else if (strcasecmp("cancel", argv[1]) == 0) {
379 yaEndlessLoop();
380 } else if (strcasecmp("deadlock-write", argv[1]) == 0) {
381 deadlock_write();
382 } else if (strcasecmp("deadlock-read", argv[1]) == 0) {
383 deadlock_read();
384 } else if (strcasecmp("deadlock-read2", argv[1]) == 0) {
385 deadlock_read2();
386 } else if (strcasecmp("overrun-stack", argv[1]) == 0) {
387 PROCESS tpid;
388 if (LWP_CreateProcess (overrun_stack, LWPTEST_STACKSIZE, 1,
389 NULL, "overunner", &tpid))
390 errx (1, "Cannot create stack overrunner process");
391 } else if (strcasecmp("underrun-stack", argv[1]) == 0) {
392 PROCESS tpid;
393 if (LWP_CreateProcess (underrun_stack, LWPTEST_STACKSIZE, 1,
394 NULL, "underrunner", &tpid))
395 errx (1, "Cannot create stack underrunner process");
396 } else if (strcasecmp("version", argv[1]) == 0) {
397 printf("Version: "
398 "$Id$\n");
399 exit (0);
400 } else {
401 printf("unknown command %s\n", argv[1]);
402 exit (1);
405 argc--;
406 argv++;
408 LWP_WaitProcess((char *) main);
409 return 0;