1 /* { dg-do run } */
2 /* { dg-options "-pthread" } */
3
4 /* Tests that new transactions can be started from both transaction_pure and
5 transaction_unsafe code. This also requires proper handling of reentrant
6 nesting in the serial_lock implementation. */
7
8 #include <stdlib.h>
9 #include <pthread.h>
10 #include <libitm.h>
11
12 int x = 0;
13
14 int __attribute__((transaction_pure)) pure(int i)
15 {
16 __transaction_atomic {
17 x++;
18 }
19 if (_ITM_inTransaction() == outsideTransaction)
20 abort();
21 return i+1;
22 }
23
24 int __attribute__((transaction_unsafe)) unsafe(int i)
25 {
26 if (_ITM_inTransaction() != inIrrevocableTransaction)
27 abort();
28 __transaction_atomic {
29 x++;
30 }
31 if (_ITM_inTransaction() != inIrrevocableTransaction)
32 abort();
33 return i+1;
34 }
35
36 static void *thread (void *dummy __attribute__((unused)))
37 {
38 __transaction_atomic {
39 pure(x);
40 }
41 __transaction_relaxed {
42 unsafe(1);
43 }
44 return 0;
45 }
46
47 int main()
48 {
49 pthread_t pt;
50 int r = 0;
51
52 __transaction_atomic {
53 r += pure(1) + x;
54 }
55 __transaction_relaxed {
56 r += unsafe(1) + x;
57 }
58 if (r != 7)
59 abort();
60
61 // Spawn a new thread to check that the serial lock is not held.
62 pthread_create(&pt, NULL, thread, NULL);
63 pthread_join(pt, NULL);
64 if (x != 4)
65 abort();
66 return 0;
67 }