lowlevellock.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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, write to the Free
  15. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  16. 02111-1307 USA. */
  17. #include <atomic.h>
  18. /* Mutex lock counter:
  19. bit 31 clear means unlocked;
  20. bit 31 set means locked.
  21. All code that looks at bit 31 first increases the 'number of
  22. interested threads' usage counter, which is in bits 0-30.
  23. All negative mutex values indicate that the mutex is still locked. */
  24. static inline void
  25. __generic_mutex_lock (int *mutex)
  26. {
  27. unsigned int v;
  28. /* Bit 31 was clear, we got the mutex. (this is the fastpath). */
  29. if (atomic_bit_test_set (mutex, 31) == 0)
  30. return;
  31. atomic_increment (mutex);
  32. while (1)
  33. {
  34. if (atomic_bit_test_set (mutex, 31) == 0)
  35. {
  36. atomic_decrement (mutex);
  37. return;
  38. }
  39. /* We have to wait now. First make sure the futex value we are
  40. monitoring is truly negative (i.e. locked). */
  41. v = *mutex;
  42. if (v >= 0)
  43. continue;
  44. lll_futex_wait (mutex, v,
  45. // XYZ check mutex flag
  46. LLL_SHARED);
  47. }
  48. }
  49. static inline void
  50. __generic_mutex_unlock (int *mutex)
  51. {
  52. /* Adding 0x80000000 to the counter results in 0 if and only if
  53. there are not other interested threads - we can return (this is
  54. the fastpath). */
  55. if (atomic_add_zero (mutex, 0x80000000))
  56. return;
  57. /* There are other threads waiting for this mutex, wake one of them
  58. up. */
  59. lll_futex_wake (mutex, 1,
  60. // XYZ check mutex flag
  61. LLL_SHARED);
  62. }
  63. #define lll_mutex_lock(futex) __generic_mutex_lock (&(futex))
  64. #define lll_mutex_unlock(futex) __generic_mutex_unlock (&(futex))