sheet loader thread
This commit is contained in:
parent
925ef5a482
commit
35ded9dbac
@ -420,7 +420,7 @@ INTERNAL void game_update(void)
|
|||||||
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
|
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
|
||||||
u64 span_frame_offset = ent->animation_frame;
|
u64 span_frame_offset = ent->animation_frame;
|
||||||
|
|
||||||
struct sheet *sheet = sheet_from_tag_await(sheet_frame_scope, ent->sprite_sheet_tag);
|
struct sheet *sheet = sheet_from_tag_async(sheet_frame_scope, ent->sprite_sheet_tag);
|
||||||
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
|
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
|
||||||
u64 frame_index = span.start + span_frame_offset;
|
u64 frame_index = span.start + span_frame_offset;
|
||||||
|
|
||||||
|
|||||||
208
src/sheet.c
208
src/sheet.c
@ -10,6 +10,7 @@
|
|||||||
#include "work.h"
|
#include "work.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "thread_local.h"
|
#include "thread_local.h"
|
||||||
|
#include "app.h"
|
||||||
|
|
||||||
#define SHEET_ARENA_RESERVE MEGABYTE(64)
|
#define SHEET_ARENA_RESERVE MEGABYTE(64)
|
||||||
#define SHEET_LOOKUP_TABLE_BUCKET_RATIO 2.0
|
#define SHEET_LOOKUP_TABLE_BUCKET_RATIO 2.0
|
||||||
@ -18,26 +19,21 @@
|
|||||||
#define CACHE_BUCKETS_COUNT 256
|
#define CACHE_BUCKETS_COUNT 256
|
||||||
#define SCOPE_BUCKETS_COUNT 256
|
#define SCOPE_BUCKETS_COUNT 256
|
||||||
|
|
||||||
|
#define MAX_LOADER_THREADS 4
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Load cmd structs
|
* Load cmd structs
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct load_cmd {
|
struct load_cmd {
|
||||||
struct cache_node *node;
|
struct load_cmd *next;
|
||||||
|
struct load_cmd *next_free;
|
||||||
|
|
||||||
|
struct cache_node *cache_node;
|
||||||
struct sheet_tag tag;
|
struct sheet_tag tag;
|
||||||
u8 tag_path_buff[4096];
|
u8 tag_path_buff[4096];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct load_cmd_store {
|
|
||||||
struct arena arena;
|
|
||||||
struct sys_mutex mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct load_cmd_array {
|
|
||||||
u64 count;
|
|
||||||
struct load_cmd *cmds;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Cache structs
|
* Cache structs
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -83,11 +79,27 @@ struct sheet_scope_reference {
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
GLOBAL struct {
|
GLOBAL struct {
|
||||||
struct load_cmd_store load_cmd_store;
|
/* Cache */
|
||||||
struct cache cache;
|
struct cache cache;
|
||||||
|
|
||||||
|
/* Load cmds */
|
||||||
|
b32 shutdown;
|
||||||
|
struct arena load_cmd_arena;
|
||||||
|
struct sys_mutex load_cmd_mutex;
|
||||||
|
struct sys_condition_variable load_cmd_or_shutdown_cv;
|
||||||
|
struct load_cmd *first_free_load_cmd;
|
||||||
|
struct load_cmd *first_load_cmd;
|
||||||
|
struct load_cmd *last_load_cmd;
|
||||||
|
|
||||||
|
/* Threads */
|
||||||
|
u64 loader_threads_count;
|
||||||
|
struct sys_thread loader_threads[MAX_LOADER_THREADS];
|
||||||
|
struct sys_thread evictor_thread;
|
||||||
} G = { 0 }, DEBUG_ALIAS(G, G_sheet);
|
} G = { 0 }, DEBUG_ALIAS(G, G_sheet);
|
||||||
|
|
||||||
GLOBAL READONLY struct sheet g_sheet_nil = { 0 };
|
GLOBAL READONLY struct sheet g_sheet_loading = {
|
||||||
|
.loading = true
|
||||||
|
};
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Thread local state
|
* Thread local state
|
||||||
@ -117,6 +129,9 @@ GLOBAL THREAD_LOCAL_VAR_DEF(tl_sheet_tctx, struct sheet_tctx, sheet_tctx_alloc,
|
|||||||
* Startup
|
* Startup
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sheet_shutdown);
|
||||||
|
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sheet_loader_thread_entry_point, arg);
|
||||||
|
|
||||||
struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
|
struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
|
||||||
struct asset_cache_startup_receipt *asset_cache_sr,
|
struct asset_cache_startup_receipt *asset_cache_sr,
|
||||||
struct resource_startup_receipt *resource_sr)
|
struct resource_startup_receipt *resource_sr)
|
||||||
@ -125,16 +140,52 @@ struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
|
|||||||
(UNUSED)asset_cache_sr;
|
(UNUSED)asset_cache_sr;
|
||||||
(UNUSED)resource_sr;
|
(UNUSED)resource_sr;
|
||||||
|
|
||||||
G.load_cmd_store.arena = arena_alloc(GIGABYTE(64));
|
|
||||||
G.load_cmd_store.mutex = sys_mutex_alloc();
|
|
||||||
|
|
||||||
G.cache.rw_mutex = sys_rw_mutex_alloc();
|
G.cache.rw_mutex = sys_rw_mutex_alloc();
|
||||||
G.cache.arena = arena_alloc(GIGABYTE(64));
|
G.cache.arena = arena_alloc(GIGABYTE(64));
|
||||||
G.cache.buckets = arena_push_array_zero(&G.cache.arena, struct cache_node *, CACHE_BUCKETS_COUNT);
|
G.cache.buckets = arena_push_array_zero(&G.cache.arena, struct cache_node *, CACHE_BUCKETS_COUNT);
|
||||||
|
|
||||||
|
G.load_cmd_arena = arena_alloc(GIGABYTE(64));
|
||||||
|
G.load_cmd_mutex = sys_mutex_alloc();
|
||||||
|
G.load_cmd_or_shutdown_cv = sys_condition_variable_alloc();
|
||||||
|
|
||||||
|
/* Startup threads */
|
||||||
|
{
|
||||||
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
G.loader_threads_count = clamp_i64(1, MAX_LOADER_THREADS, sys_num_logical_processors() - 1);
|
||||||
|
for (u64 i = 0; i < G.loader_threads_count; ++i) {
|
||||||
|
struct string thread_name = string_format(scratch.arena,
|
||||||
|
STR("[P0] Sheet loader thread %F"),
|
||||||
|
FMT_UINT(i));
|
||||||
|
G.loader_threads[i] = sys_thread_alloc(sheet_loader_thread_entry_point, NULL, thread_name);
|
||||||
|
}
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
//G.evictor_thread = sys_thread_alloc(sheet_evictor_thread_entry_point, NULL, STR("[P0] Sheet evictor thread"));
|
||||||
|
|
||||||
|
app_register_exit_callback(&sheet_shutdown);
|
||||||
|
|
||||||
return (struct sheet_startup_receipt) { 0 };
|
return (struct sheet_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(sheet_shutdown)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
|
||||||
|
/* Signal shutdown */
|
||||||
|
sys_mutex_lock(&G.load_cmd_mutex);
|
||||||
|
{
|
||||||
|
G.shutdown = true;
|
||||||
|
sys_condition_variable_broadcast(&G.load_cmd_or_shutdown_cv);
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&G.load_cmd_mutex);
|
||||||
|
|
||||||
|
/* Wait on threads */
|
||||||
|
for (u64 i = 0; i < G.loader_threads_count; ++i) {
|
||||||
|
sys_thread_wait_release(&G.loader_threads[i]);
|
||||||
|
}
|
||||||
|
//sys_thread_wait_release(&G.evictor_thread);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Tag
|
* Tag
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -163,7 +214,7 @@ struct sheet_tag sheet_tag_from_path(struct string path)
|
|||||||
{
|
{
|
||||||
struct sheet_tag res = { 0 };
|
struct sheet_tag res = { 0 };
|
||||||
res.hash = HASH_FNV64_SEED;
|
res.hash = HASH_FNV64_SEED;
|
||||||
res.hash = hash_fnv64(&res.hash, BUFFER_FROM_STRING(path));
|
res.hash = hash_fnv64(res.hash, BUFFER_FROM_STRING(path));
|
||||||
res.path = path;
|
res.path = path;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -175,44 +226,6 @@ INTERNAL struct sheet_tag sheet_tag_copy(struct arena *arena, struct sheet_tag s
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Load cmd
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
INTERNAL void push_load_cmd(struct cache_node *n, struct sheet_tag tag)
|
|
||||||
{
|
|
||||||
sys_mutex_lock(&G.load_cmd_store.mutex);
|
|
||||||
{
|
|
||||||
struct load_cmd *cmd = arena_push(&G.load_cmd_store.arena, struct load_cmd);
|
|
||||||
cmd->node = n;
|
|
||||||
cmd->tag = tag;
|
|
||||||
{
|
|
||||||
u64 copy_len = min_u64(tag.path.len, ARRAY_COUNT(cmd->tag_path_text));
|
|
||||||
cmd->tag.path.text = cmd->path_text_dest;
|
|
||||||
MEMCPY(cmd->tag.path.text, tag.path.text, copy_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sys_mutex_unlock(&G.load_cmd_store.mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL struct load_cmd_array pop_load_cmds(struct arena *arena)
|
|
||||||
{
|
|
||||||
struct load_cmd_array array = { 0 };
|
|
||||||
sys_mutex_lock(&G.load_cmd_store.mutex);
|
|
||||||
{
|
|
||||||
struct buffer cmds_buff = arena_to_buffer(&G.load_cmd_store.arena);
|
|
||||||
arena_align(arena, alignof(struct load_cmd));
|
|
||||||
array.cmds = (struct load_cmd *)arena_push_array(arena, u8, cmds_buff.size);
|
|
||||||
array.count = cmds_buff.size / sizeof(struct load_cmd);
|
|
||||||
MEMCPY(array.cmds, cmds_buff.data, cmds_buff.size);
|
|
||||||
arena_reset(&G.load_cmd_store.arena);
|
|
||||||
}
|
|
||||||
sys_mutex_unlock(&G.load_cmd_store.mutex);
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Load
|
* Load
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -369,8 +382,6 @@ void sheet_scope_end(struct sheet_scope *scope)
|
|||||||
* Cache interface
|
* Cache interface
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* FIXME: locking */
|
|
||||||
|
|
||||||
INTERNAL struct cache_node *node_lookup_touch(struct sheet_scope *scope, struct sheet_tag tag)
|
INTERNAL struct cache_node *node_lookup_touch(struct sheet_scope *scope, struct sheet_tag tag)
|
||||||
{
|
{
|
||||||
struct cache_node **n_next = NULL;
|
struct cache_node **n_next = NULL;
|
||||||
@ -418,7 +429,7 @@ INTERNAL struct cache_node *node_lookup_touch(struct sheet_scope *scope, struct
|
|||||||
|
|
||||||
INTERNAL struct sheet *sheet_from_tag_internal(struct sheet_scope *scope, struct sheet_tag tag, b32 await)
|
INTERNAL struct sheet *sheet_from_tag_internal(struct sheet_scope *scope, struct sheet_tag tag, b32 await)
|
||||||
{
|
{
|
||||||
struct sheet *res = &g_sheet_nil;
|
struct sheet *res = &g_sheet_loading;
|
||||||
|
|
||||||
struct cache_node *n = node_lookup_touch(scope, tag);
|
struct cache_node *n = node_lookup_touch(scope, tag);
|
||||||
|
|
||||||
@ -427,13 +438,39 @@ INTERNAL struct sheet *sheet_from_tag_internal(struct sheet_scope *scope, struct
|
|||||||
res = &n->sheet;
|
res = &n->sheet;
|
||||||
} else if (state == CACHE_NODE_STATE_NONE) {
|
} else if (state == CACHE_NODE_STATE_NONE) {
|
||||||
if (atomic_u32_eval_compare_exchange(&n->state, CACHE_NODE_STATE_NONE, CACHE_NODE_STATE_QUEUED) == CACHE_NODE_STATE_NONE) {
|
if (atomic_u32_eval_compare_exchange(&n->state, CACHE_NODE_STATE_NONE, CACHE_NODE_STATE_QUEUED) == CACHE_NODE_STATE_NONE) {
|
||||||
|
/* Node is new, load sheet */
|
||||||
if (await) {
|
if (await) {
|
||||||
sheet_load(n, tag);
|
sheet_load(n, tag);
|
||||||
res = &n->sheet;
|
res = &n->sheet;
|
||||||
} else {
|
} else {
|
||||||
/* TODO */
|
sys_mutex_lock(&G.load_cmd_mutex);
|
||||||
/* Node is new, push load command. */
|
{
|
||||||
//push_load_cmd(n, tag);
|
/* Allocate cmd */
|
||||||
|
struct load_cmd *cmd = NULL;
|
||||||
|
if (G.first_free_load_cmd) {
|
||||||
|
cmd = G.first_free_load_cmd;
|
||||||
|
G.first_free_load_cmd = cmd->next_free;
|
||||||
|
} else {
|
||||||
|
cmd = arena_push(&G.load_cmd_arena, struct load_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize cmd */
|
||||||
|
cmd->cache_node = n;
|
||||||
|
cmd->tag = tag;
|
||||||
|
{
|
||||||
|
u64 copy_len = min_u64(tag.path.len, ARRAY_COUNT(cmd->tag_path_buff));
|
||||||
|
cmd->tag.path.text = cmd->tag_path_buff;
|
||||||
|
MEMCPY(cmd->tag.path.text, tag.path.text, copy_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add cmd to queue */
|
||||||
|
*(G.last_load_cmd ? &G.last_load_cmd->next : &G.first_load_cmd) = cmd;
|
||||||
|
G.last_load_cmd = cmd;
|
||||||
|
|
||||||
|
/* Signal work ready */
|
||||||
|
sys_condition_variable_signal(&G.load_cmd_or_shutdown_cv);
|
||||||
|
}
|
||||||
|
sys_mutex_unlock(&G.load_cmd_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -470,6 +507,55 @@ struct sheet_span sheet_get_span(struct sheet *sheet, struct string name)
|
|||||||
|
|
||||||
struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index)
|
struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index)
|
||||||
{
|
{
|
||||||
|
if (sheet->frames_count > 0) {
|
||||||
index = min_u32(sheet->frames_count - 1, index);
|
index = min_u32(sheet->frames_count - 1, index);
|
||||||
return sheet->frames[index];
|
return sheet->frames[index];
|
||||||
|
} else {
|
||||||
|
return (struct sheet_frame) {
|
||||||
|
.index = 0,
|
||||||
|
.duration = 0.1,
|
||||||
|
.clip = CLIP_ALL
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Loader thread
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sheet_loader_thread_entry_point, arg)
|
||||||
|
{
|
||||||
|
(UNUSED)arg;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
sys_mutex_lock(&G.load_cmd_mutex);
|
||||||
|
|
||||||
|
if (G.shutdown) {
|
||||||
|
/* Thread shutdown */
|
||||||
|
sys_mutex_unlock(&G.load_cmd_mutex);
|
||||||
|
break;
|
||||||
|
} else if (!G.first_load_cmd) {
|
||||||
|
/* Wait for work */
|
||||||
|
sys_condition_variable_wait(&G.load_cmd_or_shutdown_cv, &G.load_cmd_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G.first_load_cmd) {
|
||||||
|
/* Pull cmd from queue */
|
||||||
|
struct load_cmd *cmd = G.first_load_cmd;
|
||||||
|
G.first_load_cmd = cmd->next;
|
||||||
|
|
||||||
|
/* Do work (temporarily unlock) */
|
||||||
|
sys_mutex_unlock(&G.load_cmd_mutex);
|
||||||
|
{
|
||||||
|
sheet_load(cmd->cache_node, cmd->tag);
|
||||||
|
}
|
||||||
|
sys_mutex_lock(&G.load_cmd_mutex);
|
||||||
|
|
||||||
|
/* Free cmd */
|
||||||
|
cmd->next_free = G.first_free_load_cmd;
|
||||||
|
G.first_free_load_cmd = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_mutex_unlock(&G.load_cmd_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ struct sheet_tag {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sheet {
|
struct sheet {
|
||||||
|
b32 loading;
|
||||||
struct v2 image_size;
|
struct v2 image_size;
|
||||||
struct v2 frame_size;
|
struct v2 frame_size;
|
||||||
u32 frames_count;
|
u32 frames_count;
|
||||||
|
|||||||
@ -429,7 +429,7 @@ struct string string_formatv(struct arena *arena, struct string fmt, va_list arg
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FMT_TYPE_FLOAT: {
|
case FMT_TYPE_FLOAT: {
|
||||||
parsed_str = string_from_float(arena, arg.value.f, arg.precision);
|
parsed_str = string_from_float(arena, arg.value.f.val, arg.value.f.precision);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FMT_TYPE_END: {
|
case FMT_TYPE_END: {
|
||||||
|
|||||||
@ -60,9 +60,11 @@ struct fmt_arg {
|
|||||||
u64 uint;
|
u64 uint;
|
||||||
i64 sint;
|
i64 sint;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
f64 f;
|
struct {
|
||||||
} value;
|
f64 val;
|
||||||
u32 precision;
|
u32 precision;
|
||||||
|
} f;
|
||||||
|
} value;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FMT_END (struct fmt_arg) {.type = FMT_TYPE_END}
|
#define FMT_END (struct fmt_arg) {.type = FMT_TYPE_END}
|
||||||
@ -74,7 +76,7 @@ struct fmt_arg {
|
|||||||
#define FMT_HEX(v) (struct fmt_arg) {.type = FMT_TYPE_HEX, .value.uint = (v)}
|
#define FMT_HEX(v) (struct fmt_arg) {.type = FMT_TYPE_HEX, .value.uint = (v)}
|
||||||
#define FMT_PTR(v) (struct fmt_arg) {.type = FMT_TYPE_PTR, .value.ptr = (v)}
|
#define FMT_PTR(v) (struct fmt_arg) {.type = FMT_TYPE_PTR, .value.ptr = (v)}
|
||||||
#define FMT_FLOAT(v) FMT_FLOAT_P(v, DEFAULT_FMT_PRECISION)
|
#define FMT_FLOAT(v) FMT_FLOAT_P(v, DEFAULT_FMT_PRECISION)
|
||||||
#define FMT_FLOAT_P(v, p) (struct fmt_arg) {.type = FMT_TYPE_FLOAT, .value.f = (v), .precision = p}
|
#define FMT_FLOAT_P(v, p) (struct fmt_arg) {.type = FMT_TYPE_FLOAT, .value.f.val = (v), .value.f.precision = p}
|
||||||
|
|
||||||
#define string_format(arena, fmt, ...) _string_format(arena, fmt, __VA_ARGS__, FMT_END)
|
#define string_format(arena, fmt, ...) _string_format(arena, fmt, __VA_ARGS__, FMT_END)
|
||||||
struct string _string_format(struct arena *arena, struct string fmt, ...);
|
struct string _string_format(struct arena *arena, struct string fmt, ...);
|
||||||
|
|||||||
@ -771,7 +771,7 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
{
|
{
|
||||||
struct sheet_tag sheet_tag = ent->sprite_sheet_tag;
|
struct sheet_tag sheet_tag = ent->sprite_sheet_tag;
|
||||||
struct sheet *sheet = sheet_from_tag_await(sheet_frame_scope, sheet_tag);
|
struct sheet *sheet = sheet_from_tag_async(sheet_frame_scope, sheet_tag);
|
||||||
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
|
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
|
||||||
|
|
||||||
u64 frame_index = span.start + ent->animation_frame;
|
u64 frame_index = span.start + ent->animation_frame;
|
||||||
|
|||||||
@ -400,11 +400,13 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(worker_thread_entry_point, thread_data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait */
|
if (!G.scheduled_work_head) {
|
||||||
|
/* Wait for work */
|
||||||
sys_condition_variable_wait(&G.cv, &G.mutex);
|
sys_condition_variable_wait(&G.cv, &G.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do work from top */
|
/* Do work from top */
|
||||||
while (G.scheduled_work_head) {
|
if (G.scheduled_work_head) {
|
||||||
struct work *work = G.scheduled_work_head;
|
struct work *work = G.scheduled_work_head;
|
||||||
if (work) {
|
if (work) {
|
||||||
__profscope(work_pool_task);
|
__profscope(work_pool_task);
|
||||||
@ -414,7 +416,6 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(worker_thread_entry_point, thread_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sys_mutex_unlock(&G.mutex);
|
sys_mutex_unlock(&G.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user