1 /* pthread_barrier_wait. Generic version. 2 Copyright (C) 2002-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 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 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <pthread.h> 20 #include <assert.h> 21 22 #include <pt-internal.h> 23 24 int pthread_barrier_wait(pthread_barrier_t * barrier)25pthread_barrier_wait (pthread_barrier_t *barrier) 26 { 27 __pthread_spin_wait (&barrier->__lock); 28 if (--barrier->__pending == 0) 29 { 30 barrier->__pending = barrier->__count; 31 32 if (barrier->__count == 1) 33 __pthread_spin_unlock (&barrier->__lock); 34 else 35 { 36 struct __pthread *wakeup; 37 unsigned n = 0; 38 39 __pthread_queue_iterate (barrier->__queue, wakeup) 40 n++; 41 42 { 43 struct __pthread *wakeups[n]; 44 unsigned i = 0; 45 46 __pthread_dequeuing_iterate (barrier->__queue, wakeup) 47 wakeups[i++] = wakeup; 48 49 barrier->__queue = NULL; 50 __pthread_spin_unlock (&barrier->__lock); 51 52 for (i = 0; i < n; i++) 53 __pthread_wakeup (wakeups[i]); 54 } 55 } 56 57 return PTHREAD_BARRIER_SERIAL_THREAD; 58 } 59 else 60 { 61 struct __pthread *self = _pthread_self (); 62 63 /* Add ourselves to the list of waiters. */ 64 __pthread_enqueue (&barrier->__queue, self); 65 __pthread_spin_unlock (&barrier->__lock); 66 67 __pthread_block (self); 68 return 0; 69 } 70 } 71