diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2008-02-01 11:45:14 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-02-01 11:45:14 -0500 |
commit | cd689985cf49f6ff5c8eddc48d98b9d581d9475d (patch) | |
tree | a1a119402f5208c45c21b855e8d2fbbaf18cfd72 /include | |
parent | 83e96c604e781098a2f61b8a294919bcf3abfab4 (diff) |
futex: Add bitset conditional wait/wakeup functionality
To allow the implementation of optimized rw-locks in user space, glibc
needs a possibility to select waiters for wakeup depending on a bitset
mask.
This requires two new futex OPs: FUTEX_WAIT_BITS and FUTEX_WAKE_BITS
These OPs are basically the same as FUTEX_WAIT and FUTEX_WAKE plus an
additional argument - a bitset. Further the FUTEX_WAIT_BITS OP is
expecting an absolute timeout value instead of the relative one, which
is used for the FUTEX_WAIT OP.
FUTEX_WAIT_BITS calls into the kernel with a bitset. The bitset is
stored in the futex_q structure, which is used to enqueue the waiter
into the hashed futex waitqueue.
FUTEX_WAKE_BITS also calls into the kernel with a bitset. The wakeup
function logically ANDs the bitset with the bitset stored in each
waiters futex_q structure. If the result is zero (i.e. none of the set
bits in the bitsets is matching), then the waiter is not woken up. If
the result is not zero (i.e. one of the set bits in the bitsets is
matching), then the waiter is woken.
The bitset provided by the caller must be non zero. In case the
provided bitset is zero the kernel returns EINVAL.
Internaly the new OPs are only extensions to the existing FUTEX_WAIT
and FUTEX_WAKE functions. The existing OPs hand a bitset with all bits
set into the futex_wait() and futex_wake() functions.
Signed-off-by: Thomas Gleixner <tgxl@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/futex.h | 10 | ||||
-rw-r--r-- | include/linux/thread_info.h | 1 |
2 files changed, 11 insertions, 0 deletions
diff --git a/include/linux/futex.h b/include/linux/futex.h index 1a15f8e237a7..90048fb28a38 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h | |||
@@ -21,6 +21,8 @@ union ktime; | |||
21 | #define FUTEX_LOCK_PI 6 | 21 | #define FUTEX_LOCK_PI 6 |
22 | #define FUTEX_UNLOCK_PI 7 | 22 | #define FUTEX_UNLOCK_PI 7 |
23 | #define FUTEX_TRYLOCK_PI 8 | 23 | #define FUTEX_TRYLOCK_PI 8 |
24 | #define FUTEX_WAIT_BITSET 9 | ||
25 | #define FUTEX_WAKE_BITSET 10 | ||
24 | 26 | ||
25 | #define FUTEX_PRIVATE_FLAG 128 | 27 | #define FUTEX_PRIVATE_FLAG 128 |
26 | #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG | 28 | #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG |
@@ -33,6 +35,8 @@ union ktime; | |||
33 | #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) | 35 | #define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) |
34 | #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) | 36 | #define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) |
35 | #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) | 37 | #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) |
38 | #define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG) | ||
39 | #define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG) | ||
36 | 40 | ||
37 | /* | 41 | /* |
38 | * Support for robust futexes: the kernel cleans up held futexes at | 42 | * Support for robust futexes: the kernel cleans up held futexes at |
@@ -111,6 +115,12 @@ struct robust_list_head { | |||
111 | */ | 115 | */ |
112 | #define ROBUST_LIST_LIMIT 2048 | 116 | #define ROBUST_LIST_LIMIT 2048 |
113 | 117 | ||
118 | /* | ||
119 | * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a | ||
120 | * match of any bit. | ||
121 | */ | ||
122 | #define FUTEX_BITSET_MATCH_ANY 0xffffffff | ||
123 | |||
114 | #ifdef __KERNEL__ | 124 | #ifdef __KERNEL__ |
115 | long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout, | 125 | long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout, |
116 | u32 __user *uaddr2, u32 val2, u32 val3); | 126 | u32 __user *uaddr2, u32 val2, u32 val3); |
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index dfbdfb9836f4..421323e5a2d6 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h | |||
@@ -23,6 +23,7 @@ struct restart_block { | |||
23 | u32 *uaddr; | 23 | u32 *uaddr; |
24 | u32 val; | 24 | u32 val; |
25 | u32 flags; | 25 | u32 flags; |
26 | u32 bitset; | ||
26 | u64 time; | 27 | u64 time; |
27 | } futex; | 28 | } futex; |
28 | }; | 29 | }; |