tst-cond22.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. static pthread_barrier_t b;
  5. static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
  6. static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
  7. static void
  8. cl (void *arg)
  9. {
  10. pthread_mutex_unlock (&m);
  11. }
  12. static void *
  13. tf (void *arg)
  14. {
  15. if (pthread_mutex_lock (&m) != 0)
  16. {
  17. printf ("%s: mutex_lock failed\n", __func__);
  18. exit (1);
  19. }
  20. int e = pthread_barrier_wait (&b);
  21. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  22. {
  23. printf ("%s: barrier_wait failed\n", __func__);
  24. exit (1);
  25. }
  26. pthread_cleanup_push (cl, NULL);
  27. /* We have to loop here because the cancellation might come after
  28. the cond_wait call left the cancelable area and is then waiting
  29. on the mutex. In this case the beginning of the second cond_wait
  30. call will cause the cancellation to happen. */
  31. do
  32. if (pthread_cond_wait (&c, &m) != 0)
  33. {
  34. printf ("%s: cond_wait failed\n", __func__);
  35. exit (1);
  36. }
  37. while (arg == NULL);
  38. pthread_cleanup_pop (0);
  39. if (pthread_mutex_unlock (&m) != 0)
  40. {
  41. printf ("%s: mutex_unlock failed\n", __func__);
  42. exit (1);
  43. }
  44. return NULL;
  45. }
  46. static int
  47. do_test (void)
  48. {
  49. int status = 0;
  50. if (pthread_barrier_init (&b, NULL, 2) != 0)
  51. {
  52. puts ("barrier_init failed");
  53. return 1;
  54. }
  55. pthread_t th;
  56. if (pthread_create (&th, NULL, tf, NULL) != 0)
  57. {
  58. puts ("1st create failed");
  59. return 1;
  60. }
  61. int e = pthread_barrier_wait (&b);
  62. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  63. {
  64. puts ("1st barrier_wait failed");
  65. return 1;
  66. }
  67. if (pthread_mutex_lock (&m) != 0)
  68. {
  69. puts ("1st mutex_lock failed");
  70. return 1;
  71. }
  72. if (pthread_cond_signal (&c) != 0)
  73. {
  74. puts ("1st cond_signal failed");
  75. return 1;
  76. }
  77. if (pthread_cancel (th) != 0)
  78. {
  79. puts ("cancel failed");
  80. return 1;
  81. }
  82. if (pthread_mutex_unlock (&m) != 0)
  83. {
  84. puts ("1st mutex_unlock failed");
  85. return 1;
  86. }
  87. void *res;
  88. if (pthread_join (th, &res) != 0)
  89. {
  90. puts ("1st join failed");
  91. return 1;
  92. }
  93. if (res != PTHREAD_CANCELED)
  94. {
  95. puts ("first thread not canceled");
  96. status = 1;
  97. }
  98. printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
  99. c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
  100. c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
  101. c.__data.__nwaiters, c.__data.__broadcast_seq);
  102. if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
  103. {
  104. puts ("2nd create failed");
  105. return 1;
  106. }
  107. e = pthread_barrier_wait (&b);
  108. if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
  109. {
  110. puts ("2nd barrier_wait failed");
  111. return 1;
  112. }
  113. if (pthread_mutex_lock (&m) != 0)
  114. {
  115. puts ("2nd mutex_lock failed");
  116. return 1;
  117. }
  118. if (pthread_cond_signal (&c) != 0)
  119. {
  120. puts ("2nd cond_signal failed");
  121. return 1;
  122. }
  123. if (pthread_mutex_unlock (&m) != 0)
  124. {
  125. puts ("2nd mutex_unlock failed");
  126. return 1;
  127. }
  128. if (pthread_join (th, &res) != 0)
  129. {
  130. puts ("2nd join failed");
  131. return 1;
  132. }
  133. if (res != NULL)
  134. {
  135. puts ("2nd thread canceled");
  136. status = 1;
  137. }
  138. printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n",
  139. c.__data.__lock, c.__data.__futex, c.__data.__total_seq,
  140. c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex,
  141. c.__data.__nwaiters, c.__data.__broadcast_seq);
  142. return status;
  143. }
  144. #define TEST_FUNCTION do_test ()
  145. #include "../test-skeleton.c"