Skip to content

Workqueues

struct work_args {
void *arg1;
void *arg2;
};
struct deferred_event {
size_t timer;
uint64_t timestamp_ms;
work_function callback;
struct work_args args;
struct deferred_event *next;
};

struct deferred_event referenced types:

struct work {
work_function func;
struct work_args args;
struct list_head list_node;
atomic_bool enqueued;
atomic_bool active;
uint64_t seq;
};

struct work referenced types:

struct worker {
struct thread *thread;
struct workqueue *workqueue;
time_t last_active;
time_t inactivity_check_period;
time_t start_idle;
bool timeout_ran;
bool should_exit;
bool is_permanent;
bool present;
bool idle;
enum worker_next_action next_action;
struct list_head list_node;
};

struct worker referenced types:

struct workqueue_stats {
uint64_t total_tasks_added;
uint64_t total_tasks_executed;
uint64_t total_workers_spawned;
uint64_t total_worker_exits;
uint64_t max_queue_length;
uint64_t current_queue_length;
uint64_t total_spawn_attempts;
uint64_t total_spawn_failures;
uint64_t num_idle_workers;
uint64_t num_active_workers;
};
struct workqueue_attributes {
size_t min_workers;
size_t max_workers;
size_t capacity;
time_t spawn_delay;
nice_t worker_niceness;
struct {
uint64_t min;
uint64_t max;
} idle_check;
enum workqueue_flags flags;
struct cpu_mask worker_cpu_mask;
};

struct workqueue_attributes referenced types:

struct workqueue {
char *name;
atomic_bool ignore_timeouts;
struct spinlock work_lock;
struct spinlock worker_lock;
struct spinlock worker_array_lock;
struct spinlock lock;
struct condvar queue_cv;
struct work *oneshot_works;
struct list_head workers;
struct list_head works;
struct worker *worker_array;
uint64_t head;
uint64_t tail;
atomic_bool spawn_pending;
uint32_t num_tasks;
uint32_t num_workers;
uint32_t idle_workers;
cpu_id_t core;
time_t last_spawn_attempt;
atomic_flag spawner_flag_internal;
struct workqueue_attributes attrs;
enum workqueue_state state;
struct thread_request *request;
refcount_t refcount;
};

struct workqueue referenced types:

enum worker_next_action {
WORKER_NEXT_ACTION_RUN,
WORKER_NEXT_ACTION_EXIT,
};
enum workqueue_flags {
WORKQUEUE_FLAG_PERMANENT = 1 << 1,
WORKQUEUE_FLAG_AUTO_SPAWN = 1 << 2,
WORKQUEUE_FLAG_NAMED = 1 << 3,
WORKQUEUE_FLAG_STATIC_WORKERS = 1 << 4,
WORKQUEUE_FLAG_NO_WORKER_GC = 1 << 5,
WORKQUEUE_FLAG_ISR_SAFE = 1 << 6,
WORKQUEUE_FLAG_NO_AUTO_SPAWN = 0,
WORKQUEUE_FLAG_ON_DEMAND = 0,
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,
};
enum workqueue_state {
WORKQUEUE_STATE_DEAD,
WORKQUEUE_STATE_DESTROYING,
WORKQUEUE_STATE_ACTIVE,
};
enum workqueue_error {
WORKQUEUE_ERROR_NEED_NEW_WORKER = 4,
WORKQUEUE_ERROR_NEED_NEW_WQ = 3,
WORKQUEUE_ERROR_OK = 0,
WORKQUEUE_ERROR_FULL = -1,
WORKQUEUE_ERROR_WLIST_EXECUTING = -2,
WORKQUEUE_ERROR_UNUSABLE = -3,
WORKQUEUE_ERROR_WORK_EXECUTING = -4,
};
typedef void (*work_function)(void * arg, void * arg2);
bool work_active(struct work *work);

work_active referenced types:

#define WORK_ARGS(a, b) ((struct work_args) {.arg1 = a, .arg2 = b})
#define WORKQUEUE_FLAG_SET(q, f) (q->attrs.flags |= f)
#define WORKQUEUE_FLAG_UNSET(q, f) (q->attrs.flags &= ~f)
#define WORKQUEUE_FLAG_TEST(q, f) (q->attrs.flags & f)
#define WORKQUEUE_STATE_SET(q, s) (atomic_store(&q->state, s))
#define WORKQUEUE_STATE_GET(q) (atomic_load(&q->state))
#define WORKQUEUE_DEFAULT_CAPACITY 512
#define WORKQUEUE_DEFAULT_MAX_WORKERS 16
#define WORKQUEUE_DEFAULT_SPAWN_DELAY 150
#define WORKQUEUE_DEFAULT_MIN_IDLE_CHECK SECONDS_TO_MS(2)
#define WORKQUEUE_DEFAULT_MAX_IDLE_CHECK SECONDS_TO_MS(40)