event.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 Inria
3  * 2017 Kaspar Schleiser <kaspar@schleiser.de>
4  * 2018-2019 Freie Universität Berlin
5  *
6  * This file is subject to the terms and conditions of the GNU Lesser
7  * General Public License v2.1. See the file LICENSE in the top level
8  * directory for more details.
9  */
10 
96 #ifndef EVENT_H
97 #define EVENT_H
98 
99 #include <stdint.h>
100 #include <string.h>
101 
102 #include "assert.h"
103 #include "clist.h"
104 #include "irq.h"
105 #include "thread.h"
106 #include "thread_flags.h"
107 
108 #ifdef __cplusplus
109 extern "C" {
110 #endif
111 
112 #ifndef THREAD_FLAG_EVENT
113 
116 #define THREAD_FLAG_EVENT (0x1)
117 #endif
118 
122 #define EVENT_QUEUE_INIT { .waiter = thread_get_active() }
123 
127 #define EVENT_QUEUE_INIT_DETACHED { .waiter = NULL }
128 
132 typedef struct event event_t;
133 
137 typedef void (*event_handler_t)(event_t *);
138 
142 struct event {
145 };
146 
150 typedef struct {
153 } event_queue_t;
154 
155 
164 static inline void event_queues_init(event_queue_t *queues,
165  size_t n_queues)
166 {
167  assert(queues && n_queues);
168  thread_t *me = thread_get_active();
169  for (size_t i = 0; i < n_queues; i++) {
170  memset(&queues[i], '\0', sizeof(queues[0]));
171  queues[i].waiter = me;
172  }
173 }
174 
182 static inline void event_queue_init(event_queue_t *queue)
183 {
184  event_queues_init(queue, 1);
185 }
186 
193 static inline void event_queues_init_detached(event_queue_t *queues,
194  size_t n_queues)
195 {
196  assert(queues);
197  for (size_t i = 0; i < n_queues; i++) {
198  memset(&queues[i], '\0', sizeof(queues[0]));
199  }
200 }
201 
207 static inline void event_queue_init_detached(event_queue_t *queue)
208 {
209  event_queues_init_detached(queue, 1);
210 }
211 
223 static inline void event_queues_claim(event_queue_t *queues, size_t n_queues)
224 {
225  assert(queues);
226  thread_t *me = thread_get_active();
227  for (size_t i = 0; i < n_queues; i++) {
228  assert(queues[i].waiter == NULL);
229  queues[i].waiter = me;
230  }
231 }
232 
243 static inline void event_queue_claim(event_queue_t *queue)
244 {
245  event_queues_claim(queue, 1);
246 }
247 
259 void event_post(event_queue_t *queue, event_t *event);
260 
271 void event_cancel(event_queue_t *queue, event_t *event);
272 
285 
313 event_t *event_wait_multi(event_queue_t *queues, size_t n_queues);
314 
329 static inline event_t *event_wait(event_queue_t *queue)
330 {
331  return event_wait_multi(queue, 1);
332 }
333 
334 #if defined(MODULE_XTIMER) || defined(DOXYGEN)
335 
344 event_t *event_wait_timeout(event_queue_t *queue, uint32_t timeout);
345 
355 event_t *event_wait_timeout64(event_queue_t *queue, uint64_t timeout);
356 #endif
357 
379 static inline void event_loop_multi(event_queue_t *queues, size_t n_queues)
380 {
381  event_t *event;
382 
383  while ((event = event_wait_multi(queues, n_queues))) {
384  event->handler(event);
385  }
386 }
387 
404 static inline void event_loop(event_queue_t *queue)
405 {
406  event_loop_multi(queue, 1);
407 }
408 
409 #ifdef __cplusplus
410 }
411 #endif
412 #endif /* EVENT_H */
413 
assert
#define assert(cond)
abort the program if assertion is false
Definition: assert.h:104
event::list_node
clist_node_t list_node
event queue list entry
Definition: event.h:143
event_queue_init
static void event_queue_init(event_queue_t *queue)
Initialize an event queue.
Definition: event.h:182
event_cancel
void event_cancel(event_queue_t *queue, event_t *event)
Cancel a queued event.
assert.h
POSIX.1-2008 compliant version of the assert macro.
event
event structure
Definition: event.h:142
event_loop
static void event_loop(event_queue_t *queue)
Simple event loop.
Definition: event.h:404
event_queue_t
event queue structure
Definition: event.h:150
event_queues_init
static void event_queues_init(event_queue_t *queues, size_t n_queues)
Initialize an array of event queues.
Definition: event.h:164
event_wait_timeout
event_t * event_wait_timeout(event_queue_t *queue, uint32_t timeout)
Get next event from event queue, blocking until timeout expires.
thread_get_active
static thread_t * thread_get_active(void)
Returns a pointer to the Thread Control Block of the currently running thread.
Definition: thread.h:486
event_queues_init_detached
static void event_queues_init_detached(event_queue_t *queues, size_t n_queues)
Initialize an array of event queues not binding it to a thread.
Definition: event.h:193
_thread
thread_t holds thread's context data.
Definition: thread.h:154
event_queue_init_detached
static void event_queue_init_detached(event_queue_t *queue)
Initialize an event queue not binding it to a thread.
Definition: event.h:207
clist.h
Circular linked list.
event_wait_multi
event_t * event_wait_multi(event_queue_t *queues, size_t n_queues)
Get next event from the given event queues, blocking.
event_post
void event_post(event_queue_t *queue, event_t *event)
Queue an event.
irq.h
IRQ driver interface.
list_node
List node structure.
Definition: list.h:40
event_queues_claim
static void event_queues_claim(event_queue_t *queues, size_t n_queues)
Bind an array of event queues to the calling thread.
Definition: event.h:223
event_wait
static event_t * event_wait(event_queue_t *queue)
Get next event from event queue, blocking.
Definition: event.h:329
event_queue_t::event_list
clist_node_t event_list
list of queued events
Definition: event.h:151
event_queue_t::waiter
thread_t * waiter
thread ownning event queue
Definition: event.h:152
thread_flags.h
Thread Flags API.
event::handler
event_handler_t handler
pointer to event handler function
Definition: event.h:144
event_get
event_t * event_get(event_queue_t *queue)
Get next event from event queue, non-blocking.
event_handler_t
void(* event_handler_t)(event_t *)
event handler type definition
Definition: event.h:137
event_queue_claim
static void event_queue_claim(event_queue_t *queue)
Bind an event queue to the calling thread.
Definition: event.h:243
event_loop_multi
static void event_loop_multi(event_queue_t *queues, size_t n_queues)
Simple event loop with multiple queues.
Definition: event.h:379
event_wait_timeout64
event_t * event_wait_timeout64(event_queue_t *queue, uint64_t timeout)
Get next event from event queue, blocking until timeout expires.