reentrant.c 1.2 KB

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