xref: /haiku/src/tests/system/kernel/fibo_fork.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
1 /*
2  * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Copyright 2002, Manuel J. Petit. All rights reserved.
6  * Distributed under the terms of the NewOS License.
7  */
8 
9 
10 #include <image.h>
11 
12 #include <errno.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 
18 
19 int gForked = 0;
20 
21 
22 static void
23 usage(char const *app)
24 {
25 	printf("usage: %s ###\n", app);
26 	exit(-1);
27 }
28 
29 
30 int
31 main(int argc, char *argv[])
32 {
33 	int result = 0;
34 
35 	if (argc != 2)
36 		usage(argv[0]);
37 
38 	int num = atoi(argv[1]);
39 
40 	if (num < 2) {
41 		result = num;
42 	} else {
43 		pid_t childA = fork();
44 		if (childA == 0) {
45 			// we're the child
46 			char buffer[64];
47 			char* args[]= { argv[0], buffer, NULL };
48 			int argCount = 2;
49 			gForked++;
50 
51 			snprintf(buffer, sizeof(buffer), "%d", num - 1);
52 			return main(argCount, args);
53 		} else if (childA < 0) {
54 			fprintf(stderr, "fork() failed for child A: %s\n", strerror(errno));
55 			return -1;
56 		}
57 
58 		pid_t childB = fork();
59 		if (childB == 0) {
60 			// we're the child
61 			char buffer[64];
62 			char* args[]= { argv[0], buffer, NULL };
63 			int argCount = 2;
64 			gForked++;
65 
66 			snprintf(buffer, sizeof(buffer), "%d", num - 2);
67 			return main(argCount, args);
68 		} else if (childB < 0) {
69 			fprintf(stderr, "fork() failed for child B: %s\n", strerror(errno));
70 			return -1;
71 		}
72 
73 		status_t status, returnValue = 0;
74 		do {
75 			status = wait_for_thread(childA, &returnValue);
76 		} while (status == B_INTERRUPTED);
77 
78 		if (status == B_OK)
79 			result = returnValue;
80 		else
81 			fprintf(stderr, "wait_for_thread(%ld) A failed: %s\n", childA, strerror(status));
82 
83 		do {
84 			status = wait_for_thread(childB, &returnValue);
85 		} while (status == B_INTERRUPTED);
86 
87 		if (status == B_OK)
88 			result += returnValue;
89 		else
90 			fprintf(stderr, "wait_for_thread(%ld) B failed: %s\n", childB, strerror(status));
91 	}
92 
93 	if (gForked) {
94 		return result;
95 	} else {
96 		printf("%d\n", result);
97 		return 0;
98 	}
99 }
100 
101