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
11static volatile int shared[2];
12
13static 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
23static 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
34int 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