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