1/* @title: Events */
2#pragma once
3#include <atomic.h>
4#include <thread/wait.h>
5#include <time/time.h>
6#include <tsa.h>
7
8/* This event model is somewhat similar to KEVENT in Windows. Notification
9 * events satisfy every single wait and remain "latched" until they get
10 * explicitly cleared. Synchronization events (auto resets) satisfy
11 * one wait and clear themselves.
12 *
13 * If waiters exist, the signal is handed directly and the event doesn't
14 * get perceived as signalled.
15 *
16 * Event may be freed ONLY on event_wait returns
17 */
18enum event_type : uint8_t {
19 EVENT_NOTIFICATION,
20 EVENT_SYNCHRONIZATION,
21};
22
23struct event {
24 struct thread_wait_header header;
25 enum event_type type;
26
27 /* Set under header->lock, but clears can be lockless */
28 atomic_bool signaled;
29};
30
31#define EVENT_INIT(name_, type_, signaled_) \
32 {.header = THREAD_WAIT_HEADER_INIT((name_).header), \
33 .type = (type_), \
34 .signaled = (signaled_)}
35
36void event_init(struct event *e, enum event_type type, bool signaled);
37
38/* Return previous state */
39bool event_set(struct event *e);
40bool event_set_full(struct event *e, enum thread_resume_reason reason,
41 void (*callback)(struct thread *));
42bool event_reset(struct event *e);
43void event_clear(struct event *e);
44
45bool event_read_state(struct event *e);
46
47/* This function does not block. It consumes signal for a
48 * synchronization event on success */
49bool event_try_wait(struct event *e);
50
51/* thread_wait_prepare() with several objects */
52struct thread_wait_object event_wait_object(struct event *e);
53
54struct thread_wait_result
55event_wait(struct event *e, enum thread_wait_type type,
56 enum thread_block_reason reason) TSA_MAY_SLEEP;
57
58struct thread_wait_result
59event_wait_timeout(struct event *e, enum thread_wait_type type,
60 enum thread_block_reason reason,
61 time_ms_t timeout_ms) TSA_MAY_SLEEP;
62