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 
pure(int i)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 
unsafe(int i)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 
thread(void * dummy)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 
main()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 }
68