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