barrier.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* POSIX barrier implementation for LinuxThreads.
  2. Copyright (C) 2000, 2003 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Kaz Kylheku <kaz@ashi.footprints.net>, 2000.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License as
  7. published by the Free Software Foundation; either version 2.1 of the
  8. License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; see the file COPYING.LIB. If not,
  15. write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. Boston, MA 02111-1307, USA. */
  17. #include <errno.h>
  18. #include "pthread.h"
  19. #include "internals.h"
  20. #include "spinlock.h"
  21. #include "queue.h"
  22. #include "restart.h"
  23. int
  24. pthread_barrier_wait(pthread_barrier_t *barrier)
  25. {
  26. pthread_descr self = thread_self();
  27. pthread_descr temp_wake_queue, th;
  28. int result = 0;
  29. __pthread_lock(&barrier->__ba_lock, self);
  30. /* If the required number of threads have achieved rendezvous... */
  31. if (barrier->__ba_present >= barrier->__ba_required - 1)
  32. {
  33. /* ... then this last caller shall be the serial thread */
  34. result = PTHREAD_BARRIER_SERIAL_THREAD;
  35. /* Copy and clear wait queue and reset barrier. */
  36. temp_wake_queue = barrier->__ba_waiting;
  37. barrier->__ba_waiting = NULL;
  38. barrier->__ba_present = 0;
  39. }
  40. else
  41. {
  42. result = 0;
  43. barrier->__ba_present++;
  44. enqueue(&barrier->__ba_waiting, self);
  45. }
  46. __pthread_unlock(&barrier->__ba_lock);
  47. if (result == 0)
  48. {
  49. /* Non-serial threads have to suspend */
  50. suspend(self);
  51. /* We don't bother dealing with cancellation because the POSIX
  52. spec for barriers doesn't mention that pthread_barrier_wait
  53. is a cancellation point. */
  54. }
  55. else
  56. {
  57. /* Serial thread wakes up all others. */
  58. while ((th = dequeue(&temp_wake_queue)) != NULL)
  59. restart(th);
  60. }
  61. return result;
  62. }
  63. int
  64. pthread_barrier_init(pthread_barrier_t *barrier,
  65. const pthread_barrierattr_t *attr,
  66. unsigned int count)
  67. {
  68. if (count == 0)
  69. return EINVAL;
  70. __pthread_init_lock(&barrier->__ba_lock);
  71. barrier->__ba_required = count;
  72. barrier->__ba_present = 0;
  73. barrier->__ba_waiting = NULL;
  74. return 0;
  75. }
  76. int
  77. pthread_barrier_destroy(pthread_barrier_t *barrier)
  78. {
  79. if (barrier->__ba_waiting != NULL) return EBUSY;
  80. return 0;
  81. }
  82. int
  83. pthread_barrierattr_init(pthread_barrierattr_t *attr)
  84. {
  85. attr->__pshared = PTHREAD_PROCESS_PRIVATE;
  86. return 0;
  87. }
  88. int
  89. pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
  90. {
  91. return 0;
  92. }
  93. int
  94. __pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr,
  95. int *pshared)
  96. {
  97. *pshared = PTHREAD_PROCESS_PRIVATE;
  98. return 0;
  99. }
  100. int
  101. pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
  102. {
  103. if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED)
  104. return EINVAL;
  105. /* For now it is not possible to shared a conditional variable. */
  106. if (pshared != PTHREAD_PROCESS_PRIVATE)
  107. return ENOSYS;
  108. return 0;
  109. }