CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
event.h
Go to the documentation of this file.
1#pragma once
2/**
3 * \file
4 * \brief Event-group APIs
5 *
6 * This file contains the interface for an event-group API, implemented in the
7 * `event_group` library, which provides a mechanism for wait for one or more
8 * events from a set of 24 to occur.
9 *
10 * This API is provided to ease porting from FreeRTOS. The event group
11 * abstraction is not a good design and is difficult to use correctly. It is
12 * not recommended for new code. CHERIoT RTOS provides a futex as the
13 * low-level primitive on which event groups are implemented. For new code,
14 * you will almost certainly be able to build a cleaner and less error-prone
15 * abstraction on top of futexes directly.
16 */
17
18#include <compartment-macros.h>
19#include <stdint.h>
20#include <stdlib.h>
21#include <timeout.h>
22
23struct EventGroup;
24
25/**
26 * Create a new event group, allocated using `heapCapability`. The event group
27 * is returned via `outGroup`.
28 *
29 * This returns zero on success. Otherwise it returns a negative error code.
30 * If the timeout expires then this returns `-ETIMEDOUT`, if memory cannot be
31 * allocated it returns `-ENOMEM`.
32 */
33int __cheri_libcall eventgroup_create(TimeoutArgument timeout,
34 AllocatorCapability heapCapability,
35 struct EventGroup **outGroup);
36
37/**
38 * Wait for events in an event group. The `bitsWanted` argument must contain
39 * at least one bit set in the low 24 bits (and none in the high bits). This
40 * indicates the specific events to wait for. If `waitForAll` is true then all
41 * of the bits in `bitsWanted` must be set in the event group before this
42 * returns. If `waitForAll` is false then any of the bits in `bitsWanted`
43 * being set in the event group will cause this to return.
44 *
45 * If this returns zero then `outBits` will contain the bits that were set at
46 * the time that the condition became true. If this returns `-ETIMEDOUT` then
47 * `outBits` will contain the bits that were set at the time that the timeout
48 * expired.
49 *
50 * Note: `waitForAll` requires all bits to be set *at the same time*. This
51 * makes it trivial to introduce race conditions if used with multiple waiters
52 * and `clearOnExit`, or if different threads clear different bits in the
53 * waited set.
54 *
55 * If `clearOnExit` is true and this returns successfully then the bits in
56 * `bitsWanted` will be cleared in the event group before this returns.
57 */
58int __cheri_libcall eventgroup_wait(TimeoutArgument timeout,
59 struct EventGroup *group,
60 uint32_t *outBits,
61 uint32_t bitsWanted,
62 _Bool waitForAll,
63 _Bool clearOnExit);
64
65/**
66 * Set one or more bits in an event group. The `bitsToSet` argument contains
67 * the bits to set. Any thread waiting with `eventgroup_wait` will be woken if
68 * the bits that it is waiting for are set.
69 *
70 * This returns zero on success. If the timeout expires before this returns
71 * then it returns `-ETIMEDOUT`.
72 *
73 * Independent of success or failure, `outBits` will be used to return the set
74 * of currently set bits in this event group.
75 */
76int __cheri_libcall eventgroup_set(TimeoutArgument timeout,
77 struct EventGroup *group,
78 uint32_t *outBits,
79 uint32_t bitsToSet);
80
81/**
82 * Clear one or more bits in an event group. The `bitsToClear` argument
83 * contains the set of bits to clear. This does not wake any threads.
84 *
85 * This returns zero on success. If the timeout expires before this returns
86 * then it returns `-ETIMEDOUT`.
87 *
88 * Independent of success or failure, `outBits` will be used to return the set
89 * of currently set bits in this event group.
90 */
91int __cheri_libcall eventgroup_clear(TimeoutArgument timeout,
92 struct EventGroup *group,
93 uint32_t *outBits,
94 uint32_t bitsToClear);
95
96/**
97 * Returns the current value of the event bits via `outBits`. Returns 0 on
98 * success (there is currently no way in which this call can fail).
99 *
100 * This API is inherently racy. Any arbitrary set of bits may be set or
101 * cleared in between this call reading from the event group and returning.
102 */
103int __cheri_libcall eventgroup_get(struct EventGroup *group, uint32_t *outBits);
104
105/**
106 * Destroy an event group. This forces all waiters to wake and frees the
107 * underlying memory.
108 */
109int __cheri_libcall eventgroup_destroy(AllocatorCapability heapCapability,
110 struct EventGroup *group);
111
112/**
113 * Destroy an event group without tacking the lock.
114 *
115 * This API is inherently racy. Its main purpose is to cleanup the event group
116 * in an error handler context, when taking lock may be impossible.
117 */
118int __cheri_libcall eventgroup_destroy_force(AllocatorCapability heapCapability,
119 struct EventGroup *group);
Macros for interacting with the compartmentalisation model in CHERIoT.
int __cheri_libcall eventgroup_get(struct EventGroup *group, uint32_t *outBits)
Returns the current value of the event bits via outBits.
int __cheri_libcall eventgroup_wait(TimeoutArgument timeout, struct EventGroup *group, uint32_t *outBits, uint32_t bitsWanted, _Bool waitForAll, _Bool clearOnExit)
Wait for events in an event group.
int __cheri_libcall eventgroup_clear(TimeoutArgument timeout, struct EventGroup *group, uint32_t *outBits, uint32_t bitsToClear)
Clear one or more bits in an event group.
int __cheri_libcall eventgroup_destroy_force(AllocatorCapability heapCapability, struct EventGroup *group)
Destroy an event group without tacking the lock.
int __cheri_libcall eventgroup_create(TimeoutArgument timeout, AllocatorCapability heapCapability, struct EventGroup **outGroup)
Create a new event group, allocated using heapCapability.
int __cheri_libcall eventgroup_destroy(AllocatorCapability heapCapability, struct EventGroup *group)
Destroy an event group.
int __cheri_libcall eventgroup_set(TimeoutArgument timeout, struct EventGroup *group, uint32_t *outBits, uint32_t bitsToSet)
Set one or more bits in an event group.
This file contains the types used for timeouts across scheduler APIs.