1 /* Copyright (C) 2003-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
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.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef _LOWLEVELLOCK_H
20 #define _LOWLEVELLOCK_H 1
23 #include <sys/param.h>
24 #include <bits/pthreadtypes.h>
26 #include <kernel-features.h>
28 #include <lowlevellock-futex.h>
31 __attribute__ ((always_inline
))
32 __lll_trylock (int *futex
)
34 return atomic_compare_and_exchange_val_24_acq (futex
, 1, 0) != 0;
36 #define lll_trylock(futex) __lll_trylock (&(futex))
39 __attribute__ ((always_inline
))
40 __lll_cond_trylock (int *futex
)
42 return atomic_compare_and_exchange_val_24_acq (futex
, 2, 0) != 0;
44 #define lll_cond_trylock(futex) __lll_cond_trylock (&(futex))
47 extern void __lll_lock_wait_private (int *futex
) attribute_hidden
;
48 extern void __lll_lock_wait (int *futex
, int private) attribute_hidden
;
51 __attribute__ ((always_inline
))
52 __lll_lock (int *futex
, int private)
54 int val
= atomic_compare_and_exchange_val_24_acq (futex
, 1, 0);
56 if (__glibc_unlikely (val
!= 0))
58 if (__builtin_constant_p (private) && private == LLL_PRIVATE
)
59 __lll_lock_wait_private (futex
);
61 __lll_lock_wait (futex
, private);
64 #define lll_lock(futex, private) __lll_lock (&(futex), private)
67 __attribute__ ((always_inline
))
68 __lll_cond_lock (int *futex
, int private)
70 int val
= atomic_compare_and_exchange_val_24_acq (futex
, 2, 0);
72 if (__glibc_unlikely (val
!= 0))
73 __lll_lock_wait (futex
, private);
75 #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
78 extern int __lll_timedlock_wait (int *futex
, const struct timespec
*,
79 int private) attribute_hidden
;
82 __attribute__ ((always_inline
))
83 __lll_timedlock (int *futex
, const struct timespec
*abstime
, int private)
85 int val
= atomic_compare_and_exchange_val_24_acq (futex
, 1, 0);
88 if (__glibc_unlikely (val
!= 0))
89 result
= __lll_timedlock_wait (futex
, abstime
, private);
92 #define lll_timedlock(futex, abstime, private) \
93 __lll_timedlock (&(futex), abstime, private)
95 #define lll_unlock(lock, private) \
97 int *__futex = &(lock); \
98 int __private = (private); \
99 int __val = atomic_exchange_24_rel (__futex, 0); \
100 if (__glibc_unlikely (__val > 1)) \
101 lll_futex_wake (__futex, 1, __private); \
104 #define lll_islocked(futex) \
107 /* Initializers for lock. */
108 #define LLL_LOCK_INITIALIZER (0)
109 #define LLL_LOCK_INITIALIZER_LOCKED (1)
111 /* The kernel notifies a process which uses CLONE_CHILD_CLEARTID via futex
112 wakeup when the clone terminates. The memory location contains the
113 thread ID while the clone is running and is reset to zero
115 #define lll_wait_tid(tid) \
118 __typeof (tid) __tid; \
119 while ((__tid = (tid)) != 0) \
120 lll_futex_wait (&(tid), __tid, LLL_SHARED); \
124 extern int __lll_timedwait_tid (int *, const struct timespec
*)
127 #define lll_timedwait_tid(tid, abstime) \
131 __res = __lll_timedwait_tid (&(tid), (abstime)); \
135 #endif /* lowlevellock.h */