Add pipe support
[c11tester.git] / pthread_test / insanesync.cc
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <pthread.h>
4 #include <atomic>
5
6 #include "librace.h"
7 #include "model-assert.h"
8
9 using namespace std;
10
11 atomic_int x, y;
12 atomic_intptr_t z, z2;
13
14 int r1, r2, r3; /* "local" variables */
15
16 /**
17                 This example illustrates a self-satisfying cycle involving
18                 synchronization.  A failed synchronization creates the store that
19                 causes the synchronization to fail.
20
21                 The C++11 memory model nominally allows r1=0, r2=1, r3=5.
22
23                 This example is insane, we don't support that behavior.
24 */
25
26
27 static void *a(void *obj)
28 {
29         z.store((intptr_t)&y, memory_order_relaxed);
30         r1 = y.fetch_add(1, memory_order_release);
31         z.store((intptr_t)&x, memory_order_relaxed);
32         r2 = y.fetch_add(1, memory_order_release);
33         return NULL;
34 }
35
36
37 static void *b(void *obj)
38 {
39         r3 = y.fetch_add(1, memory_order_acquire);
40         intptr_t ptr = z.load(memory_order_relaxed);
41         z2.store(ptr, memory_order_relaxed);
42         return NULL;
43 }
44
45 static void *c(void *obj)
46 {
47         atomic_int *ptr2 = (atomic_int *)z2.load(memory_order_relaxed);
48         (*ptr2).store(5, memory_order_relaxed);
49         return NULL;
50 }
51
52 int user_main(int argc, char **argv)
53 {
54         pthread_t t1, t2, t3;
55
56         atomic_init(&x, 0);
57         atomic_init(&y, 0);
58         atomic_init(&z, (intptr_t) &x);
59         atomic_init(&z2, (intptr_t) &x);
60
61         pthread_create(&t1,NULL, &a, NULL);
62         pthread_create(&t2,NULL, &b, NULL);
63         pthread_create(&t3,NULL, &c, NULL);
64
65         pthread_join(t1,NULL);
66         pthread_join(t2,NULL);
67         pthread_join(t3,NULL);
68
69         printf("r1=%d, r2=%d, r3=%d\n", r1, r2, r3);
70
71         return 0;
72 }