#define WORK_FUNCTION(name) void name(void *data)
typedef WORK_FUNCTION(WorkQueueCallback);

struct WorkQueueEntry {
    WorkQueueCallback *callback;
    void              *data;
};

struct ThreadCtx {
    int thread_index;
};

struct WorkQueue {
    int32_t        thread_count;
    WorkQueueEntry entries[256];
    int64_t volatile index_to_write;
    int64_t volatile index_to_read;
    int64_t volatile completion_index;
    int64_t volatile completion_goal;
    void *semaphore;
};

struct ThreadStartupInfo {
    uint32_t   thread_id;
    int32_t    thread_index;
    WorkQueue *queue;
};

void PushWork(WorkQueue *wq, void *data, WorkQueueCallback *callback);
void InitWorkQueue(WorkQueue *queue, uint32_t thread_count, ThreadStartupInfo *info);
void WaitUntilCompletion(WorkQueue *wq);

int64_t AtomicIncrement(volatile int64_t *i);