(root)/
glibc-2.38/
sysdeps/
htl/
pt-barrier-wait.c
       1  /* pthread_barrier_wait.  Generic version.
       2     Copyright (C) 2002-2023 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
      25  pthread_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  }