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
70 extern "C" {
71 #endif
72 
73 enum {
74  ASYNC_CONTEXT_POLL = 1,
75  ASYNC_CONTEXT_THREADSAFE_BACKGROUND = 2,
76  ASYNC_CONTEXT_FREERTOS = 3,
77 };
78 
79 typedef struct async_context async_context_t;
80 
90 typedef struct async_work_on_timeout {
103  void (*do_work)(async_context_t *context, struct async_work_on_timeout *timeout);
112  void *user_data;
114 
136  void (*do_work)(async_context_t *context, struct async_when_pending_worker *worker);
144  void *user_data;
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);
172 
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 
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 
275  return context->type->add_at_time_worker(context, worker);
276 }
277 
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 
332  return context->type->remove_at_time_worker(context, worker);
333 }
334 
352  return context->type->add_when_pending_worker(context, worker);
353 }
354 
367  return context->type->remove_when_pending_worker(context, worker);
368 }
369 
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 
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) {
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
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
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
struct async_context_type async_context_type_t
Implementation of an async_context type, providing methods common to that type.
static void async_context_acquire_lock_blocking(async_context_t *context)
Acquire the async_context lock.
Definition: async_context.h:206
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
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
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
static void async_context_deinit(async_context_t *context)
End async_context processing, and free any resources.
Definition: async_context.h:463
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
struct async_work_on_timeout async_at_time_worker_t
A "timeout" instance used by an async_context.
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
struct async_when_pending_worker async_when_pending_worker_t
A "worker" instance used by an async_context.
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
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
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
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
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
static void async_context_release_lock(async_context_t *context)
Release the async_context lock.
Definition: async_context.h:225
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
static void async_context_poll(async_context_t *context)
Perform any pending work for polling style async_context.
Definition: async_context.h:396
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:141
Definition: types.h:33
Implementation of an async_context type, providing methods common to that type.
Definition: async_context.h:155
Base structure type of all async_contexts. For details about its use, see pico_async_context.
Definition: async_context.h:179
A "worker" instance used by an async_context.
Definition: async_context.h:125
void(* do_work)(async_context_t *context, struct async_when_pending_worker *worker)
Definition: async_context.h:136
struct async_when_pending_worker * next
Definition: async_context.h:129
bool work_pending
Definition: async_context.h:140
void * user_data
Definition: async_context.h:144
A "timeout" instance used by an async_context.
Definition: async_context.h:90
void(* do_work)(async_context_t *context, struct async_work_on_timeout *timeout)
Definition: async_context.h:103
struct async_work_on_timeout * next
Definition: async_context.h:94
absolute_time_t next_time
Definition: async_context.h:108
void * user_data
Definition: async_context.h:112