blob: e8f49ba3e134afc6473825db3a93a872a00ac68b [file] [log] [blame]
/* { dg-do run } */
/* { dg-options "-pthread" } */
/* 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(x);
}
__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;
}