diff options
Diffstat (limited to 'libitm/testsuite/libitm.c/reentrant.c')
-rw-r--r-- | libitm/testsuite/libitm.c/reentrant.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/libitm/testsuite/libitm.c/reentrant.c b/libitm/testsuite/libitm.c/reentrant.c new file mode 100644 index 00000000000..007bbaab741 --- /dev/null +++ b/libitm/testsuite/libitm.c/reentrant.c @@ -0,0 +1,66 @@ +/* { dg-do run { xfail *-*-* } } + +/* Tests that new transactions can be started from both transaction_pure and + transaction_unsafe code. This also requires proper handling of reentrant + nesting in the serial_lock implementation. */ + +#include <stdlib.h> +#include <pthread.h> +#include <libitm.h> + +int x = 0; + +int __attribute__((transaction_pure)) pure(int i) +{ + __transaction_atomic { + x++; + } + if (_ITM_inTransaction() == outsideTransaction) + abort(); + return i+1; +} + +int __attribute__((transaction_unsafe)) unsafe(int i) +{ + if (_ITM_inTransaction() != inIrrevocableTransaction) + abort(); + __transaction_atomic { + x++; + } + if (_ITM_inTransaction() != inIrrevocableTransaction) + abort(); + return i+1; +} + +static void *thread (void *dummy __attribute__((unused))) +{ + __transaction_atomic { + pure(1); + } + __transaction_relaxed { + unsafe(1); + } + return 0; +} + +int main() +{ + pthread_t pt; + int r = 0; + + __transaction_atomic { + r += pure(1) + x; + } + __transaction_relaxed { + r += unsafe(1) + x; + } + if (r != 7) + abort(); + + // Spawn a new thread to check that the serial lock is not held. + pthread_create(&pt, NULL, thread, NULL); + pthread_join(pt, NULL); + if (x != 4) + abort(); + return 0; +} |