mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
163 lines
4.0 KiB
C
163 lines
4.0 KiB
C
// Copyright (c) Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
#ifndef ASYNC_H
|
|
#define ASYNC_H
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Work Function Type
|
|
|
|
#define ASYNC_WORK_SIG(name) void *name(U64 thread_idx, void *input)
|
|
#define ASYNC_WORK_DEF(name) internal ASYNC_WORK_SIG(name)
|
|
typedef ASYNC_WORK_SIG(ASYNC_WorkFunctionType);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Work Types
|
|
|
|
typedef enum ASYNC_Priority
|
|
{
|
|
ASYNC_Priority_Low,
|
|
ASYNC_Priority_High,
|
|
ASYNC_Priority_COUNT
|
|
}
|
|
ASYNC_Priority;
|
|
|
|
typedef struct ASYNC_WorkParams ASYNC_WorkParams;
|
|
struct ASYNC_WorkParams
|
|
{
|
|
void *input;
|
|
void **output;
|
|
OS_Handle semaphore;
|
|
U64 *completion_counter;
|
|
U64 *working_counter;
|
|
U64 endt_us;
|
|
ASYNC_Priority priority;
|
|
};
|
|
|
|
typedef struct ASYNC_Work ASYNC_Work;
|
|
struct ASYNC_Work
|
|
{
|
|
ASYNC_WorkFunctionType *work_function;
|
|
void *input;
|
|
void **output;
|
|
OS_Handle semaphore;
|
|
U64 *completion_counter;
|
|
U64 *working_counter;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Task-Based Work Types
|
|
|
|
typedef struct ASYNC_Task ASYNC_Task;
|
|
struct ASYNC_Task
|
|
{
|
|
OS_Handle semaphore;
|
|
void *output;
|
|
};
|
|
|
|
typedef struct ASYNC_TaskNode ASYNC_TaskNode;
|
|
struct ASYNC_TaskNode
|
|
{
|
|
ASYNC_TaskNode *next;
|
|
ASYNC_Task *v;
|
|
};
|
|
|
|
typedef struct ASYNC_TaskList ASYNC_TaskList;
|
|
struct ASYNC_TaskList
|
|
{
|
|
ASYNC_TaskNode *first;
|
|
ASYNC_TaskNode *last;
|
|
U64 count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Root (Per-Worker-Thread Arena Bundle)
|
|
|
|
typedef struct ASYNC_Root ASYNC_Root;
|
|
struct ASYNC_Root
|
|
{
|
|
Arena **arenas;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Shared State Bundle
|
|
|
|
typedef struct ASYNC_Ring ASYNC_Ring;
|
|
struct ASYNC_Ring
|
|
{
|
|
U64 ring_size;
|
|
U8 *ring_base;
|
|
U64 ring_write_pos;
|
|
U64 ring_read_pos;
|
|
OS_Handle ring_mutex;
|
|
OS_Handle ring_cv;
|
|
};
|
|
|
|
typedef struct ASYNC_Shared ASYNC_Shared;
|
|
struct ASYNC_Shared
|
|
{
|
|
Arena *arena;
|
|
|
|
// rjf: user -> work thread ring buffers
|
|
ASYNC_Ring rings[ASYNC_Priority_COUNT];
|
|
OS_Handle ring_mutex;
|
|
OS_Handle ring_cv;
|
|
|
|
// rjf: work threads
|
|
OS_Handle *work_threads;
|
|
U64 work_threads_count;
|
|
U64 work_threads_live_count;
|
|
};
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Globals
|
|
|
|
thread_static B32 async_work_thread_depth = 0;
|
|
thread_static U64 async_work_thread_idx = 0;
|
|
global ASYNC_Shared *async_shared = 0;
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Top-Level Layer Initialization
|
|
|
|
internal void async_init(CmdLine *cmdline);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Top-Level Accessors
|
|
|
|
internal U64 async_thread_count(void);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Work Kickoffs
|
|
|
|
internal B32 async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params);
|
|
#define async_push_work(function, ...) async_push_work_((function), &(ASYNC_WorkParams){.endt_us = max_U64, .priority = ASYNC_Priority_High, __VA_ARGS__})
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Task-Based Work Helper
|
|
|
|
internal void async_task_list_push(Arena *arena, ASYNC_TaskList *list, ASYNC_Task *t);
|
|
internal ASYNC_Task *async_task_launch_(Arena *arena, ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params);
|
|
#define async_task_launch(arena, work_function, ...) async_task_launch_((arena), (work_function), &(ASYNC_WorkParams){.endt_us = max_U64, __VA_ARGS__})
|
|
internal void *async_task_join(ASYNC_Task *task);
|
|
#define async_task_join_struct(task, T) (T *)async_task_join(task)
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Work Execution
|
|
|
|
internal ASYNC_Work async_pop_work(void);
|
|
internal void async_execute_work(ASYNC_Work work);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Root Allocation/Deallocation
|
|
|
|
internal ASYNC_Root *async_root_alloc(void);
|
|
internal void async_root_release(ASYNC_Root *root);
|
|
internal Arena *async_root_thread_arena(ASYNC_Root *root);
|
|
|
|
////////////////////////////////
|
|
//~ rjf: Work Thread Entry Point
|
|
|
|
internal void async_work_thread__entry_point(void *p);
|
|
|
|
#endif // ASYNC_H
|