Remove a couple mudflap remnants
[official-gcc.git] / libitm / testsuite / libitm.c / priv-1.c
blob635d5237f2985c8be1f507e12e9790bee7aa60eb
1 /* Quick stress test for proxy privatization. */
3 /* We need to use a TM method that has to enforce privatization safety
4 explicitly. */
5 /* { dg-set-target-env-var ITM_DEFAULT_METHOD "ml_wt" } */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <pthread.h>
11 /* Make them likely to be mapped to different orecs. */
12 #define ALIGN __attribute__((aligned (256)))
13 /* Don't make these static to work around PR 68591. */
14 int x ALIGN;
15 int *ptr ALIGN;
16 int *priv_ptr ALIGN;
17 int priv_value ALIGN;
18 int barrier ALIGN = 0;
19 const int iters = 100;
21 static void arrive_and_wait (int expected_value)
23 int now = __atomic_add_fetch (&barrier, 1, __ATOMIC_ACQ_REL);
24 while (now < expected_value)
25 __atomic_load (&barrier, &now, __ATOMIC_ACQUIRE);
28 static void __attribute__((transaction_pure,noinline)) delay (int i)
30 for (volatile int v = 0; v < i; v++);
33 /* This tries to catch a case in which proxy privatization safety is not
34 ensured by privatization_user. Specifically, it's access to the value
35 of it's transactional snapshot of ptr must read from an uncommitted write
36 by writer; thus, writer must still be active but must have read ptr before
37 proxy can privatize *ptr by assigning to ptr.
38 We try to make this interleaving more likely by delaying the commit of
39 writer and the start of proxy. */
40 static void *writer (void *dummy __attribute__((unused)))
42 for (int i = 0; i < iters; i++)
44 /* Initialize state in each round. */
45 x = 0;
46 ptr = &x;
47 priv_ptr = NULL;
48 int wrote = 1;
49 arrive_and_wait (i * 6 + 3);
50 /* Interference by another writer. Has a conflict with the proxy
51 privatizer. */
52 __transaction_atomic
54 if (ptr != NULL)
55 *ptr = 1;
56 else
57 wrote = 0;
58 delay (2000000);
60 arrive_and_wait (i * 6 + 6);
61 /* If the previous transaction committed first, wrote == 1 and x == 1;
62 otherwise, if the proxy came first, wrote == 0 and priv_value == 0.
64 if (wrote != priv_value)
65 abort ();
67 return NULL;
70 static void *proxy (void *dummy __attribute__((unused)))
72 for (int i = 0; i < iters; i++)
74 arrive_and_wait (i * 6 + 3);
75 delay(1000000);
76 __transaction_atomic
78 /* Hand-off to privatization-user and its read-only transaction and
79 subsequent use of privatization. */
80 priv_ptr = ptr;
81 ptr = NULL;
83 arrive_and_wait (i * 6 + 6);
85 return NULL;
88 static void *privatization_user (void *dummy __attribute__((unused)))
90 for (int i = 0; i < iters; i++)
92 arrive_and_wait (i * 6 + 3);
93 /* Spin until we have gotten a pointer from the proxy. Then access
94 the value pointed to nontransactionally. */
95 int *p = NULL;
96 while (p == NULL)
97 __transaction_atomic { p = priv_ptr; }
98 priv_value = *p;
99 arrive_and_wait (i * 6 + 6);
101 return NULL;
104 int main()
106 pthread_t p[3];
108 pthread_create (p+0, NULL, writer, NULL);
109 pthread_create (p+1, NULL, proxy, NULL);
110 pthread_create (p+2, NULL, privatization_user, NULL);
112 for (int i = 0; i < 3; ++i)
113 pthread_join (p[i], NULL);
115 return 0;