17#include "freertos/FreeRTOS.h"
18#include "freertos/queue.h"
19#include "freertos/task.h"
26thread_local int t_worker_id = 0;
34#if PC_WORKER_COUNT != 1
60 std::atomic<bool> run{
false};
72void worker_task(
void *arg)
74 int id = (int)(intptr_t)arg;
76 while (s_worker.run.load(std::memory_order_acquire))
84 s_worker.tasks[id] =
nullptr;
110struct DeferStorageCtx
115DeferStorageCtx s_defer_store;
120 if (s_worker.run.load(std::memory_order_acquire))
124 s_worker.pump = pump;
129 s_defer.dq[i] = xQueueCreateStatic(
PC_DEFER_QUEUE_DEPTH,
sizeof(DeferCmd), s_defer_store.dq_storage[i],
130 &s_defer_store.dq_struct[i]);
133 s_worker.run.store(
true, std::memory_order_release);
148 if (worker_id < 0 || worker_id >=
PC_WORKER_COUNT || !s_defer.dq[worker_id])
152 DeferCmd cmd = {fn, arg};
153 if (xQueueSend(s_defer.dq[worker_id], &cmd, 0) != pdTRUE)
167 TaskHandle_t t = s_worker.tasks[worker_id];
176 if (worker_id < 0 || worker_id >=
PC_WORKER_COUNT || !s_defer.dq[worker_id])
181 while (xQueueReceive(s_defer.dq[worker_id], &cmd, 0) == pdTRUE)
192 if (!s_worker.run.load(std::memory_order_acquire))
196 s_worker.run.store(
false, std::memory_order_release);
204 return s_worker.run.load(std::memory_order_acquire);
#define PC_DEFER_QUEUE_DEPTH
Depth of each worker's deferred-callback queue.
#define PC_WORKER_TASK_PRIORITY
FreeRTOS priority for each server worker task (ESP32).
#define PC_WORKER_COUNT
Number of server worker tasks (slots partitioned i % N). Default 1.
#define PC_WORKER_TASK_STACK
#define PC_WORKER_CORE
Core that worker 0 pins to (ESP32). Worker k pins to (PC_WORKER_CORE.
#define PC_WORKER_POLL_TICKS
Idle-sweep timeout, in FreeRTOS ticks, that a worker blocks between service iterations when no events...
void pc_worker_run_deferred(int worker_id)
Drain and run worker worker_id's deferred callbacks (called by the worker).
void pc_worker_wake(int worker_id)
Wake worker worker_id so it services a freshly-queued event now.
void pc_workers_start(pc_worker_pump_fn pump)
Spawn the worker task(s) and start them running pump. No-op on host.
bool pc_workers_running(void)
True while worker task(s) are running (always false on host).
void pc_worker_set_self(int id)
Bind the calling task/thread to worker id id (worker entry / tests).
int pc_worker_count(void)
Number of server worker tasks (PC_WORKER_COUNT).
bool pc_defer(int worker_id, pc_deferred_fn fn, void *arg)
Run fn(arg) on worker worker_id. Returns false if the queue is full.
void pc_workers_stop(void)
Signal the worker task(s) to exit and wait briefly for them. No-op on host.
int pc_worker_self(void)
Worker id [0, count) of the calling task; 0 by default / single-worker.
Layer 5 (Session) - server worker identity.
void(* pc_worker_pump_fn)(int worker_id)
Pump callback run by each worker task with its worker id.
void(* pc_deferred_fn)(void *arg)
Deferred callback signature.