aggregate base layer state
This commit is contained in:
parent
ac8a4cf6c2
commit
476d154beb
@ -748,6 +748,7 @@
|
||||
i64 TimeNs(void);
|
||||
void TrueRand(String buffer);
|
||||
CpuTopologyInfo GetCpuTopologyInfo(void);
|
||||
void SleepSeconds(f64 seconds);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
ThreadLocal ThreadArenasCtx t_arena_ctx = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Arena management
|
||||
|
||||
@ -20,7 +18,7 @@ Arena *AcquireArena(u64 reserve)
|
||||
Panic(Lit("Failed to reserve memory"));
|
||||
}
|
||||
u64 reserved = reserve;
|
||||
AddGstat(GSTAT_MEMORY_RESERVED, reserve);
|
||||
AddGstat(MemoryReserved, reserve);
|
||||
|
||||
/* Commit initial block */
|
||||
base = CommitMemory(base, ArenaBlockSize);
|
||||
@ -34,8 +32,8 @@ Arena *AcquireArena(u64 reserve)
|
||||
StaticAssert(sizeof(Arena) <= ArenaHeaderSize); /* Arena struct must fit in header */
|
||||
|
||||
AsanPoison(base + sizeof(Arena), ArenaBlockSize - sizeof(Arena));
|
||||
AddGstat(GSTAT_MEMORY_COMMITTED, ArenaBlockSize);
|
||||
AddGstat(GSTAT_NUM_ARENAS, 1);
|
||||
AddGstat(MemoryCommitted, ArenaBlockSize);
|
||||
AddGstat(NumArenas, 1);
|
||||
|
||||
/* Create & return arena header at beginning of block */
|
||||
Arena *arena = (Arena *)base;
|
||||
@ -48,9 +46,9 @@ Arena *AcquireArena(u64 reserve)
|
||||
void ReleaseArena(Arena *arena)
|
||||
{
|
||||
AsanUnpoison(arena, arena->committed + ArenaHeaderSize);
|
||||
AddGstat(GSTAT_MEMORY_COMMITTED, -(i64)(arena->committed - ArenaHeaderSize));
|
||||
AddGstat(GSTAT_MEMORY_RESERVED, -(i64)(arena->reserved));
|
||||
AddGstat(GSTAT_NUM_ARENAS, -1);
|
||||
AddGstat(MemoryCommitted, -(i64)(arena->committed - ArenaHeaderSize));
|
||||
AddGstat(MemoryReserved, -(i64)(arena->reserved));
|
||||
AddGstat(NumArenas, -1);
|
||||
ReleaseMemory(arena);
|
||||
}
|
||||
|
||||
@ -117,7 +115,7 @@ void *PushBytesNoZero(Arena *arena, u64 size, u64 align)
|
||||
Panic(Lit("Failed to commit new memory block: System may be out of memory"));
|
||||
}
|
||||
arena->committed += commit_bytes;
|
||||
AddGstat(GSTAT_MEMORY_COMMITTED, commit_bytes);
|
||||
AddGstat(MemoryCommitted, commit_bytes);
|
||||
AsanPoison(commit_address, commit_bytes);
|
||||
}
|
||||
|
||||
@ -200,15 +198,15 @@ void EndTempArena(TempArena temp)
|
||||
TempArena BeginScratch(Arena *potential_conflict)
|
||||
{
|
||||
/* This function is currently hard-coded for 2 thread-local scratch arenas */
|
||||
StaticAssert(ScratchArenasPerCtx == 2);
|
||||
StaticAssert(countof(Base_tl.arenas.scratch) == 2);
|
||||
|
||||
/* Use `BeginScratchNoConflict` if no conflicts are present */
|
||||
Assert(potential_conflict != 0);
|
||||
|
||||
Arena *scratch_arena = t_arena_ctx.scratch_arenas[0];
|
||||
Arena *scratch_arena = Base_tl.arenas.scratch[0];
|
||||
if (scratch_arena == potential_conflict)
|
||||
{
|
||||
scratch_arena = t_arena_ctx.scratch_arenas[1];
|
||||
scratch_arena = Base_tl.arenas.scratch[1];
|
||||
}
|
||||
TempArena temp = BeginTempArena(scratch_arena);
|
||||
return temp;
|
||||
@ -216,12 +214,11 @@ TempArena BeginScratch(Arena *potential_conflict)
|
||||
|
||||
TempArena BeginScratchNoConflict_(void)
|
||||
{
|
||||
Arena *scratch_arena = t_arena_ctx.scratch_arenas[0];
|
||||
Arena *scratch_arena = Base_tl.arenas.scratch[0];
|
||||
TempArena temp = BeginTempArena(scratch_arena);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void EndScratch(TempArena scratch_temp)
|
||||
{
|
||||
EndTempArena(scratch_temp);
|
||||
|
||||
@ -4,19 +4,6 @@
|
||||
#define ArenaHeaderSize 256
|
||||
#define ArenaBlockSize 16384
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
#define ScratchArenasPerCtx 2
|
||||
|
||||
Struct(ThreadArenasCtx)
|
||||
{
|
||||
Arena *perm_arena;
|
||||
Arena *scratch_arenas[ScratchArenasPerCtx];
|
||||
};
|
||||
|
||||
extern ThreadLocal ThreadArenasCtx t_arena_ctx;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Arena management
|
||||
|
||||
@ -65,7 +52,7 @@ void *ArenaFirst_(Arena *arena, u64 align);
|
||||
TempArena BeginTempArena(Arena *arena);
|
||||
void EndTempArena(TempArena temp);
|
||||
|
||||
#define PermArena() (t_arena_ctx.perm_arena)
|
||||
#define PermArena() (Base_tl.arenas.perm)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Scratch arena helpers
|
||||
@ -74,12 +61,12 @@ TempArena BeginScratch(Arena *potential_conflict);
|
||||
TempArena BeginScratchNoConflict_(void);
|
||||
void EndScratch(TempArena scratch_temp);
|
||||
|
||||
/* This macro declares an unused "arena" variable that will error if an existing "arena"
|
||||
* variable is present (due to shadowing). This is for catching obvious cases of
|
||||
* `BeginScratchNoConflict` getting called when an `arena` variable already
|
||||
* exists in the caller's scope. */
|
||||
/* This macro declares an unused "arena" variable that will produce a shadowing
|
||||
* warning variable is present (due to shadowing). This is for catching obvious
|
||||
* cases of `BeginScratchNoConflict` getting called when an `arena` variable
|
||||
* already exists in the caller's scope. */
|
||||
#define BeginScratchNoConflict() \
|
||||
BeginScratchNoConflict_(); \
|
||||
do { \
|
||||
u8 arena = 0; \
|
||||
BeginScratchNoConflict_(); \
|
||||
do { \
|
||||
u8 arena = 0; \
|
||||
} while (0)
|
||||
|
||||
@ -4,19 +4,75 @@
|
||||
void BootstrapAsync(void)
|
||||
{
|
||||
/* TODO: Dynamic lane counts */
|
||||
DispatchWave(Lit("Async"), 4, AsyncEntryPoint, 0);
|
||||
DispatchWave(Lit("Async"), 4, AsyncWorkerEntryPoint, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async ops
|
||||
|
||||
void OnAsyncTick(AsyncFunc *func)
|
||||
void OnAsyncTick(AsyncTickCallbackFunc *func)
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
|
||||
AsyncTickCallbackNode *n = PushStruct(perm, AsyncTickCallbackNode);
|
||||
n->callback.func = func;
|
||||
|
||||
Lock lock = LockE(&Base.async.mutex);
|
||||
{
|
||||
SllQueuePush(Base.async.first_callback_node, Base.async.last_callback_node, n);
|
||||
Base.async.callback_nodes_count += 1;
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async worker
|
||||
|
||||
void AsyncEntryPoint(WaveLaneCtx *lane)
|
||||
void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
|
||||
{
|
||||
/* Tick forever */
|
||||
for (;;)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
AsyncWorkerState *w = &Base.async.worker;
|
||||
|
||||
/* FIXME: Remove this */
|
||||
SleepSeconds(0.100);
|
||||
|
||||
//////////////////////////////
|
||||
//- Grab async functions
|
||||
|
||||
if (lane->idx == 0)
|
||||
{
|
||||
Lock lock = LockE(&Base.async.mutex);
|
||||
{
|
||||
w->callbacks_count = Base.async.callback_nodes_count;
|
||||
w->callbacks = PushStructsNoZero(scratch.arena, AsyncTickCallback, w->callbacks_count);
|
||||
u64 callback_idx = 0;
|
||||
for (AsyncTickCallbackNode *n = Base.async.first_callback_node; n; n = n->next)
|
||||
{
|
||||
w->callbacks[callback_idx] = n->callback;
|
||||
++callback_idx;
|
||||
}
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
|
||||
WaveSync(lane);
|
||||
|
||||
//////////////////////////////
|
||||
//- Run tick funcs
|
||||
|
||||
for (u64 callback_idx = 0; callback_idx < w->callbacks_count; ++callback_idx)
|
||||
{
|
||||
AsyncTickCallback *callback = &w->callbacks[callback_idx];
|
||||
callback->func(lane);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- End tick
|
||||
|
||||
WaveSync(lane);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,24 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async types
|
||||
|
||||
typedef void AsyncFunc(WaveLaneCtx *lane);
|
||||
typedef void AsyncTickCallbackFunc(WaveLaneCtx *lane);
|
||||
|
||||
Struct(AsyncTickCallback)
|
||||
{
|
||||
AsyncTickCallbackFunc *func;
|
||||
};
|
||||
|
||||
Struct(AsyncTickCallbackNode)
|
||||
{
|
||||
AsyncTickCallbackNode *next;
|
||||
AsyncTickCallback callback;
|
||||
};
|
||||
|
||||
Struct(AsyncWorkerState)
|
||||
{
|
||||
u64 callbacks_count;
|
||||
AsyncTickCallback *callbacks;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
@ -11,9 +28,9 @@ void BootstrapAsync(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async ops
|
||||
|
||||
void OnAsyncTick(AsyncFunc *func);
|
||||
void OnAsyncTick(AsyncTickCallbackFunc *func);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async worker
|
||||
|
||||
void AsyncEntryPoint(WaveLaneCtx *lane);
|
||||
void AsyncWorkerEntryPoint(WaveLaneCtx *lane);
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
SharedCmdlineState shared_cmdline_state = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
void BootstrapCmdline(void)
|
||||
{
|
||||
SharedCmdlineState *g = &shared_cmdline_state;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
StringList raw = GetRawCommandline();
|
||||
@ -54,19 +51,19 @@ void BootstrapCmdline(void)
|
||||
}
|
||||
|
||||
Arena *perm = PermArena();
|
||||
g->positional_args_count = tmp_positionals_count;
|
||||
g->positional_args = PushStructsNoZero(perm, String, tmp_positionals_count);
|
||||
CopyStructs(g->positional_args, tmp_positionals, tmp_positionals_count);
|
||||
Base.cmdline.positional_args_count = tmp_positionals_count;
|
||||
Base.cmdline.positional_args = PushStructsNoZero(perm, String, tmp_positionals_count);
|
||||
CopyStructs(Base.cmdline.positional_args, tmp_positionals, tmp_positionals_count);
|
||||
for (u64 i = 0; i < tmp_args_count; ++i)
|
||||
{
|
||||
CommandlineArg arg = tmp_args[i];
|
||||
CommandlineArgNode *n = PushStruct(perm, CommandlineArgNode);
|
||||
u64 hash = HashFnv64(Fnv64Basis, arg.name);
|
||||
u64 bin_idx = hash % CommandlineArgBinsCount;
|
||||
u64 bin_idx = hash % countof(Base.cmdline.arg_bins);
|
||||
n->arg = arg;
|
||||
n->hash = hash;
|
||||
n->next = g->arg_bins[bin_idx];
|
||||
g->arg_bins[bin_idx] = n;
|
||||
n->next = Base.cmdline.arg_bins[bin_idx];
|
||||
Base.cmdline.arg_bins[bin_idx] = n;
|
||||
}
|
||||
}
|
||||
EndScratch(scratch);
|
||||
@ -77,21 +74,19 @@ void BootstrapCmdline(void)
|
||||
|
||||
String StringFromCommandlineIdx(i32 idx)
|
||||
{
|
||||
SharedCmdlineState *g = &shared_cmdline_state;
|
||||
String result = ZI;
|
||||
if (idx < g->positional_args_count)
|
||||
if (idx < Base.cmdline.positional_args_count)
|
||||
{
|
||||
result = g->positional_args[idx];
|
||||
result = Base.cmdline.positional_args[idx];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CommandlineArg CommandlineArgFromName(String name)
|
||||
{
|
||||
SharedCmdlineState *g = &shared_cmdline_state;
|
||||
CommandlineArg result = ZI;
|
||||
u64 hash = HashFnv64(Fnv64Basis, name);
|
||||
for (CommandlineArgNode *n = g->arg_bins[hash % CommandlineArgBinsCount]; n; n = n->next)
|
||||
for (CommandlineArgNode *n = Base.cmdline.arg_bins[hash % countof(Base.cmdline.arg_bins)]; n; n = n->next)
|
||||
{
|
||||
if (n->hash == hash && MatchString(n->arg.name, name))
|
||||
{
|
||||
|
||||
@ -18,18 +18,6 @@ Struct(CommandlineArgNode)
|
||||
CommandlineArg arg;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
#define CommandlineArgBinsCount 1024
|
||||
|
||||
Struct(SharedCmdlineState)
|
||||
{
|
||||
String *positional_args;
|
||||
u64 positional_args_count;
|
||||
CommandlineArgNode *arg_bins[CommandlineArgBinsCount];
|
||||
} extern shared_cmdline_state;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#if GstatIsEnabled
|
||||
SharedGstatCtx _shared_gstat_ctx = ZI;
|
||||
#endif
|
||||
@ -2,21 +2,9 @@
|
||||
|
||||
#if GstatIsEnabled
|
||||
|
||||
Struct(SharedGstatCtx)
|
||||
{
|
||||
Atomic64Padded GSTAT_SOCK_BYTES_SENT;
|
||||
Atomic64Padded GSTAT_SOCK_BYTES_RECEIVED;
|
||||
Atomic64Padded GSTAT_MEMORY_COMMITTED;
|
||||
Atomic64Padded GSTAT_MEMORY_RESERVED;
|
||||
Atomic64Padded GSTAT_NUM_ARENAS;
|
||||
Atomic64Padded GSTAT_DEBUG_STEPS;
|
||||
};
|
||||
|
||||
extern SharedGstatCtx _shared_gstat_ctx;
|
||||
|
||||
#define SetGstat(name, value) Atomic64Set(&_shared_gstat_ctx.name.v, (value))
|
||||
#define AddGstat(name, value) Atomic64FetchAdd(&_shared_gstat_ctx.name.v, (value))
|
||||
#define GetGstat(name) Atomic64Fetch(&_shared_gstat_ctx.name.v)
|
||||
#define SetGstat(name, value) Atomic64Set(&Base.gstat.name.v, (value))
|
||||
#define AddGstat(name, value) Atomic64FetchAdd(&Base.gstat.name.v, (value))
|
||||
#define GetGstat(name) Atomic64Fetch(&Base.gstat.name.v)
|
||||
|
||||
#else
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
# include "base_resource.h"
|
||||
# include "base_controller.h"
|
||||
# include "base_async.h"
|
||||
# include "base_state.h"
|
||||
#elif IsLanguageG
|
||||
# include "base_shader.gh"
|
||||
#endif
|
||||
@ -40,7 +41,6 @@
|
||||
# include "base_string.c"
|
||||
# include "base_cmdline.c"
|
||||
# include "base_uni.c"
|
||||
# include "base_gstat.c"
|
||||
# include "base_buddy.c"
|
||||
# include "base_math.c"
|
||||
# include "base_rand.c"
|
||||
@ -48,6 +48,7 @@
|
||||
# include "base_resource.c"
|
||||
# include "base_controller.c"
|
||||
# include "base_async.c"
|
||||
# include "base_state.c"
|
||||
#endif
|
||||
|
||||
//- Include base_win32
|
||||
|
||||
@ -129,11 +129,6 @@ Global Readonly LogLevelSettings log_settings[LogLevel_Count] = {
|
||||
# define LogDebugF(...)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl Bootstrap
|
||||
|
||||
void BootstrapLogs(String logfile_path);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl Log
|
||||
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
SharedResourceState shared_resource_state = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
void BootstrapResources(u64 archive_strings_count, String *archive_strings)
|
||||
{
|
||||
SharedResourceState *g = &shared_resource_state;
|
||||
Arena *perm = PermArena();
|
||||
for (u64 archive_string_index = 0; archive_string_index < archive_strings_count; ++archive_string_index)
|
||||
{
|
||||
@ -32,11 +29,11 @@ void BootstrapResources(u64 archive_strings_count, String *archive_strings)
|
||||
entry->data = STRING(data_len, archive.text + data_start);
|
||||
entry->hash = HashFnv64(Fnv64Basis, entry->name);
|
||||
|
||||
ResourceEntryBin *bin = &g->bins[entry->hash % NumResourceEntryBins];
|
||||
ResourceEntryBin *bin = &Base.resource.bins[entry->hash % countof(Base.resource.bins)];
|
||||
SllQueuePushN(bin->first, bin->last, entry, next_in_bin);
|
||||
SllQueuePushN(g->first_entry, g->last_entry, entry, next);
|
||||
SllQueuePushN(Base.resource.first_entry, Base.resource.last_entry, entry, next);
|
||||
}
|
||||
g->entries_count += num_entries;
|
||||
Base.resource.entries_count += num_entries;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,8 +57,7 @@ ResourceKey ResourceKeyFromStore(ResourceStore *store, String name)
|
||||
ResourceEntry *ResourceEntryFromHash(u64 hash)
|
||||
{
|
||||
ResourceEntry *result = 0;
|
||||
SharedResourceState *g = &shared_resource_state;
|
||||
ResourceEntryBin *bin = &g->bins[hash % NumResourceEntryBins];
|
||||
ResourceEntryBin *bin = &Base.resource.bins[hash % countof(Base.resource.bins)];
|
||||
for (ResourceEntry *e = bin->first; e; e = e->next_in_bin)
|
||||
{
|
||||
if (e->hash == hash)
|
||||
|
||||
@ -17,19 +17,6 @@ Struct(ResourceEntryBin)
|
||||
ResourceEntry *last;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
#define NumResourceEntryBins 4096
|
||||
|
||||
Struct(SharedResourceState)
|
||||
{
|
||||
ResourceEntry *first_entry;
|
||||
ResourceEntry *last_entry;
|
||||
u64 entries_count;
|
||||
ResourceEntryBin bins[NumResourceEntryBins];
|
||||
} extern shared_resource_state;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
|
||||
2
src/base/base_state.c
Normal file
2
src/base/base_state.c
Normal file
@ -0,0 +1,2 @@
|
||||
BaseState Base = ZI;
|
||||
ThreadLocal BaseThreadLocalState Base_tl = ZI;
|
||||
59
src/base/base_state.h
Normal file
59
src/base/base_state.h
Normal file
@ -0,0 +1,59 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Global state
|
||||
|
||||
Struct(BaseState)
|
||||
{
|
||||
/* Command line */
|
||||
struct
|
||||
{
|
||||
String *positional_args;
|
||||
u64 positional_args_count;
|
||||
CommandlineArgNode *arg_bins[1024];
|
||||
} cmdline;
|
||||
|
||||
/* Resources */
|
||||
struct
|
||||
{
|
||||
u64 entries_count;
|
||||
ResourceEntry *first_entry;
|
||||
ResourceEntry *last_entry;
|
||||
ResourceEntryBin bins[4096];
|
||||
} resource;
|
||||
|
||||
/* Stats */
|
||||
struct
|
||||
{
|
||||
Atomic64Padded SockBytesSent;
|
||||
Atomic64Padded SockBytesReceived;
|
||||
Atomic64Padded MemoryCommitted;
|
||||
Atomic64Padded MemoryReserved;
|
||||
Atomic64Padded NumArenas;
|
||||
Atomic64Padded DebugSteps;
|
||||
} gstat;
|
||||
|
||||
/* Async */
|
||||
struct
|
||||
{
|
||||
Mutex mutex;
|
||||
u64 callback_nodes_count;
|
||||
AsyncTickCallbackNode *first_callback_node;
|
||||
AsyncTickCallbackNode *last_callback_node;
|
||||
AsyncWorkerState worker;
|
||||
} async;
|
||||
};
|
||||
|
||||
extern BaseState Base;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Thread-local state
|
||||
|
||||
Struct(BaseThreadLocalState)
|
||||
{
|
||||
struct
|
||||
{
|
||||
Arena *perm;
|
||||
Arena *scratch[2];
|
||||
} arenas;
|
||||
};
|
||||
|
||||
extern ThreadLocal BaseThreadLocalState Base_tl;
|
||||
@ -12,7 +12,7 @@ void WaveSyncEx(WaveLaneCtx *lane, u64 spin_count)
|
||||
if (blocked_count == lanes_count)
|
||||
{
|
||||
Atomic32Set(&wave->sync_count.v, 0);
|
||||
Atomic64FetchAdd(&wave->sync_gen.v, sync_gen + 1);
|
||||
Atomic64Set(&wave->sync_gen.v, sync_gen + 1);
|
||||
FutexWakeNeq(&wave->sync_gen.v);
|
||||
}
|
||||
else
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
W32_SharedState W32_shared_state = ZI;
|
||||
W32_State W32 = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Win32 embedded data
|
||||
@ -40,7 +40,7 @@ BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name
|
||||
|
||||
StringList GetRawCommandline(void)
|
||||
{
|
||||
return W32_shared_state.raw_command_line;
|
||||
return W32.raw_command_line;
|
||||
}
|
||||
|
||||
void Echo(String msg)
|
||||
@ -92,10 +92,9 @@ b32 IsRunningInDebugger(void)
|
||||
|
||||
i64 TimeNs(void)
|
||||
{
|
||||
struct W32_SharedState *g = &W32_shared_state;
|
||||
LARGE_INTEGER qpc;
|
||||
QueryPerformanceCounter(&qpc);
|
||||
i64 result = (qpc.QuadPart - g->timer_start_qpc) * g->ns_per_qpc;
|
||||
i64 result = (qpc.QuadPart - W32.timer_start_qpc) * W32.ns_per_qpc;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -165,6 +164,11 @@ CpuTopologyInfo GetCpuTopologyInfo(void)
|
||||
return res;
|
||||
}
|
||||
|
||||
void SleepSeconds(f64 seconds)
|
||||
{
|
||||
Sleep(seconds / 1000.0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Swap
|
||||
|
||||
@ -231,20 +235,18 @@ void WriteSwappedState(String name, String data)
|
||||
|
||||
void OnExit(ExitFunc *func)
|
||||
{
|
||||
W32_SharedState *g = &W32_shared_state;
|
||||
i32 index = Atomic32FetchAdd(&g->num_exit_funcs, 1);
|
||||
if (index >= W32_MaxOnExitFuncs)
|
||||
i32 index = Atomic32FetchAdd(&W32.num_exit_funcs, 1);
|
||||
if (index >= countof(W32.exit_funcs))
|
||||
{
|
||||
Panic(Lit("Maximum on exit functions registered"));
|
||||
}
|
||||
g->exit_funcs[index] = func;
|
||||
W32.exit_funcs[index] = func;
|
||||
}
|
||||
|
||||
void SignalExit(i32 code)
|
||||
{
|
||||
W32_SharedState *g = &W32_shared_state;
|
||||
Atomic32Set(&g->exit_code, code);
|
||||
SetEvent(g->exit_event);
|
||||
Atomic32Set(&W32.exit_code, code);
|
||||
SetEvent(W32.exit_event);
|
||||
}
|
||||
|
||||
void ExitNow(i32 code)
|
||||
@ -252,34 +254,168 @@ void ExitNow(i32 code)
|
||||
ExitProcess(code);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Log
|
||||
|
||||
void W32_BootstrapLogs(String logfile_path)
|
||||
{
|
||||
W32.logs_arena = AcquireArena(Gibi(64));
|
||||
W32.log_msgs_arena = AcquireArena(Gibi(64));
|
||||
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
||||
if (logfile_path.len > 0)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, logfile_path);
|
||||
W32.logfile = CreateFileW(path_wstr,
|
||||
FILE_APPEND_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
Atomic32Set(&W32.logs_initialized, 1);
|
||||
}
|
||||
|
||||
void W32_Log(i32 level, String msg)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
{
|
||||
LogLevelSettings settings = log_settings[level];
|
||||
if (level < 0 || level >= LogLevel_Count)
|
||||
{
|
||||
Panic(Lit("Invalid log level"));
|
||||
}
|
||||
|
||||
DateTime datetime = LocalDateTime();
|
||||
i64 now_ns = TimeNs();
|
||||
i32 thread_id = GetCurrentThreadId();
|
||||
|
||||
//- Log message to file
|
||||
/* TODO: Log asynchronously */
|
||||
{
|
||||
String shorthand = settings.shorthand;
|
||||
String msg_formatted = StringF(
|
||||
scratch.arena,
|
||||
"[%F:%F:%F.%F] <%F> [%F] %F\n",
|
||||
|
||||
/* Time */
|
||||
FmtUint(datetime.hour, .z = 2),
|
||||
FmtUint(datetime.minute, .z = 2),
|
||||
FmtUint(datetime.second, .z = 2),
|
||||
FmtUint(datetime.milliseconds, .z = 3),
|
||||
|
||||
/* Thread id */
|
||||
FmtUint(thread_id, .z = 5),
|
||||
|
||||
/* Level */
|
||||
FmtString(shorthand),
|
||||
|
||||
/* Message */
|
||||
FmtString(msg)
|
||||
);
|
||||
WriteFile(W32.logfile, msg_formatted.text, msg_formatted.len, 0, 0);
|
||||
}
|
||||
|
||||
//- Log message to queue
|
||||
/* TODO: Log asynchronously */
|
||||
LockTicketMutex(&W32.logs_tm);
|
||||
{
|
||||
/* Get staged data */
|
||||
LogEvent *ev = PushStruct(W32.logs_arena, LogEvent);
|
||||
ev->msg = PushString(W32.log_msgs_arena, msg);
|
||||
ev->datetime = datetime;
|
||||
ev->time_ns = now_ns;
|
||||
ev->level = level;
|
||||
ev->thread_id = thread_id;
|
||||
ev->id = W32.logs_count++;
|
||||
ev->level_id = W32.log_level_counts[level]++;
|
||||
Atomic64Set(&W32.readable_logs_count, W32.logs_count);
|
||||
}
|
||||
UnlockTicketMutex(&W32.logs_tm);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Log
|
||||
|
||||
/* Panic log function is separate to enforce zero side effects other than
|
||||
* immediately writing to log file. */
|
||||
void LogPanic(String msg)
|
||||
{
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
{
|
||||
String beg = Lit("******** PANICKING ********\n");
|
||||
String end = Lit("\n***************************\n");
|
||||
WriteFile(W32.logfile, beg.text, beg.len, 0, 0);
|
||||
WriteFile(W32.logfile, msg.text, msg.len, 0, 0);
|
||||
WriteFile(W32.logfile, end.text, end.len, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Log_(i32 level, String msg)
|
||||
{
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
|
||||
void LogF_(i32 level, String fmt, ...)
|
||||
{
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
va_end(args);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsArray GetLogEvents(void)
|
||||
{
|
||||
LogEventsArray result = ZI;
|
||||
result.count = Atomic64Fetch(&W32.readable_logs_count);
|
||||
if (result.count > 0)
|
||||
{
|
||||
result.logs = W32.readable_log_events;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Main
|
||||
|
||||
i32 W32_Main(void)
|
||||
{
|
||||
W32_SharedState *g = &W32_shared_state;
|
||||
|
||||
/* Init time */
|
||||
{
|
||||
LARGE_INTEGER qpf;
|
||||
QueryPerformanceFrequency(&qpf);
|
||||
g->ns_per_qpc = 1000000000 / qpf.QuadPart;
|
||||
W32.ns_per_qpc = 1000000000 / qpf.QuadPart;
|
||||
}
|
||||
{
|
||||
LARGE_INTEGER qpc;
|
||||
QueryPerformanceCounter(&qpc);
|
||||
g->timer_start_qpc = qpc.QuadPart;
|
||||
W32.timer_start_qpc = qpc.QuadPart;
|
||||
}
|
||||
|
||||
/* Setup events */
|
||||
g->panic_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_event = CreateEventW(0, 1, 0, 0);
|
||||
W32.panic_event = CreateEventW(0, 1, 0, 0);
|
||||
W32.exit_event = CreateEventW(0, 1, 0, 0);
|
||||
|
||||
g->main_thread_id = GetCurrentThreadId();
|
||||
W32.main_thread_id = GetCurrentThreadId();
|
||||
SetThreadDescription(GetCurrentThread(), L"Main thread");
|
||||
|
||||
/* Query system info */
|
||||
GetSystemInfo(&g->info);
|
||||
GetSystemInfo(&W32.info);
|
||||
|
||||
/* Init main thread */
|
||||
W32_InitCurrentThread(Lit("Main"));
|
||||
@ -299,7 +435,7 @@ i32 W32_Main(void)
|
||||
PushStringToList(perm, &args_list, arg);
|
||||
}
|
||||
}
|
||||
g->raw_command_line = args_list;
|
||||
W32.raw_command_line = args_list;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -310,7 +446,7 @@ i32 W32_Main(void)
|
||||
|
||||
/* Bootstrap log system */
|
||||
/* FIXME: Remove hardcoded log path */
|
||||
BootstrapLogs(Lit("log.log"));
|
||||
W32_BootstrapLogs(Lit("log.log"));
|
||||
LogInfoF("Main thread ID: %F", FmtUint(ThreadId()));
|
||||
|
||||
/* Bootstrap resource system */
|
||||
@ -324,7 +460,7 @@ i32 W32_Main(void)
|
||||
BootstrapAsync();
|
||||
|
||||
/* Bootstrap layers */
|
||||
if (!Atomic32Fetch(&g->panicking))
|
||||
if (!Atomic32Fetch(&W32.panicking))
|
||||
{
|
||||
BootstrapLayers();
|
||||
}
|
||||
@ -333,11 +469,11 @@ i32 W32_Main(void)
|
||||
//- Wait for exit signal
|
||||
|
||||
/* Wait for exit start or panic */
|
||||
if (!Atomic32Fetch(&g->panicking))
|
||||
if (!Atomic32Fetch(&W32.panicking))
|
||||
{
|
||||
HANDLE handles[] = {
|
||||
g->exit_event,
|
||||
g->panic_event,
|
||||
W32.exit_event,
|
||||
W32.panic_event,
|
||||
};
|
||||
DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
}
|
||||
@ -346,24 +482,24 @@ i32 W32_Main(void)
|
||||
//- Shutdown
|
||||
|
||||
/* Run exit callbacks */
|
||||
if (!Atomic32Fetch(&g->panicking))
|
||||
if (!Atomic32Fetch(&W32.panicking))
|
||||
{
|
||||
i32 num_funcs = Atomic32Fetch(&g->num_exit_funcs);
|
||||
i32 num_funcs = Atomic32Fetch(&W32.num_exit_funcs);
|
||||
for (i32 idx = num_funcs - 1; idx >= 0; --idx)
|
||||
{
|
||||
ExitFunc *func = g->exit_funcs[idx];
|
||||
ExitFunc *func = W32.exit_funcs[idx];
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit */
|
||||
if (Atomic32Fetch(&g->panicking))
|
||||
if (Atomic32Fetch(&W32.panicking))
|
||||
{
|
||||
WaitForSingleObject(g->panic_event, INFINITE);
|
||||
MessageBoxExW(0, g->panic_wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
||||
Atomic32FetchTestSet(&g->exit_code, 0, 1);
|
||||
WaitForSingleObject(W32.panic_event, INFINITE);
|
||||
MessageBoxExW(0, W32.panic_wstr, L"Fatal error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
||||
Atomic32FetchTestSet(&W32.exit_code, 0, 1);
|
||||
}
|
||||
return Atomic32Fetch(&g->exit_code);
|
||||
return Atomic32Fetch(&W32.exit_code);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -56,9 +56,7 @@ Struct(W32_FindEmbeddedDataCtx)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
#define W32_MaxOnExitFuncs 4096
|
||||
|
||||
Struct(W32_SharedState)
|
||||
Struct(W32_State)
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
u32 main_thread_id;
|
||||
@ -71,15 +69,33 @@ Struct(W32_SharedState)
|
||||
StringList raw_command_line;
|
||||
|
||||
//- Application control flow
|
||||
|
||||
Atomic32 panicking;
|
||||
wchar_t panic_wstr[4096];
|
||||
HANDLE panic_event;
|
||||
HANDLE exit_event;
|
||||
|
||||
//- Exit funcs
|
||||
|
||||
Atomic32 num_exit_funcs;
|
||||
ExitFunc *exit_funcs[W32_MaxOnExitFuncs];
|
||||
} extern W32_shared_state;
|
||||
ExitFunc *exit_funcs[4096];
|
||||
|
||||
//- Logs
|
||||
|
||||
HANDLE logfile;
|
||||
Atomic32 logs_initialized;
|
||||
|
||||
TicketMutex logs_tm;
|
||||
Arena *log_msgs_arena;
|
||||
Arena *logs_arena;
|
||||
|
||||
u64 logs_count;
|
||||
u64 log_level_counts[LogLevel_Count];
|
||||
LogEvent *readable_log_events;
|
||||
Atomic64 readable_logs_count;
|
||||
};
|
||||
|
||||
extern W32_State W32;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Embedded data initialization
|
||||
@ -87,6 +103,12 @@ Struct(W32_SharedState)
|
||||
#define W32_EmbeddedDataPrefix EMBEDDED_RESOURCE_DATA__
|
||||
BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name, LONG_PTR udata);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Log
|
||||
|
||||
void W32_BootstrapLogs(String logfile_path);
|
||||
void W32_Log(i32 level, String msg);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Main
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
//- Api
|
||||
#include "base_win32.h"
|
||||
#include "base_win32_wave.h"
|
||||
#include "base_win32_log.h"
|
||||
|
||||
//- Impl
|
||||
#include "base_win32.c"
|
||||
@ -9,4 +8,3 @@
|
||||
#include "base_win32_memory.c"
|
||||
#include "base_win32_wave.c"
|
||||
#include "base_win32_time.c"
|
||||
#include "base_win32_log.c"
|
||||
|
||||
@ -1,145 +0,0 @@
|
||||
W32_SharedLogState W32_shared_log_state = ZI;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Bootstrap
|
||||
|
||||
void BootstrapLogs(String logfile_path)
|
||||
{
|
||||
W32_SharedLogState *g = &W32_shared_log_state;
|
||||
g->logs_arena = AcquireArena(Gibi(64));
|
||||
g->log_msgs_arena = AcquireArena(Gibi(64));
|
||||
g->readable_log_events = ArenaNext(g->logs_arena, LogEvent);
|
||||
if (logfile_path.len > 0)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, logfile_path);
|
||||
g->logfile = CreateFileW(path_wstr,
|
||||
FILE_APPEND_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
Atomic32Set(&g->initialized, 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Log
|
||||
|
||||
void W32_Log(i32 level, String msg)
|
||||
{
|
||||
W32_SharedLogState *g = &W32_shared_log_state;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
if (Atomic32Fetch(&g->initialized))
|
||||
{
|
||||
LogLevelSettings settings = log_settings[level];
|
||||
if (level < 0 || level >= LogLevel_Count)
|
||||
{
|
||||
Panic(Lit("Invalid log level"));
|
||||
}
|
||||
|
||||
DateTime datetime = LocalDateTime();
|
||||
i64 now_ns = TimeNs();
|
||||
i32 thread_id = GetCurrentThreadId();
|
||||
|
||||
//- Log message to file
|
||||
/* TODO: Log asynchronously */
|
||||
{
|
||||
String shorthand = settings.shorthand;
|
||||
String msg_formatted = StringF(
|
||||
scratch.arena,
|
||||
"[%F:%F:%F.%F] <%F> [%F] %F\n",
|
||||
|
||||
/* Time */
|
||||
FmtUint(datetime.hour, .z = 2),
|
||||
FmtUint(datetime.minute, .z = 2),
|
||||
FmtUint(datetime.second, .z = 2),
|
||||
FmtUint(datetime.milliseconds, .z = 3),
|
||||
|
||||
/* Thread id */
|
||||
FmtUint(thread_id, .z = 5),
|
||||
|
||||
/* Level */
|
||||
FmtString(shorthand),
|
||||
|
||||
/* Message */
|
||||
FmtString(msg)
|
||||
);
|
||||
WriteFile(g->logfile, msg_formatted.text, msg_formatted.len, 0, 0);
|
||||
}
|
||||
|
||||
//- Log message to queue
|
||||
/* TODO: Log asynchronously */
|
||||
LockTicketMutex(&g->logs_tm);
|
||||
{
|
||||
/* Get staged data */
|
||||
LogEvent *ev = PushStruct(g->logs_arena, LogEvent);
|
||||
ev->msg = PushString(g->log_msgs_arena, msg);
|
||||
ev->datetime = datetime;
|
||||
ev->time_ns = now_ns;
|
||||
ev->level = level;
|
||||
ev->thread_id = thread_id;
|
||||
ev->id = g->logs_count++;
|
||||
ev->level_id = g->log_level_counts[level]++;
|
||||
Atomic64Set(&g->readable_logs_count, g->logs_count);
|
||||
}
|
||||
UnlockTicketMutex(&g->logs_tm);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Log
|
||||
|
||||
/* Panic log function is separate to enforce zero side effects other than
|
||||
* immediately writing to log file. */
|
||||
void LogPanic(String msg)
|
||||
{
|
||||
W32_SharedLogState *g = &W32_shared_log_state;
|
||||
if (Atomic32Fetch(&g->initialized))
|
||||
{
|
||||
String beg = Lit("******** PANICKING ********\n");
|
||||
String end = Lit("\n***************************\n");
|
||||
WriteFile(g->logfile, beg.text, beg.len, 0, 0);
|
||||
WriteFile(g->logfile, msg.text, msg.len, 0, 0);
|
||||
WriteFile(g->logfile, end.text, end.len, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Log_(i32 level, String msg)
|
||||
{
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
|
||||
void LogF_(i32 level, String fmt, ...)
|
||||
{
|
||||
W32_SharedLogState *g = &W32_shared_log_state;
|
||||
if (Atomic32Fetch(&g->initialized))
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
va_end(args);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsArray GetLogEvents(void)
|
||||
{
|
||||
W32_SharedLogState *g = &W32_shared_log_state;
|
||||
LogEventsArray result = ZI;
|
||||
result.count = Atomic64Fetch(&g->readable_logs_count);
|
||||
if (result.count > 0)
|
||||
{
|
||||
result.logs = g->readable_log_events;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
Struct(W32_SharedLogState)
|
||||
{
|
||||
HANDLE logfile;
|
||||
Atomic32 initialized;
|
||||
|
||||
TicketMutex logs_tm;
|
||||
Arena *log_msgs_arena;
|
||||
Arena *logs_arena;
|
||||
u64 logs_count;
|
||||
u64 log_level_counts[LogLevel_Count];
|
||||
LogEvent *readable_log_events;
|
||||
Atomic64 readable_logs_count;
|
||||
} extern W32_shared_log_state;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Log
|
||||
|
||||
void W32_Log(i32 level, String msg);
|
||||
@ -5,16 +5,15 @@ void W32_InitCurrentThread(String name)
|
||||
{
|
||||
/* Init thread arenas */
|
||||
{
|
||||
ThreadArenasCtx *tctx = &t_arena_ctx;
|
||||
tctx->perm_arena = AcquireArena(Gibi(64));
|
||||
for (i32 i = 0; i < (i32)countof(tctx->scratch_arenas); ++i)
|
||||
Base_tl.arenas.perm = AcquireArena(Gibi(64));
|
||||
for (i32 i = 0; i < (i32)countof(Base_tl.arenas.scratch); ++i)
|
||||
{
|
||||
tctx->scratch_arenas[i] = AcquireArena(Gibi(64));
|
||||
Base_tl.arenas.scratch[i] = AcquireArena(Gibi(64));
|
||||
}
|
||||
}
|
||||
|
||||
Arena *perm = PermArena();
|
||||
|
||||
/* Set thread name */
|
||||
wchar_t *thread_name_wstr = WstrFromString(perm, name);
|
||||
SetThreadDescription(GetCurrentThread(), thread_name_wstr);
|
||||
|
||||
|
||||
@ -138,15 +138,15 @@ Struct(CLD_EpaData)
|
||||
#if COLLIDER_DEBUG
|
||||
void CLD_DebugBreakable(void);
|
||||
|
||||
#define CLD_DBGSTEP \
|
||||
dbg_step++; \
|
||||
if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS)) \
|
||||
{ \
|
||||
goto abort; \
|
||||
} \
|
||||
else if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS) - 1) \
|
||||
{ \
|
||||
CLD_DebugBreakable(); \
|
||||
#define CLD_DBGSTEP \
|
||||
dbg_step++; \
|
||||
if (dbg_step >= GetGstat(DebugSteps)) \
|
||||
{ \
|
||||
goto abort; \
|
||||
} \
|
||||
else if (dbg_step >= GetGstat(DebugSteps) - 1) \
|
||||
{ \
|
||||
CLD_DebugBreakable(); \
|
||||
} (void)0
|
||||
#else
|
||||
#define CLD_DBGSTEP
|
||||
|
||||
@ -3,7 +3,7 @@ GC_State GC = ZI;
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Bootstrap
|
||||
|
||||
void GC_BootStrap(void)
|
||||
void GC_Bootstrap(void)
|
||||
{
|
||||
OnAsyncTick(GC_AsyncTick);
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
|
||||
@IncludeC glyph_cache.h
|
||||
|
||||
@Bootstrap GC_Bootstrap
|
||||
|
||||
//////////////////////////////
|
||||
//- Impl
|
||||
|
||||
|
||||
@ -2848,8 +2848,6 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
P_SleepSeconds(0.100);
|
||||
|
||||
/* Copy print-buffers to readback */
|
||||
for (G_QueueKind queue_kind = 0; queue_kind < G_NumQueues; ++queue_kind)
|
||||
{
|
||||
|
||||
@ -137,6 +137,5 @@ i64 P_GetCurrentTimerPeriodNs(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl Sleep
|
||||
|
||||
void P_SleepSeconds(f64 seconds);
|
||||
void P_SleepPrecise(i64 sleep_time_ns);
|
||||
void P_SleepFrame(i64 last_frame_time_ns, i64 target_dt_ns);
|
||||
|
||||
@ -838,7 +838,7 @@ P_SockReadResult P_ReadSock(Arena *arena, P_Sock *sock)
|
||||
result.address = P_W32_PlatformAddressFromWin32Address(ws_addr);
|
||||
if (size >= 0)
|
||||
{
|
||||
AddGstat(GSTAT_SOCK_BYTES_RECEIVED, size);
|
||||
AddGstat(SockBytesReceived, size);
|
||||
result.data.text = read_buff.text;
|
||||
result.data.len = size;
|
||||
result.valid = 1;
|
||||
@ -867,7 +867,7 @@ void P_WriteSock(P_Sock *sock, P_Address address, String data)
|
||||
i32 size = sendto(ws->sock, (char *)data.text, data.len, 0, &ws_addr.sa, ws_addr.size);
|
||||
if (size > 0)
|
||||
{
|
||||
AddGstat(GSTAT_SOCK_BYTES_SENT, size);
|
||||
AddGstat(SockBytesSent, size);
|
||||
}
|
||||
#if IsRtcEnabled
|
||||
if (size != (i32)data.len)
|
||||
@ -978,11 +978,6 @@ i64 P_GetCurrentTimerPeriodNs(void)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Sleep
|
||||
|
||||
void P_SleepSeconds(f64 seconds)
|
||||
{
|
||||
Sleep(seconds / 1000.0);
|
||||
}
|
||||
|
||||
void P_SleepPrecise(i64 sleep_time_ns)
|
||||
{
|
||||
i64 now_ns = TimeNs();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user