| 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 | */ |
| 18 | enum event_type : uint8_t { |
| 19 | EVENT_NOTIFICATION, |
| 20 | EVENT_SYNCHRONIZATION, |
| 21 | }; |
| 22 | |
| 23 | struct event { |
| 24 | struct thread_wait_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 | |
| 36 | void event_init(struct event *e, enum event_type type, bool signaled); |
| 37 | |
| 38 | /* Return previous state */ |
| 39 | bool event_set(struct event *e); |
| 40 | bool event_set_full(struct event *e, enum thread_resume_reason reason, |
| 41 | void (*callback)(struct thread *)); |
| 42 | bool event_reset(struct event *e); |
| 43 | void event_clear(struct event *e); |
| 44 | |
| 45 | bool event_read_state(struct event *e); |
| 46 | |
| 47 | /* This function does not block. It consumes signal for a |
| 48 | * synchronization event on success */ |
| 49 | bool event_try_wait(struct event *e); |
| 50 | |
| 51 | /* thread_wait_prepare() with several objects */ |
| 52 | struct thread_wait_object event_wait_object(struct event *e); |
| 53 | |
| 54 | struct thread_wait_result |
| 55 | event_wait(struct event *e, enum thread_wait_type type, |
| 56 | enum thread_block_reason reason) TSA_MAY_SLEEP; |
| 57 | |
| 58 | struct thread_wait_result |
| 59 | event_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 | |