add SYS_PRIORITY_INHERIT

This commit is contained in:
jacob 2025-07-06 18:06:25 -05:00
parent a397458c72
commit 2b08223472
9 changed files with 65 additions and 69 deletions

View File

@ -199,6 +199,7 @@ INTERNAL struct app_arg_list parse_args(struct arena *arena, struct string args_
void sys_app_entry(struct string args_str) void sys_app_entry(struct string args_str)
{ {
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
snc_counter_add(&G.exit_fence, 1);
struct app_arg_list args = parse_args(scratch.arena, args_str); struct app_arg_list args = parse_args(scratch.arena, args_str);
struct string logfile_name = LIT("log.log"); struct string logfile_name = LIT("log.log");
@ -315,7 +316,7 @@ void sys_app_entry(struct string args_str)
sys_window_show(window); sys_window_show(window);
/* Wait for app_exit() */ /* Wait for app_exit() */
snc_counter_wait_gtz(&G.exit_fence); snc_counter_wait(&G.exit_fence);
/* Run exit callbacks */ /* Run exit callbacks */
/* FIXME: Only wait on shutdown for a certain period of time before /* FIXME: Only wait on shutdown for a certain period of time before
@ -358,5 +359,5 @@ void sys_app_entry(struct string args_str)
void app_exit(void) void app_exit(void)
{ {
snc_counter_add(&G.exit_fence, 1); snc_counter_add(&G.exit_fence, -1);
} }

View File

@ -107,9 +107,6 @@ u64 asset_cache_hash(struct string key)
struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch) struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch)
{ {
struct asset *asset = NULL; struct asset *asset = NULL;
if (is_first_touch) {
*is_first_touch = false;
}
/* Lookup */ /* Lookup */
{ {
@ -119,7 +116,11 @@ struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch
} }
/* Insert if not found */ /* Insert if not found */
if (!asset->hash) { if (asset->hash) {
if (is_first_touch) {
*is_first_touch = false;
}
} else {
struct snc_lock lock = snc_lock_e(&G.lookup_mutex); struct snc_lock lock = snc_lock_e(&G.lookup_mutex);
/* Re-check asset presence in case it was inserted since lock */ /* Re-check asset presence in case it was inserted since lock */
@ -143,6 +144,7 @@ struct asset *asset_cache_touch(struct string key, u64 hash, b32 *is_first_touch
.hash = hash, .hash = hash,
.key = key_stored .key = key_stored
}; };
snc_counter_add(&asset->counter, 1);
if (is_first_touch) { if (is_first_touch) {
*is_first_touch = true; *is_first_touch = true;
} }
@ -172,7 +174,7 @@ void asset_cache_mark_ready(struct asset *asset, void *store_data)
{ {
asset->store_data = store_data; asset->store_data = store_data;
asset->status = ASSET_STATUS_READY; asset->status = ASSET_STATUS_READY;
snc_counter_add(&asset->counter, 1); snc_counter_add(&asset->counter, -1);
} }
/* ========================== * /* ========================== *
@ -181,7 +183,7 @@ void asset_cache_mark_ready(struct asset *asset, void *store_data)
void asset_cache_wait(struct asset *asset) void asset_cache_wait(struct asset *asset)
{ {
snc_counter_wait_gtz(&asset->counter); snc_counter_wait(&asset->counter);
} }
/* ========================== * /* ========================== *

View File

@ -920,8 +920,8 @@ INTERNAL SYS_JOB_DEF(pipeline_init_job, job)
struct shader_compile_job_param *params[] = { &vs, &ps }; struct shader_compile_job_param *params[] = { &vs, &ps };
struct shader_compile_job_sig comp_sig = { .params = params }; struct shader_compile_job_sig comp_sig = { .params = params };
struct snc_counter counter = ZI; struct snc_counter counter = ZI;
sys_run(countof(params), shader_compile_job, &comp_sig, SYS_PRIORITY_HIGH, &counter); sys_run(countof(params), shader_compile_job, &comp_sig, SYS_PRIORITY_INHERIT, &counter);
snc_counter_wait_ltez(&counter); snc_counter_wait(&counter);
success = vs.success && ps.success; success = vs.success && ps.success;
} }
@ -1114,8 +1114,8 @@ INTERNAL void pipeline_alloc(u64 num_pipelines, struct pipeline_desc *descs_in,
__prof; __prof;
struct pipeline_init_job_sig sig = { .descs_in = descs_in, .pipelines_out = pipelines_out }; struct pipeline_init_job_sig sig = { .descs_in = descs_in, .pipelines_out = pipelines_out };
struct snc_counter counter = ZI; struct snc_counter counter = ZI;
sys_run(num_pipelines, pipeline_init_job, &sig, SYS_PRIORITY_HIGH, &counter); sys_run(num_pipelines, pipeline_init_job, &sig, SYS_PRIORITY_INHERIT, &counter);
snc_counter_wait_ltez(&counter); snc_counter_wait(&counter);
} }
INTERNAL void pipeline_release_now(struct pipeline *pipeline) INTERNAL void pipeline_release_now(struct pipeline *pipeline)

View File

@ -287,7 +287,7 @@ INTERNAL SYS_THREAD_DEF(resource_watch_dispatcher_thread_entry_point, _)
sig.callbacks = callbacks; sig.callbacks = callbacks;
struct snc_counter counter = ZI; struct snc_counter counter = ZI;
sys_run(num_callbacks, resource_watch_callback_job, &sig, SYS_PRIORITY_BACKGROUND, &counter); sys_run(num_callbacks, resource_watch_callback_job, &sig, SYS_PRIORITY_BACKGROUND, &counter);
snc_counter_wait_ltez(&counter); snc_counter_wait(&counter);
} }
} }
} }

View File

@ -129,16 +129,16 @@ void snc_cv_broadcast(struct snc_cv *cv)
* Counter * Counter
* ========================== */ * ========================== */
void snc_counter_add(struct snc_counter *counter, i64 amount) void snc_counter_add(struct snc_counter *counter, i64 x)
{ {
i64 old_v = atomic_i64_fetch_add(&counter->v, amount); i64 old_v = atomic_i64_fetch_add(&counter->v, x);
i64 new_v = old_v + amount; i64 new_v = old_v + x;
if ((old_v > 0 && new_v <= 0) || (old_v <= 0 && new_v > 0)) { if (old_v > 0 && new_v <= 0) {
sys_wake_all(&counter->v); sys_wake_all(&counter->v);
} }
} }
void snc_counter_wait_ltez(struct snc_counter *counter) void snc_counter_wait(struct snc_counter *counter)
{ {
i64 v = atomic_i64_fetch(&counter->v); i64 v = atomic_i64_fetch(&counter->v);
while (v > 0) { while (v > 0) {
@ -146,12 +146,3 @@ void snc_counter_wait_ltez(struct snc_counter *counter)
v = atomic_i64_fetch(&counter->v); v = atomic_i64_fetch(&counter->v);
} }
} }
void snc_counter_wait_gtz(struct snc_counter *counter)
{
i64 v = atomic_i64_fetch(&counter->v);
while (v <= 0) {
sys_wait(&counter->v, &v, sizeof(v));
v = atomic_i64_fetch(&counter->v);
}
}

View File

@ -51,8 +51,7 @@ struct snc_counter {
struct atomic_i64 v; struct atomic_i64 v;
}; };
void snc_counter_add(struct snc_counter *counter, i64 amount); void snc_counter_add(struct snc_counter *counter, i64 x);
void snc_counter_wait_ltez(struct snc_counter *counter); void snc_counter_wait(struct snc_counter *counter);
void snc_counter_wait_gtz(struct snc_counter *counter);
#endif #endif

View File

@ -1374,7 +1374,7 @@ INTERNAL SYS_THREAD_DEF(sprite_evictor_scheduler_thread_entry_point, arg)
while (!G.evictor_scheduler_shutdown) { while (!G.evictor_scheduler_shutdown) {
struct snc_counter counter = ZI; struct snc_counter counter = ZI;
sys_run(1, sprite_evictor_job, NULL, SYS_PRIORITY_BACKGROUND, &counter); sys_run(1, sprite_evictor_job, NULL, SYS_PRIORITY_BACKGROUND, &counter);
snc_counter_wait_ltez(&counter); snc_counter_wait(&counter);
/* FIXME: Enable this */ /* FIXME: Enable this */
#if 0 #if 0
snc_cv_wait_time(G.evictor_scheduler_shutdown_cv, &evictor_lock, SECONDS_FROM_NS(EVICTOR_CYCLE_INTERVAL_NS)); snc_cv_wait_time(G.evictor_scheduler_shutdown_cv, &evictor_lock, SECONDS_FROM_NS(EVICTOR_CYCLE_INTERVAL_NS));

View File

@ -459,13 +459,14 @@ void sys_wake_all(void *addr);
#define SYS_MAX_FIBERS 4096 #define SYS_MAX_FIBERS 4096
i32 sys_current_fiber_id(void); i16 sys_current_fiber_id(void);
/* ========================== * /* ========================== *
* Job * Job
* ========================== */ * ========================== */
enum sys_priority { enum sys_priority {
SYS_PRIORITY_INHERIT = -1,
SYS_PRIORITY_HIGH = 0, SYS_PRIORITY_HIGH = 0,
SYS_PRIORITY_NORMAL = 1, SYS_PRIORITY_NORMAL = 1,
SYS_PRIORITY_BACKGROUND = 2, SYS_PRIORITY_BACKGROUND = 2,
@ -494,7 +495,7 @@ struct sys_scratch_ctx {
struct arena *arenas[SYS_SCRATCH_ARENAS_PER_CTX]; struct arena *arenas[SYS_SCRATCH_ARENAS_PER_CTX];
}; };
struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i32 fiber_id); struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 fiber_id);
/* ========================== * /* ========================== *
* App entry point * App entry point

View File

@ -101,7 +101,7 @@ struct win32_window {
}; };
#define NUM_WAIT_BINS 4096 #define NUM_WAIT_ADDR_BINS 4096
struct alignas(64) wait_list { struct alignas(64) wait_list {
/* =================================================== */ /* =================================================== */
@ -121,7 +121,7 @@ struct alignas(64) wait_list {
/* =================================================== */ /* =================================================== */
u8 _pad1[8]; /* 8 bytes (padding) */ u8 _pad1[8]; /* 8 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct wait_list) == 64); /* Assume wait_list fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct wait_list) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct wait_list) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct wait_list) == 64); /* Avoid false sharing */
struct alignas(64) wait_bin { struct alignas(64) wait_bin {
@ -139,12 +139,13 @@ struct alignas(64) wait_bin {
/* =================================================== */ /* =================================================== */
u8 _pad1[24]; /* 24 bytes (padding) */ u8 _pad1[24]; /* 24 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct wait_bin) == 64); /* Assume wait_bin fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct wait_bin) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct wait_bin) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct wait_bin) == 64); /* Avoid false sharing */
struct alignas(64) yielder { struct alignas(64) yielder {
/* =================================================== */ /* =================================================== */
i32 fiber_id; /* 4 bytes */ i16 fiber_id; /* 2 bytes */
u8 _pad0[2]; /* 2 bytes (padding) */
i32 job_queue_kind; /* 4 bytes */ i32 job_queue_kind; /* 4 bytes */
/* =================================================== */ /* =================================================== */
sys_job_func *job_func; /* 8 bytes */ sys_job_func *job_func; /* 8 bytes */
@ -158,11 +159,11 @@ struct alignas(64) yielder {
struct yielder *prev; /* 8 bytes */ struct yielder *prev; /* 8 bytes */
/* =================================================== */ /* =================================================== */
i32 job_id; /* 4 bytes */ i32 job_id; /* 4 bytes */
u8 _pad0[4]; /* 4 bytes (padding) */ u8 _pad1[4]; /* 4 bytes (padding) */
/* =================================================== */ /* =================================================== */
u8 _pad1[8]; /* 8 bytes (padding) */ u8 _pad2[8]; /* 8 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct yielder) == 64); /* Assume yielder fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct yielder) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct yielder) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct yielder) == 64); /* Avoid false sharing */
@ -175,7 +176,7 @@ struct alignas(64) counter {
/* =================================================== */ /* =================================================== */
u8 _pad[48]; /* 56 bytes (padding) */ u8 _pad[48]; /* 56 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct counter) == 64); /* Assume counter fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct counter) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct counter) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct counter) == 64); /* Avoid false sharing */
@ -211,8 +212,9 @@ struct alignas(64) fiber {
/* =================================================== */ /* =================================================== */
char *name_cstr; /* 8 bytes */ char *name_cstr; /* 8 bytes */
/* =================================================== */ /* =================================================== */
i32 id; /* 4 bytes */ i16 id; /* 2 bytes */
i32 parent_id; /* 4 bytes */ i16 parent_id; /* 2 bytes */
u8 _pad0[4]; /* 4 bytes (padding) */
/* =================================================== */ /* =================================================== */
void *addr; /* 8 bytes */ void *addr; /* 8 bytes */
/* =================================================== */ /* =================================================== */
@ -225,10 +227,11 @@ struct alignas(64) fiber {
/* =================================================== */ /* =================================================== */
struct yield_param *yield_param; /* 8 bytes */ struct yield_param *yield_param; /* 8 bytes */
/* =================================================== */ /* =================================================== */
u8 _pad0[8]; /* 8 bytes (padding) */ u8 _pad1[8]; /* 8 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct fiber) == 64); /* Assume fiber fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct fiber) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct fiber) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct fiber) == 64); /* Avoid false sharing */
STATIC_ASSERT(SYS_MAX_FIBERS < I16_MAX); /* Max fibers should fit in fiber id */
struct alignas(64) fiber_ctx { struct alignas(64) fiber_ctx {
/* ==================================================== */ /* ==================================================== */
@ -244,7 +247,7 @@ struct alignas(64) fiber_ctx {
/* ==================================================== */ /* ==================================================== */
u8 _pad4[8]; /* 8 bytes (padding) */ u8 _pad4[8]; /* 8 bytes (padding) */
}; };
STATIC_ASSERT(sizeof(struct fiber_ctx) == 64); /* Assume ctx fits in one cache line (increase if necessary) */ STATIC_ASSERT(sizeof(struct fiber_ctx) == 64); /* Padding validation (increase if necessary) */
STATIC_ASSERT(alignof(struct fiber_ctx) == 64); /* Avoid false sharing */ STATIC_ASSERT(alignof(struct fiber_ctx) == 64); /* Avoid false sharing */
@ -264,7 +267,7 @@ struct job_info {
void *sig; void *sig;
struct snc_counter *counter; struct snc_counter *counter;
i32 fiber_id; /* If the job is being resumed from a yield */ i16 fiber_id; /* If the job is being resumed from a yield */
struct job_info *next; struct job_info *next;
}; };
@ -340,11 +343,11 @@ GLOBAL struct {
struct arena *wait_lists_arena; struct arena *wait_lists_arena;
/* Wait table */ /* Wait table */
struct wait_bin wait_bins[NUM_WAIT_BINS]; struct wait_bin wait_bins[NUM_WAIT_ADDR_BINS];
/* Fibers */ /* Fibers */
i32 num_fibers; i16 num_fibers;
i32 first_free_fiber_id; i16 first_free_fiber_id;
struct arena *fiber_names_arena; struct arena *fiber_names_arena;
struct atomic_i32 fibers_lock; /* TODO: Prevent false sharing */ struct atomic_i32 fibers_lock; /* TODO: Prevent false sharing */
struct fiber fibers[SYS_MAX_FIBERS]; struct fiber fibers[SYS_MAX_FIBERS];
@ -365,7 +368,7 @@ GLOBAL struct {
INTERNAL struct fiber *fiber_from_id(i32 id); INTERNAL struct fiber *fiber_from_id(i16 id);
INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber); INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber);
@ -394,7 +397,7 @@ void sys_wait(void *addr, void *cmp, u32 size)
WaitOnAddress(addr, cmp, size, INFINITE); WaitOnAddress(addr, cmp, size, INFINITE);
#else #else
struct fiber *fiber = fiber_from_id(sys_current_fiber_id()); struct fiber *fiber = fiber_from_id(sys_current_fiber_id());
i32 parent_fiber_id = fiber->parent_id; i16 parent_fiber_id = fiber->parent_id;
/* Yield if job fiber, otherwise fall back to windows blocking function */ /* Yield if job fiber, otherwise fall back to windows blocking function */
if (parent_fiber_id > 0) { if (parent_fiber_id > 0) {
/* Yield if job fiber */ /* Yield if job fiber */
@ -422,7 +425,7 @@ void sys_wake_single(void *addr)
void sys_wake_all(void *addr) void sys_wake_all(void *addr)
{ {
u64 wait_bin_index = (u64)addr % NUM_WAIT_BINS; u64 wait_bin_index = (u64)addr % NUM_WAIT_ADDR_BINS;
struct wait_bin *bin = &G.wait_bins[wait_bin_index]; struct wait_bin *bin = &G.wait_bins[wait_bin_index];
while (atomic_i32_fetch_test_set(&bin->lock, 0, 1) != 0) ix_pause(); while (atomic_i32_fetch_test_set(&bin->lock, 0, 1) != 0) ix_pause();
@ -514,7 +517,7 @@ INTERNAL void job_fiber_entry(void *id_ptr);
INTERNAL struct fiber *fiber_alloc(enum fiber_kind kind) INTERNAL struct fiber *fiber_alloc(enum fiber_kind kind)
{ {
i32 fiber_id = 0; i16 fiber_id = 0;
struct fiber *fiber = NULL; struct fiber *fiber = NULL;
char *new_name_cstr = NULL; char *new_name_cstr = NULL;
{ {
@ -583,7 +586,7 @@ INTERNAL struct fiber *fiber_alloc(enum fiber_kind kind)
return fiber; return fiber;
} }
INTERNAL void fiber_release(struct fiber *fiber, i32 fiber_id) INTERNAL void fiber_release(struct fiber *fiber, i16 fiber_id)
{ {
while (atomic_i32_fetch_test_set(&G.fibers_lock, 0, 1) != 0) ix_pause(); while (atomic_i32_fetch_test_set(&G.fibers_lock, 0, 1) != 0) ix_pause();
{ {
@ -593,13 +596,13 @@ INTERNAL void fiber_release(struct fiber *fiber, i32 fiber_id)
atomic_i32_fetch_set(&G.fibers_lock, 0); atomic_i32_fetch_set(&G.fibers_lock, 0);
} }
INTERNAL struct fiber *fiber_from_id(i32 id) INTERNAL struct fiber *fiber_from_id(i16 id)
{ {
ASSERT(id >= 0 && id < SYS_MAX_FIBERS); ASSERT(id >= 0 && id < SYS_MAX_FIBERS);
return &G.fibers[id]; return &G.fibers[id];
} }
INTERNAL struct fiber_ctx *fiber_ctx_from_id(i32 id) INTERNAL struct fiber_ctx *fiber_ctx_from_id(i16 id)
{ {
ASSERT(id >= 0 && id < SYS_MAX_FIBERS); ASSERT(id >= 0 && id < SYS_MAX_FIBERS);
return &G.fiber_contexts[id]; return &G.fiber_contexts[id];
@ -609,9 +612,9 @@ INTERNAL struct fiber_ctx *fiber_ctx_from_id(i32 id)
* Test job * Test job
* ========================== */ * ========================== */
i32 sys_current_fiber_id(void) i16 sys_current_fiber_id(void)
{ {
return (i32)(i64)GetFiberData(); return (i16)(i64)GetFiberData();
} }
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_priority priority, struct snc_counter *counter) void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_priority priority, struct snc_counter *counter)
@ -682,7 +685,7 @@ INTERNAL void job_fiber_resume(struct fiber *fiber)
INTERNAL void job_fiber_entry(void *id_ptr) INTERNAL void job_fiber_entry(void *id_ptr)
{ {
i32 id = (i32)(i64)id_ptr; i16 id = (i32)(i64)id_ptr;
struct fiber *fiber = fiber_from_id(id); struct fiber *fiber = fiber_from_id(id);
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS + fiber->id); __prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS + fiber->id);
while (true) { while (true) {
@ -846,7 +849,7 @@ INTERNAL SYS_THREAD_DEF(worker_entry, worker_ctx_arg)
void *wait_cmp = yield.wait.cmp; void *wait_cmp = yield.wait.cmp;
u32 wait_size = yield.wait.size; u32 wait_size = yield.wait.size;
u64 wait_bin_index = (u64)wait_addr % NUM_WAIT_BINS; u64 wait_bin_index = (u64)wait_addr % NUM_WAIT_ADDR_BINS;
struct wait_bin *bin = &G.wait_bins[wait_bin_index]; struct wait_bin *bin = &G.wait_bins[wait_bin_index];
while (atomic_i32_fetch_test_set(&bin->lock, 0, 1) != 0) ix_pause(); while (atomic_i32_fetch_test_set(&bin->lock, 0, 1) != 0) ix_pause();
@ -986,7 +989,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
* Scratch context * Scratch context
* ========================== */ * ========================== */
struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i32 id) struct sys_scratch_ctx *sys_scratch_ctx_from_fiber_id(i16 id)
{ {
struct fiber_ctx *fiber_ctx = fiber_ctx_from_id(id); struct fiber_ctx *fiber_ctx = fiber_ctx_from_id(id);
struct sys_scratch_ctx *scratch_ctx = &fiber_ctx->scratch_ctx; struct sys_scratch_ctx *scratch_ctx = &fiber_ctx->scratch_ctx;
@ -1810,7 +1813,7 @@ INTERNAL SYS_THREAD_DEF(window_thread_entry_point, arg)
win32_update_window_from_system(window); win32_update_window_from_system(window);
BringWindowToTop(window->hwnd); BringWindowToTop(window->hwnd);
snc_counter_add(&window->ready_fence, 1); snc_counter_add(&window->ready_fence, -1);
while (!atomic_i32_fetch(&window->event_thread_shutdown)) { while (!atomic_i32_fetch(&window->event_thread_shutdown)) {
MSG msg = ZI; MSG msg = ZI;
@ -1902,10 +1905,9 @@ INTERNAL struct win32_window *win32_window_alloc(void)
MEMZERO_STRUCT(window); MEMZERO_STRUCT(window);
/* Start window thread for processing events */ /* Start window thread for processing events */
snc_counter_add(&window->ready_fence, 1);
window->event_thread = sys_thread_alloc(&window_thread_entry_point, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW); window->event_thread = sys_thread_alloc(&window_thread_entry_point, window, LIT("Window thread"), PROF_THREAD_GROUP_WINDOW);
snc_counter_wait(&window->ready_fence);
/* Wait for event thread to create actual window */
snc_counter_wait_gtz(&window->ready_fence);
return window; return window;
} }