Loading...
Searching...
No Matches
event.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2017 Inria
3 * SPDX-FileCopyrightText: 2017 Kaspar Schleiser <kaspar@schleiser.de>
4 * SPDX-FileCopyrightText: 2018-2019 Freie Universität Berlin
5 * SPDX-License-Identifier: LGPL-2.1-only
6 */
7
8#pragma once
9
94
95#include <stdio.h>
96#include <stdint.h>
97#include <stdbool.h>
98#include <string.h>
99
100#include "assert.h"
101#include "clist.h"
102#include "irq.h"
103#include "thread.h"
104#include "thread_flags.h"
105#include "ptrtag.h"
106#include "ztimer.h"
107
108#ifdef __cplusplus
109extern "C" {
110#endif
111
112#ifndef THREAD_FLAG_EVENT
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
132typedef struct event event_t;
133
137typedef void (*event_handler_t)(event_t *);
138
146
154
163static inline void event_queues_init(event_queue_t *queues,
164 size_t n_queues)
165{
166 assert(queues && n_queues);
168 for (size_t i = 0; i < n_queues; i++) {
169 memset(&queues[i], '\0', sizeof(queues[0]));
170 queues[i].waiter = me;
171 }
172}
173
181static inline void event_queue_init(event_queue_t *queue)
182{
183 event_queues_init(queue, 1);
184}
185
192static inline void event_queues_init_detached(event_queue_t *queues,
193 size_t n_queues)
194{
195 assert(queues);
196 for (size_t i = 0; i < n_queues; i++) {
197 memset(&queues[i], '\0', sizeof(queues[0]));
198 }
199}
200
206static inline void event_queue_init_detached(event_queue_t *queue)
207{
209}
210
222static inline void event_queues_claim(event_queue_t *queues, size_t n_queues)
223{
224 assert(queues);
226 for (size_t i = 0; i < n_queues; i++) {
227 assert(queues[i].waiter == NULL);
228 queues[i].waiter = me;
229 }
230}
231
242static inline void event_queue_claim(event_queue_t *queue)
243{
244 event_queues_claim(queue, 1);
245}
246
261
273
283bool event_is_queued(const event_queue_t *queue, const event_t *event);
284
297
329event_t *event_wait_multi(event_queue_t *queues, size_t n_queues);
330
348static inline event_t *event_wait(event_queue_t *queue)
349{
350 return event_wait_multi(queue, 1);
351}
352
353#if IS_USED(MODULE_XTIMER) || defined(DOXYGEN)
366event_t *event_wait_timeout(event_queue_t *queue, uint32_t timeout);
367
380event_t *event_wait_timeout64(event_queue_t *queue, uint64_t timeout);
381#endif
382
383#if IS_USED(MODULE_ZTIMER) || defined(DOXYGEN)
402 ztimer_clock_t *clock, uint32_t timeout);
403#endif
404
433static inline void event_loop_multi(event_queue_t *queues, size_t n_queues)
434{
435 while (1) {
436 event_t *event = event_wait_multi(queues, n_queues);
437 if (IS_USED(MODULE_EVENT_LOOP_DEBUG)) {
438 uint32_t now;
440
442 if (!IS_USED(MODULE_EVENT_CALLBACK) ||
444 printf("event: executing %p->%p\n",
445 (void *)event, (void *)(uintptr_t)event->handler);
446 }
447 now = ztimer_now(ZTIMER_USEC);
448
449 event->handler(event);
450
451 printf("event: %p took %" PRIu32 " µs\n",
452 (void *)event, ztimer_now(ZTIMER_USEC) - now);
454 }
455 else {
456 event->handler(event);
457 }
458 }
459}
460
483static inline void event_loop(event_queue_t *queue)
484{
485 event_loop_multi(queue, 1);
486}
487
508
509#ifdef __cplusplus
510}
511#endif
POSIX.1-2008 compliant version of the assert macro.
#define assert(cond)
abort the program if assertion is false
Definition assert.h:143
void _event_callback_handler(event_t *event)
event callback handler function (used internally)
Circular linked list.
list_node_t clist_node_t
List node structure.
Definition clist.h:104
struct _thread thread_t
forward declaration for thread_t, defined in thread.h
Definition sched.h:150
static thread_t * thread_get_active(void)
Returns a pointer to the Thread Control Block of the currently running thread.
Definition thread.h:450
#define printf(...)
A wrapper for the printf() function that passes arguments through unmodified, but fails to compile if...
Definition stdio.h:57
static void event_loop_multi(event_queue_t *queues, size_t n_queues)
Simple event loop with multiple queues.
Definition event.h:433
void event_post(event_queue_t *queue, event_t *event)
Queue an event.
static event_t * event_wait(event_queue_t *queue)
Get next event from event queue, blocking.
Definition event.h:348
static void event_loop(event_queue_t *queue)
Simple event loop.
Definition event.h:483
event_t * event_wait_timeout_ztimer(event_queue_t *queue, ztimer_clock_t *clock, uint32_t timeout)
Get next event from event queue, blocking until timeout expires.
static void event_queue_init(event_queue_t *queue)
Initialize an event queue.
Definition event.h:181
void(* event_handler_t)(event_t *)
event handler type definition
Definition event.h:137
void event_cancel(event_queue_t *queue, event_t *event)
Cancel a queued event.
struct PTRTAG event_queue_t
event queue structure
static void event_queue_init_detached(event_queue_t *queue)
Initialize an event queue not binding it to a thread.
Definition event.h:206
static void event_queue_claim(event_queue_t *queue)
Bind an event queue to the calling thread.
Definition event.h:242
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:222
void event_sync(event_queue_t *queue)
Synchronize with the last event on the queue.
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:192
event_t * event_wait_multi(event_queue_t *queues, size_t n_queues)
Get next event from the given event queues, blocking.
event_t * event_wait_timeout(event_queue_t *queue, uint32_t timeout)
Get next event from event queue, blocking until timeout expires.
static void event_queues_init(event_queue_t *queues, size_t n_queues)
Initialize an array of event queues.
Definition event.h:163
struct event event_t
event structure forward declaration
Definition event.h:132
event_t * event_get(event_queue_t *queue)
Get next event from event queue, non-blocking.
bool event_is_queued(const event_queue_t *queue, const event_t *event)
Check if an event is already queued.
event_t * event_wait_timeout64(event_queue_t *queue, uint64_t timeout)
Get next event from event queue, blocking until timeout expires.
bool ztimer_release(ztimer_clock_t *clock)
Release a clock.
struct ztimer_clock ztimer_clock_t
ztimer_clock_t forward declaration
Definition ztimer.h:287
ztimer_clock_t *const ZTIMER_USEC
Default ztimer microsecond clock.
bool ztimer_acquire(ztimer_clock_t *clock)
Acquire a clock.
static ztimer_now_t ztimer_now(ztimer_clock_t *clock)
Get the current time from a clock.
Definition ztimer.h:680
IRQ driver interface.
#define IS_USED(module)
Checks whether a module is being used or not.
Definition modules.h:67
Pointer Tagging Helpers.
event queue structure
Definition event.h:150
thread_t * waiter
thread owning event queue
Definition event.h:152
clist_node_t event_list
list of queued events
Definition event.h:151
event structure
Definition event.h:142
event_handler_t handler
pointer to event handler function
Definition event.h:144
clist_node_t list_node
event queue list entry
Definition event.h:143
Thread Flags API.
ztimer API