| // Copyright Microsoft and CHERIoT Contributors. |
| // SPDX-License-Identifier: MIT |
| |
| #pragma once |
| #include <cdefs.h> |
| #include <stdint.h> |
| #include <timeout.h> |
| |
| enum [[clang::flag_enum]] FutexWaitFlags{ |
| /// No flags |
| FutexNone = 0, |
| /** |
| * This futex uses priority inheritance. The low 16 bits of the futex word |
| * are assumed to hold the thread ID of the thread that currently holds the |
| * lock. |
| */ |
| FutexPriorityInheritance = (1 << 0)}; |
| |
| /** |
| * Compare the value at `address` to `expected` and, if they match, sleep the |
| * thread until a wake event is sent with `futex_wake` or until this the thread |
| * has slept for `ticks` ticks. |
| * |
| * The value of `ticks` specifies the permitted timeout. See `timeout.h` for |
| * details. |
| * |
| * The `address` argument must permit loading four bytes of data after the |
| * address. |
| * |
| * The `flags` argument contains flags that may control the behaviour of the |
| * call. |
| * |
| * This returns: |
| * - 0 on success: either `*address` and `expected` differ or a wake is |
| * received. |
| * - `-EINVAL` if the arguments are invalid. |
| * - `-ETIMEOUT` if the timeout expires. |
| */ |
| [[cheri::interrupt_state(disabled)]] int __cheri_compartment("sched") |
| futex_timed_wait(Timeout *ticks, |
| const uint32_t *address, |
| uint32_t expected, |
| uint32_t flags __if_cxx(= FutexNone)); |
| |
| /** |
| * Compare the value at `address` to `expected` and, if they match, sleep the |
| * thread until a wake event is sent with `futex_wake`. |
| * |
| * The `address` argument must permit loading four bytes of data after the |
| * address. |
| * |
| * This returns 0 on success or `-EINVAL` if the arguments are invalid. |
| */ |
| __always_inline static int futex_wait(const uint32_t *address, |
| uint32_t expected) |
| { |
| Timeout t = {0, UnlimitedTimeout}; |
| return futex_timed_wait(&t, address, expected, FutexNone); |
| } |
| |
| /** |
| * Wakes up to `count` threads that are sleeping with `futex[_timed]_wait` on |
| * `address`. |
| * |
| * The `address` argument must permit storing four bytes of data after the |
| * address. This call does not store to the address but requiring store |
| * permission prevents a thread from waking up a futex that it cannot possibly |
| * have moved to a different state. |
| * |
| * The return value for a successful call is the number of threads that were |
| * woken. `-EINVAL` is returned for invalid arguments. |
| */ |
| [[cheri::interrupt_state(disabled)]] int __cheri_compartment("sched") |
| futex_wake(uint32_t *address, uint32_t count); |