Back to index

glibc  2.9
Functions
pthread_barrier_wait.c File Reference
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <pthreadP.h>

Go to the source code of this file.

Functions

int pthread_barrier_wait (pthread_barrier_t *barrier)

Function Documentation

int pthread_barrier_wait ( pthread_barrier_t *  barrier)

Definition at line 28 of file pthread_barrier_wait.c.

{
  struct pthread_barrier *ibarrier = (struct pthread_barrier *) barrier;
  int result = 0;

  /* Make sure we are alone.  */
  lll_lock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);

  /* One more arrival.  */
  --ibarrier->left;

  /* Are these all?  */
  if (ibarrier->left == 0)
    {
      /* Yes. Increment the event counter to avoid invalid wake-ups and
        tell the current waiters that it is their turn.  */
      ++ibarrier->curr_event;

      /* Wake up everybody.  */
      lll_futex_wake (&ibarrier->curr_event, INT_MAX,
                    ibarrier->private ^ FUTEX_PRIVATE_FLAG);

      /* This is the thread which finished the serialization.  */
      result = PTHREAD_BARRIER_SERIAL_THREAD;
    }
  else
    {
      /* The number of the event we are waiting for.  The barrier's event
        number must be bumped before we continue.  */
      unsigned int event = ibarrier->curr_event;

      /* Before suspending, make the barrier available to others.  */
      lll_unlock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);

      /* Wait for the event counter of the barrier to change.  */
      do
       lll_futex_wait (&ibarrier->curr_event, event,
                     ibarrier->private ^ FUTEX_PRIVATE_FLAG);
      while (event == ibarrier->curr_event);
    }

  /* Make sure the init_count is stored locally or in a register.  */
  unsigned int init_count = ibarrier->init_count;

  /* If this was the last woken thread, unlock.  */
  if (atomic_increment_val (&ibarrier->left) == init_count)
    /* We are done.  */
    lll_unlock (ibarrier->lock, ibarrier->private ^ FUTEX_PRIVATE_FLAG);

  return result;
}