blob: 482919a8641b76063a2cd7ba94025f0be07ec69f [file] [log] [blame] [edit]
// 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);