zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

futex.h (6126B) - Raw


      1 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
      2 #ifndef _LINUX_FUTEX_H
      3 #define _LINUX_FUTEX_H
      4 
      5 
      6 #include <linux/types.h>
      7 
      8 /* Second argument to futex syscall */
      9 
     10 
     11 #define FUTEX_WAIT		0
     12 #define FUTEX_WAKE		1
     13 #define FUTEX_FD		2
     14 #define FUTEX_REQUEUE		3
     15 #define FUTEX_CMP_REQUEUE	4
     16 #define FUTEX_WAKE_OP		5
     17 #define FUTEX_LOCK_PI		6
     18 #define FUTEX_UNLOCK_PI		7
     19 #define FUTEX_TRYLOCK_PI	8
     20 #define FUTEX_WAIT_BITSET	9
     21 #define FUTEX_WAKE_BITSET	10
     22 #define FUTEX_WAIT_REQUEUE_PI	11
     23 #define FUTEX_CMP_REQUEUE_PI	12
     24 #define FUTEX_LOCK_PI2		13
     25 
     26 #define FUTEX_PRIVATE_FLAG	128
     27 #define FUTEX_CLOCK_REALTIME	256
     28 #define FUTEX_CMD_MASK		~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME)
     29 
     30 #define FUTEX_WAIT_PRIVATE	(FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
     31 #define FUTEX_WAKE_PRIVATE	(FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
     32 #define FUTEX_REQUEUE_PRIVATE	(FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG)
     33 #define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG)
     34 #define FUTEX_WAKE_OP_PRIVATE	(FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG)
     35 #define FUTEX_LOCK_PI_PRIVATE	(FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
     36 #define FUTEX_LOCK_PI2_PRIVATE	(FUTEX_LOCK_PI2 | FUTEX_PRIVATE_FLAG)
     37 #define FUTEX_UNLOCK_PI_PRIVATE	(FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
     38 #define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
     39 #define FUTEX_WAIT_BITSET_PRIVATE	(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
     40 #define FUTEX_WAKE_BITSET_PRIVATE	(FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
     41 #define FUTEX_WAIT_REQUEUE_PI_PRIVATE	(FUTEX_WAIT_REQUEUE_PI | \
     42 					 FUTEX_PRIVATE_FLAG)
     43 #define FUTEX_CMP_REQUEUE_PI_PRIVATE	(FUTEX_CMP_REQUEUE_PI | \
     44 					 FUTEX_PRIVATE_FLAG)
     45 
     46 /*
     47  * Flags for futex2 syscalls.
     48  *
     49  * NOTE: these are not pure flags, they can also be seen as:
     50  *
     51  *   union {
     52  *     u32  flags;
     53  *     struct {
     54  *       u32 size    : 2,
     55  *           numa    : 1,
     56  *                   : 4,
     57  *           private : 1;
     58  *     };
     59  *   };
     60  */
     61 #define FUTEX2_SIZE_U8		0x00
     62 #define FUTEX2_SIZE_U16		0x01
     63 #define FUTEX2_SIZE_U32		0x02
     64 #define FUTEX2_SIZE_U64		0x03
     65 #define FUTEX2_NUMA		0x04
     66 			/*	0x08 */
     67 			/*	0x10 */
     68 			/*	0x20 */
     69 			/*	0x40 */
     70 #define FUTEX2_PRIVATE		FUTEX_PRIVATE_FLAG
     71 
     72 #define FUTEX2_SIZE_MASK	0x03
     73 
     74 /* do not use */
     75 #define FUTEX_32		FUTEX2_SIZE_U32 /* historical accident :-( */
     76 
     77 /*
     78  * Max numbers of elements in a futex_waitv array
     79  */
     80 #define FUTEX_WAITV_MAX		128
     81 
     82 /**
     83  * struct futex_waitv - A waiter for vectorized wait
     84  * @val:	Expected value at uaddr
     85  * @uaddr:	User address to wait on
     86  * @flags:	Flags for this waiter
     87  * @__reserved:	Reserved member to preserve data alignment. Should be 0.
     88  */
     89 struct futex_waitv {
     90 	__u64 val;
     91 	__u64 uaddr;
     92 	__u32 flags;
     93 	__u32 __reserved;
     94 };
     95 
     96 /*
     97  * Support for robust futexes: the kernel cleans up held futexes at
     98  * thread exit time.
     99  */
    100 
    101 /*
    102  * Per-lock list entry - embedded in user-space locks, somewhere close
    103  * to the futex field. (Note: user-space uses a double-linked list to
    104  * achieve O(1) list add and remove, but the kernel only needs to know
    105  * about the forward link)
    106  *
    107  * NOTE: this structure is part of the syscall ABI, and must not be
    108  * changed.
    109  */
    110 struct robust_list {
    111 	struct robust_list *next;
    112 };
    113 
    114 /*
    115  * Per-thread list head:
    116  *
    117  * NOTE: this structure is part of the syscall ABI, and must only be
    118  * changed if the change is first communicated with the glibc folks.
    119  * (When an incompatible change is done, we'll increase the structure
    120  *  size, which glibc will detect)
    121  */
    122 struct robust_list_head {
    123 	/*
    124 	 * The head of the list. Points back to itself if empty:
    125 	 */
    126 	struct robust_list list;
    127 
    128 	/*
    129 	 * This relative offset is set by user-space, it gives the kernel
    130 	 * the relative position of the futex field to examine. This way
    131 	 * we keep userspace flexible, to freely shape its data-structure,
    132 	 * without hardcoding any particular offset into the kernel:
    133 	 */
    134 	long futex_offset;
    135 
    136 	/*
    137 	 * The death of the thread may race with userspace setting
    138 	 * up a lock's links. So to handle this race, userspace first
    139 	 * sets this field to the address of the to-be-taken lock,
    140 	 * then does the lock acquire, and then adds itself to the
    141 	 * list, and then clears this field. Hence the kernel will
    142 	 * always have full knowledge of all locks that the thread
    143 	 * _might_ have taken. We check the owner TID in any case,
    144 	 * so only truly owned locks will be handled.
    145 	 */
    146 	struct robust_list *list_op_pending;
    147 };
    148 
    149 /*
    150  * Are there any waiters for this robust futex:
    151  */
    152 #define FUTEX_WAITERS		0x80000000
    153 
    154 /*
    155  * The kernel signals via this bit that a thread holding a futex
    156  * has exited without unlocking the futex. The kernel also does
    157  * a FUTEX_WAKE on such futexes, after setting the bit, to wake
    158  * up any possible waiters:
    159  */
    160 #define FUTEX_OWNER_DIED	0x40000000
    161 
    162 /*
    163  * The rest of the robust-futex field is for the TID:
    164  */
    165 #define FUTEX_TID_MASK		0x3fffffff
    166 
    167 /*
    168  * This limit protects against a deliberately circular list.
    169  * (Not worth introducing an rlimit for it)
    170  */
    171 #define ROBUST_LIST_LIMIT	2048
    172 
    173 /*
    174  * bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
    175  * match of any bit.
    176  */
    177 #define FUTEX_BITSET_MATCH_ANY	0xffffffff
    178 
    179 
    180 #define FUTEX_OP_SET		0	/* *(int *)UADDR2 = OPARG; */
    181 #define FUTEX_OP_ADD		1	/* *(int *)UADDR2 += OPARG; */
    182 #define FUTEX_OP_OR		2	/* *(int *)UADDR2 |= OPARG; */
    183 #define FUTEX_OP_ANDN		3	/* *(int *)UADDR2 &= ~OPARG; */
    184 #define FUTEX_OP_XOR		4	/* *(int *)UADDR2 ^= OPARG; */
    185 
    186 #define FUTEX_OP_OPARG_SHIFT	8	/* Use (1 << OPARG) instead of OPARG.  */
    187 
    188 #define FUTEX_OP_CMP_EQ		0	/* if (oldval == CMPARG) wake */
    189 #define FUTEX_OP_CMP_NE		1	/* if (oldval != CMPARG) wake */
    190 #define FUTEX_OP_CMP_LT		2	/* if (oldval < CMPARG) wake */
    191 #define FUTEX_OP_CMP_LE		3	/* if (oldval <= CMPARG) wake */
    192 #define FUTEX_OP_CMP_GT		4	/* if (oldval > CMPARG) wake */
    193 #define FUTEX_OP_CMP_GE		5	/* if (oldval >= CMPARG) wake */
    194 
    195 /* FUTEX_WAKE_OP will perform atomically
    196    int oldval = *(int *)UADDR2;
    197    *(int *)UADDR2 = oldval OP OPARG;
    198    if (oldval CMP CMPARG)
    199      wake UADDR2;  */
    200 
    201 #define FUTEX_OP(op, oparg, cmp, cmparg) \
    202   (((op & 0xf) << 28) | ((cmp & 0xf) << 24)		\
    203    | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
    204 
    205 #endif /* _LINUX_FUTEX_H */