
1: /* Low level locking macros used in NPTL implementation. Stub version. 2: Copyright (C) 2002, 2007 Free Software Foundation, Inc. 3: This file is part of the GNU C Library. 4: Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. 5: 6: The GNU C Library is free software; you can redistribute it and/or 7: modify it under the terms of the GNU Lesser General Public 8: License as published by the Free Software Foundation; either 9: version 2.1 of the License, or (at your option) any later version. 10: 11: The GNU C Library is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: Lesser General Public License for more details. 15: 16: You should have received a copy of the GNU Lesser General Public 17: License along with the GNU C Library; if not, write to the Free 18: Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19: 02111-1307 USA. */ 20: 21: #include <atomic.h> 22: 23: 24: /* Mutex lock counter: 25: bit 31 clear means unlocked; 26: bit 31 set means locked. 27: 28: All code that looks at bit 31 first increases the 'number of 29: interested threads' usage counter, which is in bits 0-30. 30: 31: All negative mutex values indicate that the mutex is still locked. */ 32: 33: 34: static inline void 35: __generic_mutex_lock (int *mutex) 36: { 37: unsigned int v; 38: 39: /* Bit 31 was clear, we got the mutex. (this is the fastpath). */ 40: if (atomic_bit_test_set (mutex, 31) == 0) 41: return; 42: 43: atomic_increment (mutex); 44: 45: while (1) 46: { 47: if (atomic_bit_test_set (mutex, 31) == 0) 48: { 49: atomic_decrement (mutex); 50: return; 51: } 52: 53: /* We have to wait now. First make sure the futex value we are 54: monitoring is truly negative (i.e. locked). */ 55: v = *mutex; 56: if (v >= 0) 57: continue; 58: 59: lll_futex_wait (mutex, v, 60: // XYZ check mutex flag 61: LLL_SHARED); 62: } 63: } 64: 65: 66: static inline void 67: __generic_mutex_unlock (int *mutex) 68: { 69: /* Adding 0x80000000 to the counter results in 0 if and only if 70: there are not other interested threads - we can return (this is 71: the fastpath). */ 72: if (atomic_add_zero (mutex, 0x80000000)) 73: return; 74: 75: /* There are other threads waiting for this mutex, wake one of them 76: up. */ 77: lll_futex_wake (mutex, 1, 78: // XYZ check mutex flag 79: LLL_SHARED); 80: } 81: 82: 83: #define lll_mutex_lock(futex) __generic_mutex_lock (&(futex)) 84: #define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex))