Back to index

glibc  2.9
Functions
sem_wait.c File Reference
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <internaltypes.h>
#include <semaphore.h>
#include <pthreadP.h>
#include <shlib-compat.h>

Go to the source code of this file.

Functions

void attribute_hidden __sem_wait_cleanup (void *arg)
int __new_sem_wait (sem_t *sem)
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1)

Function Documentation

int __new_sem_wait ( sem_t sem)

Definition at line 49 of file sem_wait.c.

{
  struct sparc_new_sem *isem = (struct sparc_new_sem *) sem;
  int err;
  int val;

  if (__atomic_is_v9)
    val = atomic_decrement_if_positive (&isem->value);
  else
    {
      __sparc32_atomic_do_lock24 (&isem->lock);
      val = isem->value;
      if (val > 0)
       isem->value = val - 1;
      else
       isem->nwaiters++;
      __sparc32_atomic_do_unlock24 (&isem->lock);
    }

  if (val > 0)
    return 0;

  if (__atomic_is_v9)
    atomic_increment (&isem->nwaiters);
  else
    /* Already done above while still holding isem->lock.  */;

  pthread_cleanup_push (__sem_wait_cleanup, isem);

  while (1)
    {
      /* Enable asynchronous cancellation.  Required by the standard.  */
      int oldtype = __pthread_enable_asynccancel ();

      err = lll_futex_wait (&isem->value, 0,
                         isem->private ^ FUTEX_PRIVATE_FLAG);

      /* Disable asynchronous cancellation.  */
      __pthread_disable_asynccancel (oldtype);

      if (err != 0 && err != -EWOULDBLOCK)
       {
         __set_errno (-err);
         err = -1;
         break;
       }

      if (__atomic_is_v9)
       val = atomic_decrement_if_positive (&isem->value);
      else
       {
         __sparc32_atomic_do_lock24 (&isem->lock);
         val = isem->value;
         if (val > 0)
           isem->value = val - 1;
         __sparc32_atomic_do_unlock24 (&isem->lock);
       }

      if (val > 0)
       {
         err = 0;
         break;
       }
    }

  pthread_cleanup_pop (0);

  if (__atomic_is_v9)
    atomic_decrement (&isem->nwaiters);
  else
    {
      __sparc32_atomic_do_lock24 (&isem->lock);
      isem->nwaiters--;
      __sparc32_atomic_do_unlock24 (&isem->lock);
    }

  return err;
}

Here is the call graph for this function:

void attribute_hidden __sem_wait_cleanup ( void *  arg)

Definition at line 33 of file sem_wait.c.

{
  struct sparc_new_sem *isem = (struct sparc_new_sem *) arg;

  if (__atomic_is_v9)
    atomic_decrement (&isem->nwaiters);
  else
    {
      __sparc32_atomic_do_lock24 (&isem->lock);
      isem->nwaiters--;
      __sparc32_atomic_do_unlock24 (&isem->lock);
    }
}

Here is the caller graph for this function:

versioned_symbol ( libpthread  ,
__new_sem_wait  ,
sem_wait  ,
GLIBC_2_1   
)