99 lines
2.9 KiB
C
99 lines
2.9 KiB
C
////////////////////////////////
|
|
//~ Job queue types
|
|
|
|
/* Work pools contain their own worker threads with their own thread priority
|
|
* affinity based on the intended context of the pool. */
|
|
typedef i32 JobPool; enum
|
|
{
|
|
JobPool_Inherit = -1,
|
|
|
|
/* The floating pool contains a large number of lower priority worker
|
|
* threads that have affinity over the entire CPU. Other pools should push
|
|
* jobs that only block and do no work here so that they can yield on the
|
|
* blocking job rather than blocking themselves. */
|
|
JobPool_Floating = 0,
|
|
|
|
JobPool_Background = 1,
|
|
JobPool_Audio = 2,
|
|
JobPool_User = 3,
|
|
JobPool_Sim = 4,
|
|
|
|
JobPool_Count
|
|
};
|
|
|
|
/* Job execution order within a pool is based on priority. */
|
|
typedef i32 JobPriority; enum
|
|
{
|
|
JobPriority_Inherit = -1,
|
|
JobPriority_High = 0,
|
|
JobPriority_Normal = 1,
|
|
JobPriority_Low = 2,
|
|
|
|
JobPriority_Count
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ @hookdecl Startup
|
|
|
|
void StartupBaseJobs(void);
|
|
|
|
////////////////////////////////
|
|
//~ @hookdecl Futex
|
|
|
|
/* Futex-like wait & wake */
|
|
void FutexWait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns);
|
|
void FutexWake(void *addr, i32 count);
|
|
|
|
////////////////////////////////
|
|
//~ @hookdecl Job helpers
|
|
|
|
#define EmptySig { i32 _; }
|
|
|
|
typedef void GenericJobFunc(void *, i32);
|
|
|
|
Struct(GenericJobDesc)
|
|
{
|
|
Arena *arena;
|
|
void *sig;
|
|
GenericJobFunc *func;
|
|
i32 count;
|
|
JobPool pool;
|
|
JobPriority priority;
|
|
Counter *counter;
|
|
};
|
|
|
|
Struct(JobDescParams)
|
|
{
|
|
i32 count;
|
|
JobPool pool;
|
|
JobPriority priority;
|
|
Counter *counter;
|
|
};
|
|
|
|
#define JobDecl(job, sigdef) \
|
|
typedef struct job##_Sig sigdef job##_Sig; \
|
|
Struct(job##_Desc) { Arena *arena; job##_Sig *sig; GenericJobFunc *func; i32 count; JobPool pool; JobPriority priority; Counter *counter; }; \
|
|
void job(job##_Sig *, i32); \
|
|
inline void job##_Generic(void *sig, i32 id) { job((job##_Sig *)sig, id); } \
|
|
StaticAssert(1)
|
|
|
|
#define PushJobDesc(job, ...) (job##_Desc *)PushJobDesc_(sizeof(job##_Sig), alignof(job##_Sig), job##_Generic, (JobDescParams) { .count = 1, .pool = JobPool_Inherit, .priority = JobPriority_Inherit, .counter = 0, __VA_ARGS__ })
|
|
GenericJobDesc *PushJobDesc_(u64 sig_size, u64 sig_align, GenericJobFunc *func, JobDescParams params);
|
|
|
|
#define JobDef(job, sig_arg, id_arg) void job(job##_Sig *sig_arg, i32 id_arg)
|
|
|
|
#define RunJob(_count, job, _pool, _priority, _counter, ...) do { \
|
|
job##_Desc *__job_desc = (job##_Desc *)PushJobDesc_(sizeof(job##_Sig), alignof(job##_Sig), job##_Generic, (JobDescParams) { .count = _count, .pool = _pool, .priority = _priority, .counter = _counter,}); \
|
|
*__job_desc->sig = (job##_Sig) { __VA_ARGS__ }; \
|
|
RunJobEx((GenericJobDesc *)__job_desc); \
|
|
} while (0)
|
|
void RunJobEx(GenericJobDesc *desc);
|
|
|
|
////////////////////////////////
|
|
//~ @hookdecl Helpers
|
|
|
|
i64 TimeNs(void);
|
|
u32 ThreadId(void);
|
|
u32 GetLogicalProcessorCount(void);
|
|
i64 GetCurrentSchedulerPeriodNs(void);
|