| ... | ... | @@ -323,6 +323,113 @@ pub fn futex_wake(uaddr: *const i32, futex_op: u32, val: i32) usize { |
| 323 | 323 | return syscall3(.futex, @intFromPtr(uaddr), futex_op, @as(u32, @bitCast(val))); |
| 324 | 324 | } |
| 325 | 325 | |
| 326 | /// Given an array of `futex_waitv`, wait on each uaddr. |
| 327 | /// The thread wakes if a futex_wake() is performed at any uaddr. |
| 328 | /// The syscall returns immediately if any waiter has *uaddr != val. |
| 329 | /// timeout is an optional timeout value for the operation. |
| 330 | /// Each waiter has individual flags. |
| 331 | /// The `flags` argument for the syscall should be used solely for specifying |
| 332 | /// the timeout as realtime, if needed. |
| 333 | /// Flags for private futexes, sizes, etc. should be used on the |
| 334 | /// individual flags of each waiter. |
| 335 | /// |
| 336 | /// Returns the array index of one of the woken futexes. |
| 337 | /// No further information is provided: any number of other futexes may also |
| 338 | /// have been woken by the same event, and if more than one futex was woken, |
| 339 | /// the retrned index may refer to any one of them. |
| 340 | /// (It is not necessaryily the futex with the smallest index, nor the one |
| 341 | /// most recently woken, nor...) |
| 342 | pub fn futex2_waitv( |
| 343 | /// List of futexes to wait on. |
| 344 | waiters: [*]futex_waitv, |
| 345 | /// Length of `waiters`. |
| 346 | nr_futexes: u32, |
| 347 | /// Flag for timeout (monotonic/realtime). |
| 348 | flags: u32, |
| 349 | /// Optional absolute timeout. |
| 350 | timeout: ?*const timespec, |
| 351 | /// Clock to be used for the timeout, realtime or monotonic. |
| 352 | clockid: i32, |
| 353 | ) usize { |
| 354 | return syscall6( |
| 355 | .futex_waitv, |
| 356 | @intFromPtr(waiters), |
| 357 | nr_futexes, |
| 358 | flags, |
| 359 | @intFromPtr(timeout), |
| 360 | @bitCast(@as(isize, clockid)), |
| 361 | ); |
| 362 | } |
| 363 | |
| 364 | /// Wait on a futex. |
| 365 | /// Identical to `FUTEX.WAIT`, except it is part of the futex2 family of calls. |
| 366 | pub fn futex2_wait( |
| 367 | /// Address of the futex to wait on. |
| 368 | uaddr: *const anyopaque, |
| 369 | /// Value of `uaddr`. |
| 370 | val: usize, |
| 371 | /// Bitmask. |
| 372 | mask: usize, |
| 373 | /// `FUTEX2` flags. |
| 374 | flags: u32, |
| 375 | /// Optional absolute timeout. |
| 376 | timeout: *const timespec, |
| 377 | /// Clock to be used for the timeout, realtime or monotonic. |
| 378 | clockid: i32, |
| 379 | ) usize { |
| 380 | return syscall6( |
| 381 | .futex_wait, |
| 382 | @intFromPtr(uaddr), |
| 383 | val, |
| 384 | mask, |
| 385 | flags, |
| 386 | @intFromPtr(timeout), |
| 387 | @bitCast(@as(isize, clockid)), |
| 388 | ); |
| 389 | } |
| 390 | |
| 391 | /// Wake a number of futexes. |
| 392 | /// Identical to `FUTEX.WAKE`, except it is part of the futex2 family of calls. |
| 393 | pub fn futex2_wake( |
| 394 | /// Address of the futex(es) to wake. |
| 395 | uaddr: [*]const anyopaque, |
| 396 | /// Bitmask |
| 397 | mask: usize, |
| 398 | /// Number of the futexes to wake. |
| 399 | nr: i32, |
| 400 | /// `FUTEX2` flags. |
| 401 | flags: u32, |
| 402 | ) usize { |
| 403 | return syscall4( |
| 404 | .futex_wake, |
| 405 | @intFromPtr(uaddr), |
| 406 | mask, |
| 407 | @bitCast(@as(isize, nr)), |
| 408 | flags, |
| 409 | ); |
| 410 | } |
| 411 | |
| 412 | /// Requeue a waiter from one futex to another. |
| 413 | /// Identical to `FUTEX.CMP_REQUEUE`, except it is part of the futex2 family of calls. |
| 414 | pub fn futex2_requeue( |
| 415 | /// Array describing the source and destination futex. |
| 416 | waiters: [*]futex_waitv, |
| 417 | /// Unsed. |
| 418 | flags: u32, |
| 419 | /// Number of futexes to wake. |
| 420 | nr_wake: i32, |
| 421 | /// Number of futexes to requeue. |
| 422 | nr_requeue: i32, |
| 423 | ) usize { |
| 424 | return syscall4( |
| 425 | .futex_requeue, |
| 426 | @intFromPtr(waiters), |
| 427 | flags, |
| 428 | @bitCast(@as(isize, nr_wake)), |
| 429 | @bitCast(@as(isize, nr_requeue)), |
| 430 | ); |
| 431 | } |
| 432 | |
| 326 | 433 | pub fn getcwd(buf: [*]u8, size: usize) usize { |
| 327 | 434 | return syscall2(.getcwd, @intFromPtr(buf), size); |
| 328 | 435 | } |
| ... | ... | @@ -1901,10 +2008,17 @@ pub fn ptrace( |
| 1901 | 2008 | ); |
| 1902 | 2009 | } |
| 1903 | 2010 | |
| 2011 | /// Query the page cache statistics of a file. |
| 1904 | 2012 | pub fn cachestat( |
| 2013 | /// The open file descriptor to retrieve statistics from. |
| 1905 | 2014 | fd: fd_t, |
| 2015 | /// The byte range in `fd` to query. |
| 2016 | /// When `len > 0`, the range is `[off..off + len]`. |
| 2017 | /// When `len` == 0, the range is from `off` to the end of `fd`. |
| 1906 | 2018 | cstat_range: *const cache_stat_range, |
| 2019 | /// The structure where page cache statistics are stored. |
| 1907 | 2020 | cstat: *cache_stat, |
| 2021 | /// Currently unused, and must be set to `0`. |
| 1908 | 2022 | flags: u32, |
| 1909 | 2023 | ) usize { |
| 1910 | 2024 | return syscall4( |
| ... | ... | @@ -1916,6 +2030,10 @@ pub fn cachestat( |
| 1916 | 2030 | ); |
| 1917 | 2031 | } |
| 1918 | 2032 | |
| 2033 | pub fn map_shadow_stack(addr: u64, size: u64, flags: u32) usize { |
| 2034 | return syscall3(.map_shadow_stack, addr, size, flags); |
| 2035 | } |
| 2036 | |
| 1919 | 2037 | pub const E = switch (native_arch) { |
| 1920 | 2038 | .mips, .mipsel => @import("linux/errno/mips.zig").E, |
| 1921 | 2039 | .sparc, .sparcel, .sparc64 => @import("linux/errno/sparc.zig").E, |
| ... | ... | @@ -2016,6 +2134,19 @@ pub const FUTEX = struct { |
| 2016 | 2134 | pub const PRIVATE_FLAG = 128; |
| 2017 | 2135 | |
| 2018 | 2136 | pub const CLOCK_REALTIME = 256; |
| 2137 | |
| 2138 | /// Max numbers of elements in a `futex_waitv` array. |
| 2139 | pub const WAITV_MAX = 128; |
| 2140 | }; |
| 2141 | |
| 2142 | pub const FUTEX2 = struct { |
| 2143 | pub const SIZE_U8 = 0x00; |
| 2144 | pub const SIZE_U16 = 0x01; |
| 2145 | pub const SIZE_U32 = 0x02; |
| 2146 | pub const SIZE_U64 = 0x03; |
| 2147 | pub const NUMA = 0x04; |
| 2148 | |
| 2149 | pub const PRIVATE = FUTEX.PRIVATE_FLAG; |
| 2019 | 2150 | }; |
| 2020 | 2151 | |
| 2021 | 2152 | pub const PROT = struct { |
| ... | ... | @@ -6100,15 +6231,41 @@ pub const PTRACE = struct { |
| 6100 | 6231 | pub const GET_SYSCALL_INFO = 0x420e; |
| 6101 | 6232 | }; |
| 6102 | 6233 | |
| 6234 | /// A waiter for vectorized wait. |
| 6235 | pub const futex_waitv = extern struct { |
| 6236 | // Expected value at uaddr |
| 6237 | val: u64, |
| 6238 | /// User address to wait on. |
| 6239 | uaddr: u64, |
| 6240 | /// Flags for this waiter. |
| 6241 | flags: u32, |
| 6242 | /// Reserved memeber to preserve alignment. |
| 6243 | /// Should be 0. |
| 6244 | __reserved: u32, |
| 6245 | }; |
| 6246 | |
| 6103 | 6247 | pub const cache_stat_range = extern struct { |
| 6104 | 6248 | off: u64, |
| 6105 | 6249 | len: u64, |
| 6106 | 6250 | }; |
| 6107 | 6251 | |
| 6108 | 6252 | pub const cache_stat = extern struct { |
| 6253 | /// Number of cached pages. |
| 6109 | 6254 | cache: u64, |
| 6255 | /// Number of dirty pages. |
| 6110 | 6256 | dirty: u64, |
| 6257 | /// Number of pages marked for writeback. |
| 6111 | 6258 | writeback: u64, |
| 6259 | /// Number of pages evicted from the cache. |
| 6112 | 6260 | evicted: u64, |
| 6261 | /// Number of recently evicted pages. |
| 6262 | /// A page is recently evicted if its last eviction was recent enough that its |
| 6263 | /// reentry to the cache would indicate that it is actively being used by the |
| 6264 | /// system, and that there is memory pressure on the system. |
| 6113 | 6265 | recently_evicted: u64, |
| 6114 | 6266 | }; |
| 6267 | |
| 6268 | pub const SHADOW_STACK = struct { |
| 6269 | /// Set up a restore token in the shadow stack. |
| 6270 | pub const SET_TOKEN: u64 = 1 << 0; |
| 6271 | }; |