1 /*        $NetBSD: futex.h,v 1.7 2025/03/05 12:02:00 riastradh Exp $  */
2 
3 /*-
4  * Copyright (c) 2018, 2019 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Taylor R. Campbell and Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 2005 Emmanuel Dreyfus, all rights reserved.
34  *
35  * Redistribution and use in source and binary forms, with or without
36  * modification, are permitted provided that the following conditions
37  * are met:
38  * 1. Redistributions of source code must retain the above copyright
39  *    notice, this list of conditions and the following disclaimer.
40  * 2. Redistributions in binary form must reproduce the above copyright
41  *    notice, this list of conditions and the following disclaimer in the
42  *    documentation and/or other materials provided with the distribution.
43  * 3. All advertising materials mentioning features or use of this software
44  *    must display the following acknowledgement:
45  *        This product includes software developed by Emmanuel Dreyfus
46  * 4. The name of the author may not be used to endorse or promote
47  *    products derived from this software without specific prior written
48  *    permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
51  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
52  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
54  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
62 
63 #ifndef _SYS_FUTEX_H_
64 #define _SYS_FUTEX_H_
65 
66 /*
67  * Definitions for the __futex(2) synchronization primitive.
68  *
69  * These definitions are intended to be ABI-compatible with the
70  * Linux futex(2) system call.
71  */
72 
73 #include <sys/timespec.h>
74 
75 #define FUTEX_WAIT                        0
76 #define FUTEX_WAKE                        1
77 #define FUTEX_FD                          2
78 #define FUTEX_REQUEUE                               3
79 #define FUTEX_CMP_REQUEUE                 4
80 #define FUTEX_WAKE_OP                               5
81 #define FUTEX_LOCK_PI                               6
82 #define FUTEX_UNLOCK_PI                             7
83 #define FUTEX_TRYLOCK_PI                  8
84 #define FUTEX_WAIT_BITSET                 9
85 #define FUTEX_WAKE_BITSET                10
86 #define FUTEX_WAIT_REQUEUE_PI            11
87 #define FUTEX_CMP_REQUEUE_PI             12
88 
89 #define FUTEX_PRIVATE_FLAG              __BIT(7)
90 #define FUTEX_CLOCK_REALTIME            __BIT(8)
91 
92 #define FUTEX_CMD_MASK                            \
93     (~(FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME))
94 
95 #define FUTEX_OP_OP_MASK                __BITS(28,31)
96 #define FUTEX_OP_CMP_MASK               __BITS(24,27)
97 #define FUTEX_OP_OPARG_MASK             __BITS(12,23)
98 #define FUTEX_OP_CMPARG_MASK            __BITS(0,11)
99 
100 #define FUTEX_OP(op, oparg, cmp, cmparg)                     \
101           (__SHIFTIN((op) & 0xf, FUTEX_OP_OP_MASK)          |\
102            __SHIFTIN((oparg) & 0xfff, FUTEX_OP_OPARG_MASK)|\
103            __SHIFTIN((cmp) & 0xf, FUTEX_OP_CMP_MASK)        |\
104            __SHIFTIN((cmparg) & 0xfff, FUTEX_OP_CMPARG_MASK))
105 
106 #define FUTEX_OP_SET                    0
107 #define FUTEX_OP_ADD                    1
108 #define FUTEX_OP_OR           2
109 #define FUTEX_OP_ANDN                   3
110 #define FUTEX_OP_XOR                    4
111 #define FUTEX_OP_OPARG_SHIFT  8
112 
113 #define FUTEX_OP_CMP_EQ                 0
114 #define FUTEX_OP_CMP_NE                 1
115 #define FUTEX_OP_CMP_LT                 2
116 #define FUTEX_OP_CMP_LE                 3
117 #define FUTEX_OP_CMP_GT                 4
118 #define FUTEX_OP_CMP_GE                 5
119 
120 /*
121  * FUTEX_SYNCOBJ_0 and FUTEX_SYNCOBJ_1 are extensions to the Linux
122  * futex API that are reserved for individual consumers of futexes
123  * to define information specific to that synchronzation object.
124  * Note that as a result there is a system-wide upper limit of
125  * 268,435,455 threads (as opposed to 1,073,741,823).
126  */
127 #define FUTEX_WAITERS                   ((int)__BIT(31))
128 #define FUTEX_OWNER_DIED      ((int)__BIT(30))
129 #define FUTEX_SYNCOBJ_1                 ((int)__BIT(29))
130 #define FUTEX_SYNCOBJ_0                 ((int)__BIT(28))
131 #define FUTEX_TID_MASK                  ((int)__BITS(0,27))
132 
133 #define FUTEX_BITSET_MATCH_ANY  ((int)__BITS(0,31))
134 
135 /*
136  * The robust futex ABI consists of an array of 3 longwords, the address
137  * of which is registered with the kernel on a per-thread basis:
138  *
139  *        0: A pointer to a singly-linked list of "lock entries".  If the
140  *           list is empty, this points back to the list itself.
141  *
142  *        1: An offset from address of the "lock entry" to the 32-bit futex
143  *           word associated with that lock entry (may be negative).
144  *
145  *        2: A "pending" pointer, for locks that are in the process of being
146  *           acquired or released.
147  *
148  * PI futexes are handled slightly differently.  User-space indicates
149  * an entry is for a PI futex by setting the last-significant bit.
150  */
151 #define _FUTEX_ROBUST_HEAD_LIST                   0
152 #define _FUTEX_ROBUST_HEAD_OFFSET       1
153 #define _FUTEX_ROBUST_HEAD_PENDING      2
154 #define _FUTEX_ROBUST_HEAD_NWORDS       3
155 #define _FUTEX_ROBUST_HEAD_SIZE                   (_FUTEX_ROBUST_HEAD_NWORDS * \
156                                                    sizeof(u_long))
157 #define _FUTEX_ROBUST_HEAD_SIZE32       (_FUTEX_ROBUST_HEAD_NWORDS * \
158                                                    sizeof(uint32_t))
159 #define   _FUTEX_ROBUST_ENTRY_PI                  __BIT(0)
160 
161 #ifdef __LIBC_FUTEX_PRIVATE
162 struct futex_robust_list {
163           struct futex_robust_list      *next;
164 };
165 
166 struct futex_robust_list_head {
167           struct futex_robust_list      list;
168           long                                    futex_offset;
169           struct futex_robust_list      *pending_list;
170 };
171 #endif /* __LIBC_FUTEX_PRIVATE */
172 
173 #ifdef _KERNEL
174 struct lwp;
175 
176 int       futex_robust_head_lookup(struct lwp *, lwpid_t, void **);
177 void      futex_release_all_lwp(struct lwp *);
178 int       do_futex(int *, int, int, const struct timespec *, int *, int,
179               int, register_t *);
180 void      futex_sys_init(void);
181 void      futex_sys_fini(void);
182 #endif /* _KERNEL */
183 
184 #endif /* ! _SYS_FUTEX_H_ */
185