Workqueues
include/thread/workqueue.h View source View on GitHubStructs
Section titled “Structs”work_args
Section titled “work_args” struct work (5 fields) source
delayed_work
Section titled “delayed_work” struct delayed_work (3 fields) source
worker
Section titled “worker” struct worker (12 fields) source
workqueue_stats
Section titled “workqueue_stats” struct workqueue_stats (10 fields) source
Get in profiling.h and put these under there
uint64_t total_tasks_added Total # of tasks submitted to the queue
uint64_t total_tasks_executed Number of tasks successfully executed
uint64_t total_workers_spawned Total worker threads spawned
uint64_t total_worker_exits Total workers that exited
uint64_t max_queue_length Max observed length of the task queue
uint64_t current_queue_length Current length of the queue
uint64_t total_spawn_attempts times spawn_worker was attempted
uint64_t total_spawn_failures Number of times spawn_worker failed
uint64_t num_idle_workers Snapshot of current idle workers
uint64_t num_active_workers Snapshot of current active workers
workqueue_attributes
Section titled “workqueue_attributes” struct workqueue_attributes (7 fields) source
workqueue
Section titled “workqueue” struct workqueue (23 fields) source
char *name atomic_bool ignore_timeouts atomic_uint64_t head atomic_uint64_t tail atomic_bool spawn_pending Some enqueue wants us to spawn a worker
atomic_uint32_t num_tasks How many tasks do we have in the ringbuf
atomic_uint32_t num_workers Current # workers
atomic_uint32_t idle_workers idle
atomic_flag spawner_flag_internal struct workqueue_attributes attrs atomic(enum workqueue_state) state Atomic to avoid race where stale state is seen
struct thread_request *request refcount_t refcount worker_next_action
Section titled “worker_next_action”workqueue_flags
Section titled “workqueue_flags” enum workqueue_flags : uint16_t (13 variants) source
WORKQUEUE_FLAG_PERMANENT = 1 << 1 Inverse: On-demand
Permanent workqueues are attached to each core and are always Active workqueues with on-demand worker spawning
WORKQUEUE_FLAG_AUTO_SPAWN = 1 << 2 Inverse: No auto spawn
This flag allows workqueues with multiple workers to spawn workers automatically if they detect that workers are busy.
Otherwise, that doesn’t happen, and workers are manually spawned
WORKQUEUE_FLAG_NAMED = 1 << 3 Has name - will honor (fmt, …)
WORKQUEUE_FLAG_STATIC_WORKERS = 1 << 4 struct worker will be
statically allocated
during workqueue creation.
This allows allocators to safely use workqueues that dynamically spawn threads, but shouldn’t be used everywhere because it can waste memory
WORKQUEUE_FLAG_NO_WORKER_GC = 1 << 5 Do not timeout workers
WORKQUEUE_FLAG_ISR_SAFE = 1 << 6 WORKQUEUE_FLAG_NO_AUTO_SPAWN = 0 Do not auto spawn workers
WORKQUEUE_FLAG_ON_DEMAND = 0 Inverse of a permanent workqueue
WORKQUEUE_FLAG_NAMELESS = 0 WORKQUEUE_FLAG_NON_STATIC_WORKERS = 0 WORKQUEUE_FLAG_WORKER_GC = 0 WORKQUEUE_FLAG_NON_ISR_SAFE = 0 WORKQUEUE_FLAG_DEFAULTS = WORKQUEUE_FLAG_AUTO_SPAWN | WORKQUEUE_FLAG_NAMED workqueue_state
Section titled “workqueue_state” enum workqueue_state : uint16_t (3 variants) source
workqueue_error
Section titled “workqueue_error” enum workqueue_error : int32_t (7 variants) source
Positive values are success with a message, zero is success with nothing special.
Negative values are errors
WORKQUEUE_ERROR_NEED_NEW_WORKER = 4 For manual worker spawn
WORKQUEUE_ERROR_NEED_NEW_WQ = 3 All worker slots filled
WORKQUEUE_ERROR_OK = 0 No message
WORKQUEUE_ERROR_FULL = -1 Full ringbuffer
WORKQUEUE_ERROR_WLIST_EXECUTING = -2 Worklist executing
WORKQUEUE_ERROR_UNUSABLE = -3 Being destroyed, etc.
WORKQUEUE_ERROR_WORK_EXECUTING = -4 Type Aliases
Section titled “Type Aliases”work_function
Section titled “work_function”typedef void (*work_function)(void * arg, void * arg2) source Functions
Section titled “Functions”delayed_work_init
Section titled “delayed_work_init”void delayed_work_init(
struct delayed_work *dwork,
work_function fn,
struct work_args args
) source delayed_work_schedule
Section titled “delayed_work_schedule”bool delayed_work_schedule(
struct delayed_work *dwork,
time_ms_t delay_ms
) source delayed_work_schedule_on
Section titled “delayed_work_schedule_on”delayed_work_cancel
Section titled “delayed_work_cancel”bool delayed_work_cancel(struct delayed_work *dwork) source delayed_work_cancel_sync
Section titled “delayed_work_cancel_sync”bool delayed_work_cancel_sync(struct delayed_work *dwork) source workqueues_permanent_init
Section titled “workqueues_permanent_init”void workqueues_permanent_init(void) source workqueue_create_internal
Section titled “workqueue_create_internal”struct workqueue * workqueue_create_internal(
struct workqueue_attributes *attrs,
const char *fmt
) source workqueue_create_default
Section titled “workqueue_create_default”work_create
Section titled “work_create”struct work * work_create(work_function func, struct work_args args) source work_init
Section titled “work_init”workqueue_free
Section titled “workqueue_free”workqueue_enqueue
Section titled “workqueue_enqueue”enum workqueue_error workqueue_enqueue(
struct workqueue *queue,
struct work *work
) source work_execute
Section titled “work_execute”void work_execute(struct work *cc_nonnull_ptr) source workqueue_should_spawn_worker
Section titled “workqueue_should_spawn_worker”workqueue_kick
Section titled “workqueue_kick”workqueue_destroy
Section titled “workqueue_destroy”void workqueue_destroy(struct workqueue *cc_nonnull_ptr) source worker_main
Section titled “worker_main”void worker_main(void * *) source work_active
Section titled “work_active”Macros
Section titled “Macros”WORK_ARGS
Section titled “WORK_ARGS”#define WORK_ARGS(a, b) source WORKQUEUE_FLAG_SET
Section titled “WORKQUEUE_FLAG_SET”#define WORKQUEUE_FLAG_SET(q, f) source Expansion
#define WORKQUEUE_FLAG_SET(q, f) (q->attrs.flags |= f) WORKQUEUE_FLAG_UNSET
Section titled “WORKQUEUE_FLAG_UNSET”#define WORKQUEUE_FLAG_UNSET(q, f) source Expansion
#define WORKQUEUE_FLAG_UNSET(q, f) (q->attrs.flags &= ~f) WORKQUEUE_FLAG_TEST
Section titled “WORKQUEUE_FLAG_TEST”#define WORKQUEUE_FLAG_TEST(q, f) source Expansion
#define WORKQUEUE_FLAG_TEST(q, f) (q->attrs.flags & f) WORKQUEUE_STATE_SET
Section titled “WORKQUEUE_STATE_SET”#define WORKQUEUE_STATE_SET(q, s) source Expansion
#define WORKQUEUE_STATE_SET(q, s) (atomic_store(&q->state, s)) WORKQUEUE_STATE_GET
Section titled “WORKQUEUE_STATE_GET”#define WORKQUEUE_STATE_GET(q) source Expansion
#define WORKQUEUE_STATE_GET(q) (atomic_load(&q->state)) WORKQUEUE_DEFAULT_MAX_WORKERS
Section titled “WORKQUEUE_DEFAULT_MAX_WORKERS”#define WORKQUEUE_DEFAULT_MAX_WORKERS 16 source WORKQUEUE_DEFAULT_SPAWN_DELAY
Section titled “WORKQUEUE_DEFAULT_SPAWN_DELAY”#define WORKQUEUE_DEFAULT_SPAWN_DELAY 150 source WORKQUEUE_DEFAULT_MIN_IDLE_CHECK
Section titled “WORKQUEUE_DEFAULT_MIN_IDLE_CHECK”#define WORKQUEUE_DEFAULT_MIN_IDLE_CHECK SECONDS_TO_MS(2) source WORKQUEUE_DEFAULT_MAX_IDLE_CHECK
Section titled “WORKQUEUE_DEFAULT_MAX_IDLE_CHECK”#define WORKQUEUE_DEFAULT_MAX_IDLE_CHECK SECONDS_TO_MS(40) source WORKQUEUE_DEFAULT_IDLE_CHECK
Section titled “WORKQUEUE_DEFAULT_IDLE_CHECK”#define WORKQUEUE_DEFAULT_IDLE_CHECK source Expansion
#define WORKQUEUE_DEFAULT_IDLE_CHECK \
{.max = WORKQUEUE_DEFAULT_MAX_IDLE_CHECK, \
.min = WORKQUEUE_DEFAULT_MIN_IDLE_CHECK} workqueue_create
Section titled “workqueue_create”#define workqueue_create(name, attrs) source Expansion
#define workqueue_create(name, attrs) \
workqueue_create_internal((attrs), PP_UNPAREN(name))