An async_context provides a logically single-threaded context for performing work, and responding to asynchronous events. Thus an async_context instance is suitable for servicing third-party libraries that are not re-entrant.
More...
|
static void | async_context_acquire_lock_blocking (async_context_t *context) |
| Acquire the async_context lock. More...
|
|
static void | async_context_release_lock (async_context_t *context) |
| Release the async_context lock. More...
|
|
static void | async_context_lock_check (async_context_t *context) |
| Assert if the caller does not own the lock for the async_context. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
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. More...
|
|
static void | async_context_poll (async_context_t *context) |
| Perform any pending work for polling style async_context. More...
|
|
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 More...
|
|
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. More...
|
|
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. More...
|
|
static uint | async_context_core_num (const async_context_t *context) |
| Return the processor core this async_context belongs to. More...
|
|
static void | async_context_deinit (async_context_t *context) |
| End async_context processing, and free any resources. More...
|
|
An async_context provides a logically single-threaded context for performing work, and responding to asynchronous events. Thus an async_context instance is suitable for servicing third-party libraries that are not re-entrant.
The "context" in async_context refers to the fact that when calling workers or timeouts within the async_context various pre-conditions hold:
-
That there is a single logical thread of execution; i.e. that the context does not call any worker functions concurrently.
-
That the context always calls workers from the same processor core, as most uses of async_context rely on interaction with IRQs which are themselves core-specific.
THe async_context provides two mechanisms for asynchronous work:
Note: "when pending" workers with work pending are executed before "at time" workers.
The async_context provides locking mechanisms, see async_context_acquire_lock_blocking, async_context_release_lock and async_context_check_lock which can be used by external code to ensure execution of external code does not happen concurrently with worker code. Locked code runs on the calling core, however async_context_execute_sync is provided to synchronously run a function from the core of the async_context.
The SDK ships with the following default async_contexts:
async_context_poll - this context is not thread-safe, and the user is responsible for calling async_context_poll() periodically, and can use async_context_wait_for_work_until() to sleep between calls until work is needed if the user has nothing else to do.
async_context_threadsafe_background - in order to work in the background, a low priority IRQ is used to handle callbacks. Code is usually invoked from this IRQ context, but may be invoked after any other code that uses the async context in another (non-IRQ) context on the same core. Calling async_context_poll() is not required, and is a no-op. This context implements async_context locking and is thus safe to call from either core, according to the specific notes on each API.
async_context_freertos - Work is performed from a separate "async_context" task, however once again, code may also be invoked after a direct use of the async_context on the same core that the async_context belongs to. Calling async_context_poll() is not required, and is a no-op. This context implements async_context locking and is thus safe to call from any task, and from either core, according to the specific notes on each API.
Each async_context provides bespoke methods of instantiation which are provided in the corresponding headers (e.g. async_context_poll.h, async_context_threadsafe_background.h, asycn_context_freertos.h). async_contexts are de-initialized by the common async_context_deint() method.
Multiple async_context instances can be used by a single application, and they will operate independently.
◆ async_at_time_worker_t
A "timeout" instance used by an async_context.
A "timeout" represents some future action that must be taken at a specific time. It's methods are called from the async_context under lock at the given time
- See also
- async_context_add_worker_at
-
async_context_add_worker_in_ms
◆ async_when_pending_worker_t
A "worker" instance used by an async_context.
A "worker" represents some external entity that must do work in response to some external stimulus (usually an IRQ). It's methods are called from the async_context under lock at the given time
- See also
- async_context_add_worker_at
-
async_context_add_worker_in_ms
◆ async_context_acquire_lock_blocking()
static void async_context_acquire_lock_blocking |
( |
async_context_t * |
context | ) |
|
|
inlinestatic |
◆ async_context_add_at_time_worker()
Add an "at time" worker to a context.
An "at time" worker will run at or after a specific point in time, and is automatically when (just before) it runs.
The time to fire is specified in the next_time field of the worker.
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
- Returns
- true if the worker was added, false if the worker was already present.
◆ async_context_add_at_time_worker_at()
Add an "at time" worker to a context.
An "at time" worker will run at or after a specific point in time, and is automatically when (just before) it runs.
The time to fire is specified by the at parameter.
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
context | the async_context |
worker | the "at time" worker to add |
at | the time to fire at |
- Returns
- true if the worker was added, false if the worker was already present.
◆ async_context_add_at_time_worker_in_ms()
Add an "at time" worker to a context.
An "at time" worker will run at or after a specific point in time, and is automatically when (just before) it runs.
The time to fire is specified by a delay via the ms parameter
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
context | the async_context |
worker | the "at time" worker to add |
ms | the number of milliseconds from now to fire after |
- Returns
- true if the worker was added, false if the worker was already present.
◆ async_context_add_when_pending_worker()
Add a "when pending" worker to a context.
An "when pending" worker will run when it is pending (can be set via async_context_set_work_pending), and is NOT automatically removed when it runs.
The time to fire is specified by a delay via the ms parameter
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
- Returns
- true if the worker was added, false if the worker was already present.
◆ async_context_core_num()
Return the processor core this async_context belongs to.
- Parameters
-
- Returns
- the physical core number
◆ async_context_deinit()
End async_context processing, and free any resources.
Note the user should clean up any resources associated with workers in the async_context themselves.
Asynchronous (non-polled) async_contexts guarantee that no callback is being called once this method returns.
- Parameters
-
- Returns
- the physical core number
◆ async_context_execute_sync()
static uint32_t async_context_execute_sync |
( |
async_context_t * |
context, |
|
|
uint32_t(*)(void *param) |
func, |
|
|
void * |
param |
|
) |
| |
|
inlinestatic |
Execute work synchronously on the core the async_context belongs to.
This method is intended for code external to the async_context (e.g. another thread/task) to execute a function with the same guarantees (single core, logical thread of execution) that async_context workers are called with.
- Note
- you should NOT call this method while holding the async_context's lock
- Parameters
-
context | the async_context |
func | the function to call |
parm | the paramter to pass to the function |
- Returns
- the return value from func
◆ async_context_lock_check()
Assert if the caller does not own the lock for the async_context.
- Note
- this method is thread-safe
- Parameters
-
◆ async_context_poll()
Perform any pending work for polling style async_context.
For a polled async_context (e.g. async_context_poll) the user is responsible for calling this method periodically to perform any required work.
This method may immediately perform outstanding work on other context types, but is not required to.
- Parameters
-
◆ async_context_release_lock()
Release the async_context lock.
- Note
- the async_context lock may be called in a nested fashion, so an internal count is maintained. On the outermost release, When the outermost lock is released, a check is made for work which might have been skipped while the lock was held, and any such work may be performed during this call IF the call is made from the same core that the async_context belongs to.
-
for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
- See also
- async_context_acquire_lock_blocking
◆ async_context_remove_at_time_worker()
Remove an "at time" worker from a context.
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
- Returns
- true if the worker was removed, false if the instance not present.
◆ async_context_remove_when_pending_worker()
Remove a "when pending" worker from a context.
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-
context | the async_context |
worker | the "when pending" worker to remove |
- Returns
- true if the worker was removed, false if the instance not present.
◆ async_context_set_work_pending()
Mark a "when pending" worker as having work pending.
The worker will be run from the async_context at a later time.
- Note
- this method may be called from any context including IRQs
- Parameters
-
context | the async_context |
worker | the "when pending" worker to mark as pending. |
◆ async_context_wait_for_work_ms()
static void async_context_wait_for_work_ms |
( |
async_context_t * |
context, |
|
|
uint32_t |
ms |
|
) |
| |
|
inlinestatic |
Block until work needs to be done or the specified number of milliseconds have passed.
- Note
- this method should not be called from a worker callback
- Parameters
-
context | the async_context |
ms | the number of milliseconds to return after if no work is required |
◆ async_context_wait_for_work_until()
Block until work needs to be done or the specified time has been reached.
- Note
- this method should not be called from a worker callback
- Parameters
-
context | the async_context |
until | the time to return at if no work is required |
◆ async_context_wait_until()
sleep until the specified time in an async_context callback safe way
- Note
- for async_contexts that provide locking (not async_context_poll), this method is threadsafe. and may be called from within any worker method called by the async_context or from any other non-IRQ context.
- Parameters
-