lowlevellock.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include <atomic.h>
  17. /* Mutex lock counter:
  18. bit 31 clear means unlocked;
  19. bit 31 set means locked.
  20. All code that looks at bit 31 first increases the 'number of
  21. interested threads' usage counter, which is in bits 0-30.
  22. All negative mutex values indicate that the mutex is still locked. */
  23. static inline void
  24. __generic_mutex_lock (int *mutex)
  25. {
  26. unsigned int v;
  27. /* Bit 31 was clear, we got the mutex. (this is the fastpath). */
  28. if (atomic_bit_test_set (mutex, 31) == 0)
  29. return;
  30. atomic_increment (mutex);
  31. while (1)
  32. {
  33. if (atomic_bit_test_set (mutex, 31) == 0)
  34. {
  35. atomic_decrement (mutex);
  36. return;
  37. }
  38. /* We have to wait now. First make sure the futex value we are
  39. monitoring is truly negative (i.e. locked). */
  40. v = *mutex;
  41. if (v >= 0)
  42. continue;
  43. lll_futex_wait (mutex, v,
  44. // XYZ check mutex flag
  45. LLL_SHARED);
  46. }
  47. }
  48. static inline void
  49. __generic_mutex_unlock (int *mutex)
  50. {
  51. /* Adding 0x80000000 to the counter results in 0 if and only if
  52. there are not other interested threads - we can return (this is
  53. the fastpath). */
  54. if (atomic_add_zero (mutex, 0x80000000))
  55. return;
  56. /* There are other threads waiting for this mutex, wake one of them
  57. up. */
  58. lll_futex_wake (mutex, 1,
  59. // XYZ check mutex flag
  60. LLL_SHARED);
  61. }
  62. #define lll_mutex_lock(futex) __generic_mutex_lock (&(futex))
  63. #define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex))