1 /*
2  * Copyright (c) 2008-2014 Travis Geiselbrecht
3  *
4  * Use of this source code is governed by a MIT-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/MIT
7  */
8 #pragma once
9 
10 #include <kernel/thread.h>
11 #include <lk/compiler.h>
12 #include <stdbool.h>
13 #include <sys/types.h>
14 
15 __BEGIN_CDECLS
16 
17 #define EVENT_MAGIC (0x65766E74)  // "evnt"
18 
19 typedef struct event {
20     int magic;
21     bool signaled;
22     uint flags;
23     wait_queue_t wait;
24 } event_t;
25 
26 #define EVENT_FLAG_AUTOUNSIGNAL 1
27 
28 #define EVENT_INITIAL_VALUE(e, initial, _flags) \
29 { \
30     .magic = EVENT_MAGIC, \
31     .signaled = initial, \
32     .flags = _flags, \
33     .wait = WAIT_QUEUE_INITIAL_VALUE((e).wait), \
34 }
35 
36 /* Rules for Events:
37  * - Events may be signaled from interrupt context *but* the reschedule
38  *   parameter must be false in that case.
39  * - Events may not be waited upon from interrupt context.
40  * - Events without FLAG_AUTOUNSIGNAL:
41  *   - Wake up any waiting threads when signaled.
42  *   - Continue to do so (no threads will wait) until unsignaled.
43  * - Events with FLAG_AUTOUNSIGNAL:
44  *   - If one or more threads are waiting when signaled, one thread will
45  *     be woken up and return.  The signaled state will not be set.
46  *   - If no threads are waiting when signaled, the Event will remain
47  *     in the signaled state until a thread attempts to wait (at which
48  *     time it will unsignal atomicly and return immediately) or
49  *     event_unsignal() is called.
50 */
51 
52 void event_init(event_t *, bool initial, uint flags);
53 void event_destroy(event_t *);
54 status_t event_wait_timeout(event_t *, lk_time_t); /* wait on the event with a timeout */
55 status_t event_signal(event_t *, bool reschedule);
56 status_t event_unsignal(event_t *);
57 
event_initialized(event_t * e)58 static inline bool event_initialized(event_t *e) {
59     return e->magic == EVENT_MAGIC;
60 }
61 
event_wait(event_t * e)62 static inline status_t event_wait(event_t *e) {
63     return event_wait_timeout(e, INFINITE_TIME);
64 }
65 
66 __END_CDECLS
67