v2.0.0
async_context.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
63#ifndef _PICO_ASYNC_CONTEXT_H
64#define _PICO_ASYNC_CONTEXT_H
65
66#include "pico.h"
67#include "pico/time.h"
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
73enum {
74 ASYNC_CONTEXT_POLL = 1,
75 ASYNC_CONTEXT_THREADSAFE_BACKGROUND = 2,
76 ASYNC_CONTEXT_FREERTOS = 3,
77};
78
79typedef struct async_context async_context_t;
80
90 typedef struct async_work_on_timeout {
94 struct async_work_on_timeout *next;
103 void (*do_work)(async_context_t *context, struct async_work_on_timeout *timeout);
108 absolute_time_t next_time;
112 void *user_data;
113} async_at_time_worker_t;
114
125 typedef struct async_when_pending_worker {
129 struct async_when_pending_worker *next;
136 void (*do_work)(async_context_t *context, struct async_when_pending_worker *worker);
140 bool work_pending;
144 void *user_data;
145} async_when_pending_worker_t;
146
147#define ASYNC_CONTEXT_FLAG_CALLBACK_FROM_NON_IRQ 0x1
148#define ASYNC_CONTEXT_FLAG_CALLBACK_FROM_IRQ 0x2
149#define ASYNC_CONTEXT_FLAG_POLLED 0x4
150
155 typedef struct async_context_type {
156 uint16_t type;
157 // see wrapper functions for documentation
158 void (*acquire_lock_blocking)(async_context_t *self);
159 void (*release_lock)(async_context_t *self);
160 void (*lock_check)(async_context_t *self);
161 uint32_t (*execute_sync)(async_context_t *context, uint32_t (*func)(void *param), void *param);
162 bool (*add_at_time_worker)(async_context_t *self, async_at_time_worker_t *worker);
163 bool (*remove_at_time_worker)(async_context_t *self, async_at_time_worker_t *worker);
164 bool (*add_when_pending_worker)(async_context_t *self, async_when_pending_worker_t *worker);
165 bool (*remove_when_pending_worker)(async_context_t *self, async_when_pending_worker_t *worker);
166 void (*set_work_pending)(async_context_t *self, async_when_pending_worker_t *worker);
167 void (*poll)(async_context_t *self); // may be NULL
168 void (*wait_until)(async_context_t *self, absolute_time_t until);
169 void (*wait_for_work_until)(async_context_t *self, absolute_time_t until);
170 void (*deinit)(async_context_t *self);
171} async_context_type_t;
172
179 struct async_context {
180 const async_context_type_t *type;
181 async_when_pending_worker_t *when_pending_list;
182 async_at_time_worker_t *at_time_list;
183 absolute_time_t next_time;
184 uint16_t flags;
185 uint8_t core_num;
186};
187
206 static inline void async_context_acquire_lock_blocking(async_context_t *context) {
207 context->type->acquire_lock_blocking(context);
208}
209
225 static inline void async_context_release_lock(async_context_t *context) {
226 context->type->release_lock(context);
227}
228
236 static inline void async_context_lock_check(async_context_t *context) {
237 context->type->lock_check(context);
238}
239
255 static inline uint32_t async_context_execute_sync(async_context_t *context, uint32_t (*func)(void *param), void *param) {
256 return context->type->execute_sync(context, func, param);
257}
258
274 static inline bool async_context_add_at_time_worker(async_context_t *context, async_at_time_worker_t *worker) {
275 return context->type->add_at_time_worker(context, worker);
276}
277
294 static inline bool async_context_add_at_time_worker_at(async_context_t *context, async_at_time_worker_t *worker, absolute_time_t at) {
295 worker->next_time = at;
296 return context->type->add_at_time_worker(context, worker);
297}
298
315 static inline bool async_context_add_at_time_worker_in_ms(async_context_t *context, async_at_time_worker_t *worker, uint32_t ms) {
316 worker->next_time = make_timeout_time_ms(ms);
317 return context->type->add_at_time_worker(context, worker);
318}
319
331 static inline bool async_context_remove_at_time_worker(async_context_t *context, async_at_time_worker_t *worker) {
332 return context->type->remove_at_time_worker(context, worker);
333}
334
351 static inline bool async_context_add_when_pending_worker(async_context_t *context, async_when_pending_worker_t *worker) {
352 return context->type->add_when_pending_worker(context, worker);
353}
354
366 static inline bool async_context_remove_when_pending_worker(async_context_t *context, async_when_pending_worker_t *worker) {
367 return context->type->remove_when_pending_worker(context, worker);
368}
369
381 static inline void async_context_set_work_pending(async_context_t *context, async_when_pending_worker_t *worker) {
382 context->type->set_work_pending(context, worker);
383}
384
396 static inline void async_context_poll(async_context_t *context) {
397 if (context->type->poll) context->type->poll(context);
398}
399
410 static inline void async_context_wait_until(async_context_t *context, absolute_time_t until) {
411 context->type->wait_until(context, until);
412}
413
423 static inline void async_context_wait_for_work_until(async_context_t *context, absolute_time_t until) {
424 context->type->wait_for_work_until(context, until);
425}
426
436 static inline void async_context_wait_for_work_ms(async_context_t *context, uint32_t ms) {
437 async_context_wait_for_work_until(context, make_timeout_time_ms(ms));
438}
439
447 static inline uint async_context_core_num(const async_context_t *context) {
448 return context->core_num;
449}
450
463 static inline void async_context_deinit(async_context_t *context) {
464 context->type->deinit(context);
465}
466
467#ifdef __cplusplus
468}
469#endif
470
471#endif
time.h
async_context_lock_check
static void async_context_lock_check(async_context_t *context)
Assert if the caller does not own the lock for the async_context.
Definition: async_context.h:236
async_context_set_work_pending
static void async_context_set_work_pending(async_context_t *context, async_when_pending_worker_t *worker)
Mark a "when pending" worker as having work pending.
Definition: async_context.h:381
async_context_type_t
struct async_context_type async_context_type_t
Implementation of an async_context type, providing methods common to that type.
async_context_acquire_lock_blocking
static void async_context_acquire_lock_blocking(async_context_t *context)
Acquire the async_context lock.
Definition: async_context.h:206
async_context_remove_at_time_worker
static bool async_context_remove_at_time_worker(async_context_t *context, async_at_time_worker_t *worker)
Remove an "at time" worker from a context.
Definition: async_context.h:331
async_context_core_num
static uint async_context_core_num(const async_context_t *context)
Return the processor core this async_context belongs to.
Definition: async_context.h:447
async_context_wait_for_work_until
static void async_context_wait_for_work_until(async_context_t *context, absolute_time_t until)
Block until work needs to be done or the specified time has been reached.
Definition: async_context.h:423
async_context_deinit
static void async_context_deinit(async_context_t *context)
End async_context processing, and free any resources.
Definition: async_context.h:463
async_context_remove_when_pending_worker
static bool async_context_remove_when_pending_worker(async_context_t *context, async_when_pending_worker_t *worker)
Remove a "when pending" worker from a context.
Definition: async_context.h:366
async_at_time_worker_t
struct async_work_on_timeout async_at_time_worker_t
A "timeout" instance used by an async_context.
async_context_add_at_time_worker_at
static bool async_context_add_at_time_worker_at(async_context_t *context, async_at_time_worker_t *worker, absolute_time_t at)
Add an "at time" worker to a context.
Definition: async_context.h:294
async_when_pending_worker_t
struct async_when_pending_worker async_when_pending_worker_t
A "worker" instance used by an async_context.
async_context_add_when_pending_worker
static bool async_context_add_when_pending_worker(async_context_t *context, async_when_pending_worker_t *worker)
Add a "when pending" worker to a context.
Definition: async_context.h:351
async_context_execute_sync
static uint32_t async_context_execute_sync(async_context_t *context, uint32_t(*func)(void *param), void *param)
Execute work synchronously on the core the async_context belongs to.
Definition: async_context.h:255
async_context_wait_for_work_ms
static void async_context_wait_for_work_ms(async_context_t *context, uint32_t ms)
Block until work needs to be done or the specified number of milliseconds have passed.
Definition: async_context.h:436
async_context_wait_until
static void async_context_wait_until(async_context_t *context, absolute_time_t until)
sleep until the specified time in an async_context callback safe way
Definition: async_context.h:410
async_context_add_at_time_worker
static bool async_context_add_at_time_worker(async_context_t *context, async_at_time_worker_t *worker)
Add an "at time" worker to a context.
Definition: async_context.h:274
async_context_release_lock
static void async_context_release_lock(async_context_t *context)
Release the async_context lock.
Definition: async_context.h:225
async_context_add_at_time_worker_in_ms
static bool async_context_add_at_time_worker_in_ms(async_context_t *context, async_at_time_worker_t *worker, uint32_t ms)
Add an "at time" worker to a context.
Definition: async_context.h:315
async_context_poll
static void async_context_poll(async_context_t *context)
Perform any pending work for polling style async_context.
Definition: async_context.h:396
absolute_time_t
uint64_t absolute_time_t
An opaque 64 bit timestamp in microseconds.
Definition: types.h:43
make_timeout_time_ms
static absolute_time_t make_timeout_time_ms(uint32_t ms)
Convenience method to get the timestamp a number of milliseconds from the current time.
Definition: time.h:146
pico.h
async_context_type
Implementation of an async_context type, providing methods common to that type.
Definition: async_context.h:155
async_context
Base structure type of all async_contexts. For details about its use, see pico_async_context.
Definition: async_context.h:179
async_when_pending_worker
A "worker" instance used by an async_context.
Definition: async_context.h:125
async_when_pending_worker::do_work
void(* do_work)(async_context_t *context, struct async_when_pending_worker *worker)
Called by the async_context when the worker has been marked as having "work pending".
Definition: async_context.h:136
async_when_pending_worker::next
struct async_when_pending_worker * next
private link list pointer
Definition: async_context.h:129
async_when_pending_worker::work_pending
bool work_pending
True if the worker need do_work called.
Definition: async_context.h:140
async_when_pending_worker::user_data
void * user_data
User data associated with the worker instance.
Definition: async_context.h:144
async_work_on_timeout
A "timeout" instance used by an async_context.
Definition: async_context.h:90
async_work_on_timeout::do_work
void(* do_work)(async_context_t *context, struct async_work_on_timeout *timeout)
Method called when the timeout is reached; may not be NULL.
Definition: async_context.h:103
async_work_on_timeout::next
struct async_work_on_timeout * next
private link list pointer
Definition: async_context.h:94
async_work_on_timeout::next_time
absolute_time_t next_time
The next timeout time; this should only be modified during the above methods or via async_context met...
Definition: async_context.h:108
async_work_on_timeout::user_data
void * user_data
User data associated with the timeout instance.
Definition: async_context.h:112