#ifndef WORK_H
#define WORK_H

enum work_status {
    WORK_STATUS_DONE,
    WORK_STATUS_SCHEDULED,
    WORK_STATUS_IN_PROGRESS
};

enum work_priority {
    WORK_PRIORITY_HIGH,
    WORK_PRIORITY_NORMAL,

    NUM_WORK_PRIORITIES
};

#define WORK_TASK_FUNC_DEF(name, arg_name) void name(void *arg_name)
typedef WORK_TASK_FUNC_DEF(work_task_func, data);

struct work;
struct work_task;

struct work_handle {
    struct work *work;
    u64 gen;
};

struct work_slate {
    struct work_task *task_head;
    struct work_task *task_tail;
    u32 num_tasks;
};

struct work_startup_receipt { i32 _; };
struct work_startup_receipt work_startup(u32 num_worker_threads);

struct work_slate work_slate_begin(void);
struct work_handle work_slate_end(struct work_slate *ws, enum work_priority priority);
struct work_handle work_slate_end_and_help(struct work_slate *ws, enum work_priority priority);

struct work_handle work_push_task(work_task_func *func, void *data, enum work_priority priority);
struct work_handle work_push_task_and_help(work_task_func *func, void *data, enum work_priority priority);
void work_slate_push_task(struct work_slate *ws, work_task_func *func, void *data);

void work_wait(struct work_handle handle);
void work_help(struct work_handle handle);

#endif
