CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
multiwaiter.h
Go to the documentation of this file.
1// Copyright Microsoft and CHERIoT Contributors.
2// SPDX-License-Identifier: MIT
3
4#pragma once
5/**
6 * @file multiwaiter.h
7 *
8 * This file provides interfaces to the multi-waiter system. A multi-waiter
9 * object (or 'multiwaiter') is an object that allows a calling thread to
10 * suspend execution until one of a set of events has occurred.
11 *
12 * The CHERIoT multiwaiter system is designed to avoid allocation (or
13 * interaction with the allocator) on the fast path. The scheduler may not
14 * capture any of the arguments to the multiwaiter's wait call and expose them
15 * to other threads unless they are heap allocated. It must also be robust in
16 * the presence of malicious code that attempts to concurrently mutate any data
17 * structures while sleeping.
18 *
19 * The multiwaiter object is allocated with space to wait for *n* objects, up
20 * to a fixed limit. Each wait call provides a set of things to wait on and
21 * will suspend until either one occurs or a timeout is reached. On return,
22 * the caller-provided list will be updated. This list can be allocated on the
23 * stack: the scheduler does not need to hold a copy of it between calls or
24 * write to it from another thread.
25 *
26 * The multiwaiter should be used sparingly. In the worst case, it can add a
27 * linear-complexity overhead on all wake events. Memory overhead and code
28 * size have been the key optimisation goals for this design. Unlike systems
29 * such as `kqueue`, scalability has not been a priority in this design because
30 * expected number of waited objects is small and so is the number of threads.
31 */
32#include <compartment.h>
33#include <stdlib.h>
34#include <timeout.h>
35
36/**
37 * Structure describing a change to the set of managed event sources for an
38 * event waiter.
39 */
41{
42 /**
43 * A pointer to the event source. This is the futex that is monitored for
44 * the multiwaiter.
45 */
47 /**
48 * Event value. This field is modified during the wait
49 * call.
50 *
51 * This indicates the value to compare the futex word against. If they
52 * mismatch, the event fires immediately.
53 *
54 * On return, this is set to 1 if the futex is signaled, 0 otherwise.
55 */
56 uint32_t value;
57};
58
59/**
60 * Structure used for the MultiWaiter inside the scheduler.
61 */
62struct MultiWaiterInternal;
63
64/**
65 * Opaque type for multiwaiter objects. Callers will always see this as a
66 * sealed object.
67 */
68typedef CHERI_SEALED(struct MultiWaiterInternal *) MultiWaiter;
69
70/**
71 * Create a multiwaiter object. This is a stateful object that can wait on at
72 * most `maxItems` event sources.
73 */
74[[cheriot::interrupt_state(disabled)]] int __cheri_compartment("scheduler")
75 multiwaiter_create(TimeoutArgument timeout,
76 AllocatorCapability heapCapability,
77 MultiWaiter *ret,
78 size_t maxItems);
79
80/**
81 * Destroy a multiwaiter object.
82 */
83[[cheriot::interrupt_state(disabled)]] int __cheri_compartment("scheduler")
84 multiwaiter_delete(AllocatorCapability heapCapability, MultiWaiter mw);
85
86/**
87 * Wait for events. The first argument is the multiwaiter to wait on. New
88 * events can optionally be added by providing an array of `newEventsCount`
89 * elements as the `newEvents` argument.
90 *
91 * Return values:
92 *
93 * - On success, this function returns `0`.
94 * - If the arguments are invalid, this function returns `-EINVAL`.
95 * - If the timeout is reached without any events being triggered then this
96 * returns `-ETIMEDOUT`.
97 */
98[[cheriot::interrupt_state(disabled)]] int __cheri_compartment("scheduler")
99 multiwaiter_wait(TimeoutArgument timeout,
100 MultiWaiter waiter,
101 struct EventWaiterSource *events,
102 size_t newEventsCount);
int multiwaiter_wait(TimeoutArgument timeout, MultiWaiter waiter, struct EventWaiterSource *events, size_t newEventsCount)
Wait for events.
typedef CHERI_SEALED(struct MultiWaiterInternal *) MultiWaiter
Opaque type for multiwaiter objects.
int multiwaiter_delete(AllocatorCapability heapCapability, MultiWaiter mw)
Destroy a multiwaiter object.
int multiwaiter_create(TimeoutArgument timeout, AllocatorCapability heapCapability, MultiWaiter *ret, size_t maxItems)
Create a multiwaiter object.
Structure describing a change to the set of managed event sources for an event waiter.
Definition multiwaiter.h:41
void * eventSource
A pointer to the event source.
Definition multiwaiter.h:46
uint32_t value
Event value.
Definition multiwaiter.h:56
This file contains the types used for timeouts across scheduler APIs.