1 
2 /* I don't think this is a very good test .. all this
3    sleepery is highly confusing. */
4 
5 /* test child thread inheriting data */
6 
7 #include <stdio.h>
8 #include <pthread.h>
9 #include <unistd.h>
10 
11 static volatile int shared[2];
12 
13 static void *t1(void *v)
14 {
15 	volatile int *ip = (int *)v;
16 	if (0) printf("ta W\n");
17 	*ip += 44;
18 	*ip *= 2;
19 	sleep(1);
20 	return 0;
21 }
22 
23 static void *t2(void *v)
24 {
25 	volatile int *ip = (int *)v;
26 	sleep(2);
27 	if (0) printf("tb W\n");
28 	*ip += 88;
29 	*ip *= 3;
30 	sleep(1);
31 	return 0;
32 }
33 
34 int main(void)
35 {
36 	pthread_t a, b;
37 	volatile int ret = 0;
38 
39 	sleep(0);
40 
41 	shared[0] = 22;
42 	shared[1] = 77;
43 
44 	pthread_create(&a, NULL, t1, (void *)&shared[0]);
45 	// a steals shared[0] from root thread, so is excl(a)
46 	pthread_create(&b, NULL, t2, (void *)&shared[1]);
47 	// b steals shared[1] from root thread, so is excl(b)
48 
49 	pthread_join(a, NULL);
50 	// b's stuff (shared[1]) still belongs to b, so is excl(b)
51 
52 	// ret is excl(root), and shared[0] is re-acquired as excl(root)
53 	// since a joined to root
54 	if (0) printf("r R1\n");
55 	ret += shared[0];	/* no error - a is finished */
56 
57 	// but shared[1] is excl(b); hence we're reading excl(b)
58 	// without a lock and without a dependency edge
59 	if (0) printf("r R2\n");
60 	ret += shared[1];	/* expect error - b has not finished,
61 				   so we can't touch shared[1] yet */
62 
63 	pthread_join(b, NULL);
64 
65 
66 	return ret;
67 }
68