Back to index

glibc  2.9
Functions
lowlevelrobustlock.c File Reference
#include <errno.h>
#include <sysdep.h>
#include <lowlevellock.h>
#include <sys/time.h>
#include <pthreadP.h>

Go to the source code of this file.

Functions

int __lll_robust_lock_wait (int *futex, int private)
int __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, int private)

Function Documentation

int __lll_robust_lock_wait ( int futex,
int  private 
)

Definition at line 28 of file lowlevelrobustlock.c.

{
  int oldval = *futex;
  int tid = THREAD_GETMEM (THREAD_SELF, tid);

  /* If the futex changed meanwhile try locking again.  */
  if (oldval == 0)
    goto try;

  do
    {
      if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
       return oldval;

      int newval = oldval | FUTEX_WAITERS;
      if (oldval != newval
         && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
       continue;

      lll_futex_wait (futex, newval, private);

    try:
      ;
    }
  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
                                                 tid | FUTEX_WAITERS,
                                                 0)) != 0);
  return 0;
}
int __lll_robust_timedlock_wait ( int futex,
const struct timespec abstime,
int  private 
)

Definition at line 60 of file lowlevelrobustlock.c.

{
  /* Reject invalid timeouts.  */
  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
    return EINVAL;

  int tid = THREAD_GETMEM (THREAD_SELF, tid);
  int oldval = *futex;

  /* If the futex changed meanwhile try locking again.  */
  if (oldval == 0)
    goto try;

  do
    {
      struct timeval tv;
      struct timespec rt;

      /* Get the current time.  */
      (void) __gettimeofday (&tv, NULL);

      /* Compute relative timeout.  */
      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
      if (rt.tv_nsec < 0)
       {
         rt.tv_nsec += 1000000000;
         --rt.tv_sec;
       }

      /* Already timed out?  */
      if (rt.tv_sec < 0)
       return ETIMEDOUT;

      /* Wait.  */
      if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
       return oldval;

      int newval = oldval | FUTEX_WAITERS;
      if (oldval != newval
         && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
       continue;

      lll_futex_timed_wait (futex, newval, &rt, private);

    try:
      ;
    }
  while ((oldval = atomic_compare_and_exchange_val_acq (futex,
                                                 tid | FUTEX_WAITERS,
                                                 0)) != 0);

  return 0;
}