diff options
Diffstat (limited to 'libpthread/nptl/sysdeps/generic/lowlevellock.h')
| -rw-r--r-- | libpthread/nptl/sysdeps/generic/lowlevellock.h | 89 | 
1 files changed, 89 insertions, 0 deletions
| diff --git a/libpthread/nptl/sysdeps/generic/lowlevellock.h b/libpthread/nptl/sysdeps/generic/lowlevellock.h new file mode 100644 index 000000000..7f95daada --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/lowlevellock.h @@ -0,0 +1,89 @@ +/* Copyright (C) 2002 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <atomic.h> + + +/* Implement generic mutex.  Basic futex syscall support is required: + +     lll_futex_wait(futex, value) - call sys_futex with FUTEX_WAIT +				    and third parameter VALUE + +     lll_futex_wake(futex, value) - call sys_futex with FUTEX_WAKE +				    and third parameter VALUE +*/ + + +/* Mutex lock counter: +   bit 31 clear means unlocked; +   bit 31 set means locked. + +   All code that looks at bit 31 first increases the 'number of +   interested threads' usage counter, which is in bits 0-30. + +   All negative mutex values indicate that the mutex is still locked.  */ + + +static inline void +__generic_mutex_lock (int *mutex) +{ +  unsigned int v; + +  /* Bit 31 was clear, we got the mutex.  (this is the fastpath).  */ +  if (atomic_bit_test_set (mutex, 31) == 0) +    return; + +  atomic_increment (mutex); + +  while (1) +    { +      if (atomic_bit_test_set (mutex, 31) == 0) +	{ +	  atomic_decrement (mutex); +	  return; +	} + +      /* We have to wait now. First make sure the futex value we are +	 monitoring is truly negative (i.e. locked). */ +      v = *mutex; +      if (v >= 0) +	continue; + +      lll_futex_wait (mutex, v); +    } +} + + +static inline void +__generic_mutex_unlock (int *mutex) +{ +  /* Adding 0x80000000 to the counter results in 0 if and only if +     there are not other interested threads - we can return (this is +     the fastpath).  */ +  if (atomic_add_zero (mutex, 0x80000000)) +    return; + +  /* There are other threads waiting for this mutex, wake one of them +     up.  */ +  lll_futex_wake (mutex, 1); +} + + +#define lll_mutex_lock(futex) __generic_mutex_lock (&(futex)) +#define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex)) | 
