@@ -725,13 +725,13 @@ pub fn futex_4arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, timeout
725725 );
726726}
727727
728- /// Given an array of `futex2_waitone `, wait on each uaddr.
728+ /// Given an array of `Futex2.WaitOne `, wait on each uaddr.
729729/// The thread wakes if a futex_wake() is performed at any uaddr.
730730/// The syscall returns immediately if any futex has *uaddr != val.
731731/// timeout is an optional, absolute timeout value for the operation.
732732/// The `flags` argument is for future use and currently should be `.{}`.
733733/// Flags for private futexes, sizes, etc. should be set on the
734- /// individual flags of each `futex2_waitone `.
734+ /// individual flags of each `Futex2.WaitOne `.
735735///
736736/// Returns the array index of one of the woken futexes.
737737/// No further information is provided: any number of other futexes may also
@@ -741,20 +741,21 @@ pub fn futex_4arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, timeout
741741/// most recently woken, nor...)
742742///
743743/// Requires at least kernel v5.16.
744+ // TODO: can't we use slices here? and assert `Futex2.waitone_max`
744745pub fn futex2_waitv (
745- futexes : [* ]const futex2_waitone ,
746- /// Length of `futexes`. Max of FUTEX2_WAITONE_MAX.
747- nr_futexes : u32 ,
748- flags : FUTEX2_FLAGS_WAITV ,
746+ /// The length of `futexes` slice must not exceed `Futex2.waitone_max`
747+ futexes : []const Futex2.WaitOne ,
748+ flags : Futex2.Waitv ,
749749 /// Optional absolute timeout. Always 64-bit, even on 32-bit platforms.
750750 timeout : ? * const kernel_timespec ,
751751 /// Clock to be used for the timeout, realtime or monotonic.
752752 clockid : clockid_t ,
753753) usize {
754+ assert (futexes .len <= Futex2 .waitone_max );
754755 return syscall5 (
755756 .futex_waitv ,
756757 @intFromPtr (futexes ),
757- nr_futexes ,
758+ @intCast ( futexes . len ) ,
758759 @as (u32 , @bitCast (flags )),
759760 @intFromPtr (timeout ),
760761 @intFromEnum (clockid ),
@@ -772,8 +773,8 @@ pub fn futex2_wait(
772773 /// Value of `uaddr`.
773774 val : usize ,
774775 /// Bitmask to match against incoming wakeup masks. Must not be zero.
775- mask : usize ,
776- flags : FUTEX2_FLAGS ,
776+ mask : Futex2.Bitset ,
777+ flags : Futex2.Wait ,
777778 /// Optional absolute timeout. Always 64-bit, even on 32-bit platforms.
778779 timeout : ? * const kernel_timespec ,
779780 /// Clock to be used for the timeout, realtime or monotonic.
@@ -783,7 +784,7 @@ pub fn futex2_wait(
783784 .futex_wait ,
784785 @intFromPtr (uaddr ),
785786 val ,
786- mask ,
787+ @intFromEnum ( mask ) ,
787788 @as (u32 , @bitCast (flags )),
788789 @intFromPtr (timeout ),
789790 @intFromEnum (clockid ),
@@ -799,16 +800,16 @@ pub fn futex2_wake(
799800 /// Futex to wake
800801 uaddr : * const anyopaque ,
801802 /// Bitmask to match against waiters.
802- mask : usize ,
803+ mask : Futex2.Bitset ,
803804 /// Maximum number of waiters on the futex to wake.
804805 nr_wake : i32 ,
805- flags : FUTEX2_FLAGS ,
806+ flags : Futex2.Wake ,
806807) usize {
807808 return syscall4 (
808809 .futex_wake ,
809810 @intFromPtr (uaddr ),
810- mask ,
811- @as ( u32 , @bitCast ( nr_wake ) ),
811+ @intFromEnum ( mask ) ,
812+ @intCast ( nr_wake ),
812813 @as (u32 , @bitCast (flags )),
813814 );
814815}
@@ -817,11 +818,12 @@ pub fn futex2_wake(
817818/// Identical to `FUTEX.CMP_REQUEUE`, except it is part of the futex2 family of calls.
818819///
819820/// Requires at least kernel v6.7.
821+ // TODO: test to ensure I didn't break it
820822pub fn futex2_requeue (
821823 /// The source and destination futexes. Must be a 2-element array.
822- waiters : [ * ] const futex2_waitone ,
824+ waiters : * const [ 2 ] Futex2.WaitOne ,
823825 /// Currently unused.
824- flags : FUTEX2_FLAGS_REQUEUE ,
826+ flags : Futex2.Requeue ,
825827 /// Maximum number of waiters to wake on the source futex.
826828 nr_wake : i32 ,
827829 /// Maximum number of waiters to transfer to the destination futex.
@@ -831,8 +833,8 @@ pub fn futex2_requeue(
831833 .futex_requeue ,
832834 @intFromPtr (waiters ),
833835 @as (u32 , @bitCast (flags )),
834- @as ( u32 , @bitCast ( nr_wake ) ),
835- @as ( u32 , @bitCast ( nr_requeue ) ),
836+ @intCast ( nr_wake ),
837+ @intCast ( nr_requeue ),
836838 );
837839}
838840
@@ -3675,39 +3677,91 @@ pub const FUTEX_WAKE_OP_CMP = enum(u4) {
36753677 GE = 5 ,
36763678};
36773679
3678- /// Max numbers of elements in a `futex2_waitone` array.
3679- pub const FUTEX2_WAITONE_MAX = 128 ;
3680+ pub const Futex2 = struct {
3681+ /// Max numbers of elements in a `futex_waitv` .ie `WaitOne` array
3682+ /// matches FUTEX_WAITV_MAX
3683+ pub const waitone_max = 128 ;
36803684
3681- /// For futex v2 API, the size of the futex at the uaddr. v1 futex are
3682- /// always implicitly U32. As of kernel v6.14, only U32 is implemented
3683- /// for v2 futexes.
3684- pub const FUTEX2_SIZE = enum (u2 ) {
3685- U8 = 0 ,
3686- U16 = 1 ,
3687- U32 = 2 ,
3688- U64 = 3 ,
3689- };
3685+ /// For futex v2 API, the size of the futex at the uaddr. v1 futex are
3686+ /// always implicitly U32. As of kernel v6.14, only U32 is implemented
3687+ /// for v2 futexes.
3688+ pub const Size = enum (u2 ) {
3689+ U8 = 0 ,
3690+ U16 = 1 ,
3691+ U32 = 2 ,
3692+ U64 = 3 ,
3693+ };
36903694
3691- /// As of kernel 6.14 there are no defined flags to futex2_waitv.
3692- pub const FUTEX2_FLAGS_WAITV = packed struct (u32 ) {
3693- _reserved : u32 = 0 ,
3694- };
3695+ /// flags for `futex2_requeue` syscall
3696+ /// As of kernel 6.14 there are no defined flags to futex2_requeue.
3697+ pub const Requeue = packed struct (u32 ) {
3698+ _ : u32 = 0 ,
3699+ };
36953700
3696- /// As of kernel 6.14 there are no defined flags to futex2_requeue.
3697- pub const FUTEX2_FLAGS_REQUEUE = packed struct (u32 ) {
3698- _reserved : u32 = 0 ,
3699- };
3701+ /// flags for `futex2_waitv` syscall
3702+ /// As of kernel 6.14 there are no defined flags to futex2_waitv.
3703+ pub const Waitv = packed struct (u32 ) {
3704+ _ : u32 = 0 ,
3705+ };
37003706
3701- /// Flags for futex v2 APIs (futex2_wait, futex2_wake, futex2_requeue, but
3702- /// not the futex2_waitv syscall, but also used in the futex2_waitone struct).
3703- pub const FUTEX2_FLAGS = packed struct (u32 ) {
3704- size : FUTEX2_SIZE ,
3705- numa : bool = false ,
3706- _reserved : u4 = 0 ,
3707- private : bool ,
3708- _undefined : u24 = 0 ,
3707+ /// flags for `futex2_wait` syscall
3708+ // COMMIT: add mpol and fix private field as its 128 not 32
3709+ pub const Wait = packed struct (u32 ) {
3710+ size : Size ,
3711+ numa : bool = false ,
3712+ mpol : bool = false ,
3713+ _5 : u3 = 0 ,
3714+ private : bool ,
3715+ _9 : u24 = 0 ,
3716+ };
3717+
3718+ /// flags for `futex2_wake` syscall
3719+ pub const Wake = Wait ;
3720+
3721+ /// A waiter for vectorized wait
3722+ /// For `futex2_waitv` and `futex2_requeue`. Arrays of `WaitOne`
3723+ /// allow waiting on multiple futexes in one call.
3724+ /// matches `futex_waitv` in kernel
3725+ pub const WaitOne = extern struct {
3726+ /// Expected value at uaddr, should match size of futex.
3727+ val : u64 ,
3728+ /// User address to wait on. Top-bits must be 0 on 32-bit.
3729+ uaddr : u64 ,
3730+ /// Flags for this waiter.
3731+ flags : Wait ,
3732+ /// Reserved member to preserve data alignment.
3733+ __reserved : u32 = 0 ,
3734+ };
3735+
3736+ pub const Bitset = enum (u64 ) {
3737+ /// matches FUTEX_WAIT_BITSET
3738+ wait = 9 ,
3739+ /// matches FUTEX_WAKE_BITSET
3740+ wake = 10 ,
3741+ /// bitset with all bits set for the FUTEX_xxx_BITSET OPs to request a
3742+ /// match of any bit.
3743+ match_any = 0xffffffff ,
3744+ };
37093745};
37103746
3747+ /// DEPRECATED use `Futex2.WaitOne`
3748+ pub const futex2_waitone = Futex2 .WaitOne ;
3749+
3750+ /// DEPRECATED use constant in `Futex2`
3751+ pub const FUTEX2_WAITONE_MAX = Futex2 .waitone_max ;
3752+
3753+ /// DEPRECATED use `Size` type in `Futex2`
3754+ pub const FUTEX2_SIZE = Futex2 .Size ;
3755+
3756+ /// DEPRECATED use `Waitv` in `Futex2`
3757+ pub const FUTEX2_FLAGS_WAITV = Futex2 .Waitv ;
3758+
3759+ /// DEPRECATED use `Requeue` in `Futex2`
3760+ pub const FUTEX2_FLAGS_REQUEUE = Futex2 .Requeue ;
3761+
3762+ /// DEPRECATED use `Wait` in `Futex2`
3763+ pub const FUTEX2_FLAGS = Futex2 .Wait ;
3764+
37113765pub const PROT = struct {
37123766 /// page can not be accessed
37133767 pub const NONE = 0x0 ;
@@ -9860,19 +9914,6 @@ pub const PTRACE = struct {
98609914 };
98619915};
98629916
9863- /// For futex2_waitv and futex2_requeue. Arrays of `futex2_waitone` allow
9864- /// waiting on multiple futexes in one call.
9865- pub const futex2_waitone = extern struct {
9866- /// Expected value at uaddr, should match size of futex.
9867- val : u64 ,
9868- /// User address to wait on. Top-bits must be 0 on 32-bit.
9869- uaddr : u64 ,
9870- /// Flags for this waiter.
9871- flags : FUTEX2_FLAGS ,
9872- /// Reserved member to preserve alignment.
9873- __reserved : u32 = 0 ,
9874- };
9875-
98769917pub const cache_stat_range = extern struct {
98779918 off : u64 ,
98789919 len : u64 ,
0 commit comments