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