2014-10-17 Ed Schonberg <schonberg@adacore.com>
[official-gcc.git] / libitm / testsuite / libitm.c / reentrant.c
blobe8f49ba3e134afc6473825db3a93a872a00ac68b
1 /* { dg-do run } */
2 /* { dg-options "-pthread" } */
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. */
8 #include <stdlib.h>
9 #include <pthread.h>
10 #include <libitm.h>
12 int x = 0;
14 int __attribute__((transaction_pure)) pure(int i)
16 __transaction_atomic {
17 x++;
19 if (_ITM_inTransaction() == outsideTransaction)
20 abort();
21 return i+1;
24 int __attribute__((transaction_unsafe)) unsafe(int i)
26 if (_ITM_inTransaction() != inIrrevocableTransaction)
27 abort();
28 __transaction_atomic {
29 x++;
31 if (_ITM_inTransaction() != inIrrevocableTransaction)
32 abort();
33 return i+1;
36 static void *thread (void *dummy __attribute__((unused)))
38 __transaction_atomic {
39 pure(x);
41 __transaction_relaxed {
42 unsafe(1);
44 return 0;
47 int main()
49 pthread_t pt;
50 int r = 0;
52 __transaction_atomic {
53 r += pure(1) + x;
55 __transaction_relaxed {
56 r += unsafe(1) + x;
58 if (r != 7)
59 abort();
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;