AxlTask — Task Pool and Arena
AP worker pool, region-based arena allocator, preallocated buffer pool, and async work helpers.
Headers:
<axl/axl-task.h>— Arena allocator and AP task pool<axl/axl-buf-pool.h>— Preallocated buffer pool (LIFO free-stack)<axl/axl-async.h>— AP-offloaded async work
Overview
UEFI systems have multiple CPU cores, but only one — the Bootstrap Processor (BSP) — can call Boot Services (I/O, networking, protocol calls). The other cores are Application Processors (APs) that can run compute-heavy tasks in parallel.
BSP (main core) APs (worker cores)
├─ Boot Services (gBS) ├─ CRC/checksum
├─ Protocol calls ├─ Decompression
├─ Network I/O ├─ Hash computation
├─ File I/O ├─ Data parsing
├─ axl_printf └─ Memory-only work
└─ Event loop (no Boot Services!)
AP constraints: APs cannot call Boot Services, axl_printf,
axl_fopen, or any UEFI protocol function. They can only access
memory (including the arena allocator, which uses lock-free CAS).
Arena Allocator
Lock-free bump allocator for AP-safe memory. Pre-allocates a contiguous block; allocations are O(1) pointer bumps with CAS (no locks needed for concurrent AP access).
AXL_AUTOPTR(AxlArena) arena = axl_arena_new(4096);
// AP-safe: can be called from any core
void *buf = axl_arena_alloc(arena, 256);
// BSP-only: reset frees all allocations at once
axl_arena_reset(arena);
Task Pool
Submit work to an AP and get a callback on the BSP when it completes:
// Create pool (discovers available APs)
AxlTaskPool *pool = axl_task_pool_new();
// AP work function (runs on a worker core)
void compute(void *arg, AxlArena *arena) {
Result *r = axl_arena_alloc(arena, sizeof(Result));
r->crc = calculate_crc(arg);
}
// BSP completion callback (runs on main core)
void on_done(void *arg, AxlArena *arena) {
axl_printf("CRC computed on AP\n");
}
AxlArena *arena = axl_arena_new(1024);
axl_task_pool_submit(pool, compute, data, arena, on_done);
// Poll for completions (call from event loop or main loop)
axl_task_pool_poll(pool);
// Single-core fallback: if no APs available, submit runs
// the work synchronously on the BSP.
axl_task_pool_free(pool);
AxlBufPool
Preallocated fixed-size buffer pool with LIFO free-stack. Zero-copy:
get returns a buffer pointer, put returns it to the pool.
No allocation or freeing in the hot path.
AXL_AUTOPTR(AxlBufPool) pool = axl_buf_pool_new(4, 64 * 1024);
// ^ ^
// 4 buffers, 64KB each
void *buf = axl_buf_pool_get(pool); // grab a buffer (NULL if exhausted)
// ... use buf ...
axl_buf_pool_put(pool, buf); // return to pool
AxlAsync
Convenience wrapper: submit AP work and get a BSP callback via the event loop (combines AxlTask + AxlLoop idle source).
AxlAsync *async = axl_async_new(loop, 4); // max 4 pending jobs
axl_async_submit(async, work_fn, data, arena, done_fn);
// work_fn runs on AP, done_fn fires on BSP via loop idle
axl_async_free(async);
See also
docs/AXL-Concurrency.md— the full primitive-selection taxonomy.AxlTaskandAxlAsyncare the “work offload” axis; the doc also coversAxlLoop(dispatch),AxlEvent/AxlCancellable/AxlWait(coordination), andAxlPubsub(notification).src/event/README.md— the signalling primitive to rendezvous with completed AP work.
API Reference
AxlTask
Defines
-
axl_arena_new(capacity)
Captures the caller’s file/line for leak reporting via the tier-1 resource registry. See docs/AXL-Lifecycle.md §4.2.1.
-
AXL_TASK_ID_INVALID
Typedefs
-
typedef struct AxlArena AxlArena
axl-task.h:
AP worker pool and region-based arena allocator. The arena provides lock-free bump allocation suitable for AP use. The task pool dispatches work to Application Processors (APs).
-
typedef struct AxlTaskPool AxlTaskPool
-
typedef uint32_t AxlTaskId
Functions
-
AxlArena *axl_arena_new_impl(size_t capacity, const char *file, int line)
Create a new arena with fixed capacity. BSP-only.
All memory is zeroed.
- Parameters:
capacity – total bytes available
file – caller file (via macro)
line – caller line (via macro)
- Returns:
arena handle, or NULL on failure.
-
void axl_arena_free(AxlArena *arena)
Free backing memory. BSP-only.
- Parameters:
arena – arena to free (NULL-safe)
-
void *axl_arena_alloc(AxlArena *arena, size_t size)
Allocate from arena. AP-safe (lock-free CAS).
Returns zeroed, 8-byte-aligned memory. Returns NULL on exhaustion.
- Parameters:
arena – arena
size – bytes to allocate
-
void axl_arena_reset(AxlArena *arena)
Reset arena, freeing all allocations.
Backing memory retained and zeroed. BSP-only.
- Parameters:
arena – arena to reset
-
size_t axl_arena_remaining(AxlArena *arena)
Get bytes remaining in the arena.
- Parameters:
arena – arena to query
- Returns:
bytes remaining.
-
size_t axl_arena_capacity(AxlArena *arena)
Get total capacity of the arena.
- Parameters:
arena – arena to query
- Returns:
total capacity in bytes.
-
AxlTaskPool *axl_task_pool_new(void)
Create a new task pool.
Locates MP Services and dispatches APs.
- Returns:
pool handle, or NULL on error.
-
void axl_task_pool_free(AxlTaskPool *pool)
Free the task pool. Signals all workers to exit.
- Parameters:
pool – pool to free (NULL-safe)
-
AxlTaskId axl_task_pool_submit(AxlTaskPool *pool, AxlTaskProc proc, void *arg, AxlArena *arena, AxlTaskComplete on_complete)
Submit a task. Non-blocking.
On single-core, runs synchronously.
- Parameters:
pool – task pool
proc – task procedure (AP-safe)
arg – argument passed to proc and on_complete
arena – arena for task allocations (NULL = no arena)
on_complete – BSP callback when done (NULL = fire-and-forget)
- Returns:
task ID, or AXL_TASK_ID_INVALID if all workers busy.
-
size_t axl_task_pool_poll(AxlTaskPool *pool)
Poll for completed tasks. Call once per event loop iteration.
- Parameters:
pool – task pool
- Returns:
number of tasks completed this poll cycle.
-
bool axl_task_pool_done(AxlTaskPool *pool, AxlTaskId id)
Check if a task is done.
- Parameters:
pool – task pool
id – task ID
- Returns:
true if task is done (or ID is invalid).
-
size_t axl_task_pool_available(AxlTaskPool *pool)
Get idle worker count.
- Parameters:
pool – task pool
- Returns:
number of idle workers.
-
size_t axl_task_pool_worker_count(AxlTaskPool *pool)
Get total worker count.
- Parameters:
pool – task pool
- Returns:
total worker count (0 on single-core).
-
bool axl_task_pool_is_single_core(AxlTaskPool *pool)
Check if the pool is in single-core fallback mode.
- Parameters:
pool – task pool
- Returns:
true if single-core (no APs available).
AxlBufPool
Typedefs
-
typedef struct AxlBufPool AxlBufPool
axl-buf-pool.h:
Preallocated buffer pool with zero-copy get/put.
All buffers are allocated up front in a single contiguous block. Get and put are O(1) free-stack operations — no allocation, no memcpy. Designed for network receive buffers, file transfer chunks, and VNC tile buffers.
AxlBufPool *pool = axl_buf_pool_new(4, 64 * 1024); // 4 x 64KB void *buf = axl_buf_pool_get(pool); // grab a buffer // ... use buf ... axl_buf_pool_put(pool, buf); // return it axl_buf_pool_free(pool);
Functions
-
AxlBufPool *axl_buf_pool_new(size_t count, size_t buf_size)
Create a new buffer pool.
Allocates count buffers of buf_size bytes each in a single contiguous block. All buffers are initially available.
- Parameters:
count – number of buffers
buf_size – size of each buffer in bytes
- Returns:
pool handle, or NULL on failure.
-
void *axl_buf_pool_get(AxlBufPool *pool)
Get a buffer from the pool.
- Parameters:
pool – buffer pool
- Returns:
pointer to a buffer, or NULL if the pool is exhausted.
-
void axl_buf_pool_put(AxlBufPool *pool, void *buf)
Return a buffer to the pool.
The buffer must have been obtained from this pool via axl_buf_pool_get. NULL-safe (no-op if pool or buf is NULL).
- Parameters:
pool – buffer pool
buf – buffer to return
-
size_t axl_buf_pool_available(AxlBufPool *pool)
Get the number of available (free) buffers.
- Parameters:
pool – buffer pool (NULL returns 0)
- Returns:
number of buffers available for axl_buf_pool_get.
-
size_t axl_buf_pool_buf_size(AxlBufPool *pool)
Get the size of each buffer in the pool.
- Parameters:
pool – buffer pool
- Returns:
buffer size in bytes (0 if pool is NULL).
-
void axl_buf_pool_free(AxlBufPool *pool)
Free the pool and all backing memory. NULL-safe.
- Parameters:
pool – buffer pool to free
AxlAsync
Defines
-
AXL_ASYNC_INVALID
Typedefs
-
typedef struct AxlLoop AxlLoop
axl-async.h:
AP-offloaded async work queue with main-loop integration.
Bridges AxlTask (AP core dispatch) with AxlLoop (main loop events). Submit CPU-heavy work to an Application Processor while the BSP continues servicing network, timers, and UI. The done callback fires on the BSP during an idle poll in the event loop.
On single-core systems, work runs synchronously on the BSP (same API, just blocking).
AxlAsync *async = axl_async_new(loop, 4); AxlAsyncHandle h = axl_async_submit(async, verify_crc, chunk, arena, on_done); // BSP continues — on_done fires when AP finishes axl_async_free(async);AP constraints: work functions cannot call Boot Services, protocol calls, logging, or axl_malloc. Use the arena for AP-side allocation.
-
typedef uint32_t AxlAsyncHandle
Functions
-
AxlAsync *axl_async_new(AxlLoop *loop, size_t max_pending)
Create a new async work queue.
Creates an internal task pool and slot array.
- Parameters:
loop – event loop (idle source installed here)
max_pending – maximum concurrent async jobs
- Returns:
async handle, or NULL on failure.
-
void axl_async_free(AxlAsync *async)
Free the async work queue. Drains pending work.
- Parameters:
async – async handle (NULL-safe)
-
AxlAsyncHandle axl_async_submit(AxlAsync *async, AxlTaskProc work_fn, void *data, AxlArena *arena, AxlTaskComplete done_cb)
Submit work to an AP core.
On multi-core, dispatches work_fn to an AP and returns immediately. On single-core, runs work_fn and done_cb synchronously before returning.
- Parameters:
async – async handle
work_fn – AP work function (same as AxlTaskProc)
data – argument passed to work_fn and done_cb
arena – arena for AP allocations (NULL OK)
done_cb – BSP callback when done (NULL = fire-and-forget)
- Returns:
handle for axl_async_cancel, or AXL_ASYNC_INVALID on failure.
-
bool axl_async_cancel(AxlAsync *async, AxlAsyncHandle handle)
Cancel pending async work (best-effort).
AP work continues to completion, but done_cb is suppressed.
- Parameters:
async – async handle
handle – handle from axl_async_submit
- Returns:
true if cancelled, false if handle invalid or already completed.