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);
void defer_init(void);
bool defer_enqueue(work_function func, struct work_args args, uint64_t delay_ms);

defer_enqueue referenced types:

void workqueues_permanent_init(void);
struct workqueue * workqueue_create(char *fmt, struct workqueue_attributes *attrs);

workqueue_create referenced types:

struct workqueue * workqueue_create_default(char *fmt);

workqueue_create_default referenced types:

struct work * work_create(work_function func, struct work_args args);

work_create referenced types:

struct work * work_init(struct work *work, work_function fn, struct work_args args);

work_init referenced types:

void workqueue_free(struct workqueue *queue);

workqueue_free referenced types:

enum workqueue_error workqueue_enqueue_oneshot(struct workqueue *queue, work_function func, struct work_args args);

workqueue_enqueue_oneshot referenced types:

enum workqueue_error workqueue_enqueue(struct workqueue *queue, struct work *work);

workqueue_enqueue referenced types:

workqueue_error workqueue_add_oneshot(work_function func, struct work_args args);

workqueue_add_oneshot referenced types:

workqueue_error workqueue_add_remote_oneshot(work_function func, struct work_args args);

workqueue_add_remote_oneshot referenced types:

workqueue_error workqueue_add_local_oneshot(work_function func, struct work_args args);

workqueue_add_local_oneshot referenced types:

workqueue_error workqueue_add_fast_oneshot(work_function func, struct work_args args);

workqueue_add_fast_oneshot referenced types:

workqueue_error workqueue_add(struct work *work);

workqueue_add referenced types:

workqueue_error workqueue_add_remote(struct work *work);

workqueue_add_remote referenced types:

workqueue_error workqueue_add_local(struct work *work);

workqueue_add_local referenced types:

workqueue_error workqueue_add_fast(struct work *work);

workqueue_add_fast referenced types:

void work_execute(struct work *task);

work_execute referenced types:

bool workqueue_should_spawn_worker(struct workqueue *queue);

workqueue_should_spawn_worker referenced types:

void workqueue_kick(struct workqueue *queue);

workqueue_kick referenced types:

void workqueue_destroy(struct workqueue *queue);

workqueue_destroy referenced types:

void worker_main(void *);
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)