1 /* Quick stress test for proxy privatization. */
3 /* We need to use a TM method that has to enforce privatization safety
5 /* { dg-set-target-env-var ITM_DEFAULT_METHOD "ml_wt" } */
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. */
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. */
49 arrive_and_wait (i
* 6 + 3);
50 /* Interference by another writer. Has a conflict with the proxy
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
)
70 static void *proxy (void *dummy
__attribute__((unused
)))
72 for (int i
= 0; i
< iters
; i
++)
74 arrive_and_wait (i
* 6 + 3);
78 /* Hand-off to privatization-user and its read-only transaction and
79 subsequent use of privatization. */
83 arrive_and_wait (i
* 6 + 6);
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. */
97 __transaction_atomic
{ p
= priv_ptr
; }
99 arrive_and_wait (i
* 6 + 6);
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
);