tst-cond22.c 3.6 KB

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