swap testing
This commit is contained in:
parent
0f31e27d96
commit
05f6c937cb
@ -37,6 +37,10 @@
|
||||
# error Missing compile time definition for 'TestsAreEnabled'
|
||||
#endif
|
||||
|
||||
#ifndef HotSwappingIsEnabled
|
||||
# error Missing compile time definition for 'HotSwappingIsEnabled'
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Machine context
|
||||
|
||||
|
||||
@ -5,7 +5,16 @@
|
||||
typedef ExitFuncDef(ExitFunc);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl Exit operations
|
||||
//~ @hookdecl Swap hooks
|
||||
|
||||
b32 IsSwappingIn(void);
|
||||
b32 IsSwappingOut(void);
|
||||
|
||||
String SwappedStateFromName(Arena *arena, String name);
|
||||
void WriteSwappedState(String name, String data);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdecl Exit hooks
|
||||
|
||||
void OnExit(ExitFunc *func);
|
||||
void SignalExit(i32 code);
|
||||
|
||||
@ -109,6 +109,68 @@ void TrueRand(String buffer)
|
||||
BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Swap hooks
|
||||
|
||||
b32 IsSwappingIn(void)
|
||||
{
|
||||
return HotSwappingIsEnabled;
|
||||
}
|
||||
|
||||
b32 IsSwappingOut(void)
|
||||
{
|
||||
return HotSwappingIsEnabled;
|
||||
}
|
||||
|
||||
String SwappedStateFromName(Arena *arena, String name)
|
||||
{
|
||||
TempArena scratch = BeginScratch(arena);
|
||||
String result = ZI;
|
||||
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name));
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, path);
|
||||
HANDLE handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
u32 chunk_size = Kibi(64);
|
||||
result.text = PushDry(arena, u8);
|
||||
for (;;)
|
||||
{
|
||||
u8 *chunk = PushStructsNoZero(arena, u8, chunk_size);
|
||||
u32 chunk_bytes_read = 0;
|
||||
ReadFile(handle, chunk, chunk_size, (LPDWORD)&chunk_bytes_read, 0);
|
||||
result.len += chunk_bytes_read;
|
||||
if (chunk_bytes_read < chunk_size)
|
||||
{
|
||||
PopStructsNoCopy(arena, u8, chunk_size - chunk_bytes_read);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(handle);
|
||||
EndScratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
void WriteSwappedState(String name, String data)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
String result = ZI;
|
||||
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name));
|
||||
wchar_t *path_wstr = WstrFromString(scratch.arena, path);
|
||||
HANDLE handle = CreateFileW(path_wstr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetFilePointer(handle, 0, 0, FILE_BEGIN);
|
||||
SetEndOfFile(handle);
|
||||
WriteFile(handle, data.text, data.len, 0, 0);
|
||||
}
|
||||
CloseHandle(handle);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookdef Exit hooks
|
||||
|
||||
void OnExit(ExitFunc *func)
|
||||
{
|
||||
W32_SharedState *g = &W32_shared_state;
|
||||
@ -254,10 +316,15 @@ i32 W32_Main(void)
|
||||
}
|
||||
|
||||
/* Set up exit events */
|
||||
g->panic_event = CreateEventW(0, 1, 0, 0);
|
||||
#if HotSwappingIsEnabled
|
||||
g->swap_event = CreateEventW(0, 1, 0, L"Local\\pp_swap_start");
|
||||
#else
|
||||
g->swap_event = CreateEventW(0, 1, 0, 0);
|
||||
#endif
|
||||
g->panic_event = CreateEventW(0, 1, 0, 0);
|
||||
g->startup_end_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_begin_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_end_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_begin_event = CreateEventW(0, 1, 0, 0);
|
||||
g->exit_end_event = CreateEventW(0, 1, 0, 0);
|
||||
|
||||
g->main_thread_id = GetCurrentThreadId();
|
||||
SetThreadDescription(GetCurrentThread(), L"Main thread");
|
||||
@ -291,7 +358,7 @@ i32 W32_Main(void)
|
||||
{
|
||||
HANDLE handles[] = {
|
||||
g->startup_end_event,
|
||||
g->panic_event
|
||||
g->panic_event,
|
||||
};
|
||||
WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
}
|
||||
@ -301,9 +368,10 @@ i32 W32_Main(void)
|
||||
{
|
||||
HANDLE handles[] = {
|
||||
g->exit_begin_event,
|
||||
g->panic_event
|
||||
g->panic_event,
|
||||
g->swap_event,
|
||||
};
|
||||
WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
}
|
||||
|
||||
//- App shutdown
|
||||
@ -324,6 +392,16 @@ i32 W32_Main(void)
|
||||
WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
|
||||
}
|
||||
|
||||
/* Signal swap finish */
|
||||
if (!Atomic32Fetch(&g->panicking) && IsSwappingOut())
|
||||
{
|
||||
HANDLE swap_end_event = OpenEventW(EVENT_MODIFY_STATE, 0, L"Local\\pp_swap_end");
|
||||
if (swap_end_event != 0)
|
||||
{
|
||||
SetEvent(swap_end_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit */
|
||||
if (Atomic32Fetch(&g->panicking))
|
||||
{
|
||||
|
||||
@ -38,6 +38,7 @@ Struct(W32_SharedState)
|
||||
Atomic32 panicking;
|
||||
wchar_t panic_wstr[4096];
|
||||
HANDLE panic_event;
|
||||
HANDLE swap_event;
|
||||
HANDLE startup_end_event;
|
||||
HANDLE exit_begin_event;
|
||||
HANDLE exit_end_event;
|
||||
|
||||
@ -45,6 +45,10 @@
|
||||
# define TestsAreEnabled 0
|
||||
#endif
|
||||
|
||||
#ifndef HotSwappingIsEnabled
|
||||
# define HotSwappingIsEnabled 0
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Includes
|
||||
|
||||
@ -96,6 +100,36 @@ LineCol LineColFromPos(String data, i64 pos)
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Swap
|
||||
|
||||
#if PlatformIsWindows
|
||||
u64 SignalSwapStart(void)
|
||||
{
|
||||
OS_Mkdir(Lit("swap"));
|
||||
HANDLE swap_end_event = CreateEventW(0, 1, 0, L"Local\\pp_swap_end");
|
||||
HANDLE swap_start_event = OpenEventW(EVENT_MODIFY_STATE, 0, L"Local\\pp_swap_start");
|
||||
if (swap_start_event != 0)
|
||||
{
|
||||
SetEvent(swap_start_event);
|
||||
CloseHandle(swap_start_event);
|
||||
}
|
||||
return (u64)swap_end_event;
|
||||
}
|
||||
|
||||
void WaitForSwapEnd(u64 swap_start, i64 timeout_ns)
|
||||
{
|
||||
HANDLE swap_start_event = (HANDLE)swap_start;
|
||||
if (swap_start_event != 0)
|
||||
{
|
||||
DWORD timeout_ms = timeout_ns / 1000000;
|
||||
WaitForSingleObject(swap_start_event, timeout_ms);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# error Swap signaling not implemented
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ OS command job
|
||||
|
||||
@ -138,7 +172,6 @@ Struct(CompilerParams)
|
||||
StringList linker_only_flags_clang;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Build step job
|
||||
|
||||
@ -872,6 +905,8 @@ JobDef(Build, _, __)
|
||||
}
|
||||
}
|
||||
|
||||
u64 swap_start = SignalSwapStart();
|
||||
|
||||
//////////////////////////////
|
||||
//- Args
|
||||
|
||||
@ -895,6 +930,7 @@ JobDef(Build, _, __)
|
||||
PushStringToList(arena, &cp.defs, Lit("-DProfilingIsEnabled=0"));
|
||||
PushStringToList(arena, &cp.defs, Lit("-DUnoptimizedIsEnabled=1"));
|
||||
PushStringToList(arena, &cp.defs, Lit("-DTestsAreEnabled=0"));
|
||||
PushStringToList(arena, &cp.defs, Lit("-DHotSwappingIsEnabled=1"));
|
||||
|
||||
//- Msvc
|
||||
{
|
||||
@ -1049,6 +1085,8 @@ JobDef(Build, _, __)
|
||||
|
||||
//- Link
|
||||
|
||||
WaitForSwapEnd(swap_start, NsFromSeconds(0.5f / 1000.f));
|
||||
|
||||
String exe_file = Lit("pp.exe");
|
||||
i64 link_elapsed_ns = 0;
|
||||
if (ret == 0)
|
||||
|
||||
43
src/pp/pp.c
43
src/pp/pp.c
@ -30,8 +30,36 @@ void StartupUser(void)
|
||||
g->local_to_user_client_store = AcquireClientStore();
|
||||
g->local_to_user_client = AcquireClient(g->local_to_user_client_store);
|
||||
|
||||
/* Init from swap */
|
||||
g->world_to_ui_xf = XformIdentity;
|
||||
g->world_to_render_xf = XformIdentity;
|
||||
if (IsSwappingIn());
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
String swap_str = SwappedStateFromName(scratch.arena, Lit("pp_user"));
|
||||
if (swap_str.len == sizeof(SwappedUserState))
|
||||
{
|
||||
SwappedUserState *swap = (SwappedUserState *)swap_str.text;
|
||||
SharedUserState *old = &swap->s;
|
||||
g->debug_following = old->debug_following;
|
||||
g->debug_camera = old->debug_camera;
|
||||
g->debug_camera_panning = old->debug_camera_panning;
|
||||
g->debug_camera_pan_start = old->debug_camera_pan_start;
|
||||
g->debug_draw = old->debug_draw;
|
||||
g->screen_size = old->screen_size;
|
||||
g->screen_cursor = old->screen_cursor;
|
||||
g->ui_to_screen_xf = old->ui_to_screen_xf;
|
||||
g->ui_size = old->ui_size;
|
||||
g->ui_cursor = old->ui_cursor;
|
||||
g->render_to_ui_xf = old->render_to_ui_xf;
|
||||
g->render_size = old->render_size;
|
||||
g->world_to_render_xf = old->world_to_render_xf;
|
||||
g->world_to_ui_xf = old->world_to_ui_xf;
|
||||
g->world_cursor = old->world_cursor;
|
||||
g->focus_send = old->focus_send;
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
g->console_logs_arena = AcquireArena(Gibi(64));
|
||||
//P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Success);
|
||||
@ -55,6 +83,19 @@ ExitFuncDef(ShutdownUser)
|
||||
SharedUserState *g = &shared_user_state;
|
||||
Atomic32Set(&g->shutdown, 1);
|
||||
YieldOnFence(&g->shutdown_jobs_fence, g->shutdown_jobs_count);
|
||||
|
||||
/* Swap out */
|
||||
if (IsSwappingOut())
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
SwappedUserState *swap = PushStruct(scratch.arena, SwappedUserState);
|
||||
swap->s = *g;
|
||||
WriteSwappedState(Lit("pp_user"), StringFromStruct(swap));
|
||||
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
P_ReleaseWindow(g->window);
|
||||
}
|
||||
|
||||
@ -3215,9 +3256,11 @@ JobDef(UpdateSim, UNUSED sig, UNUSED id)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
ReleaseClientStore(store);
|
||||
ReleaseSimAccel(&accel);
|
||||
BB_ReleaseBuff(&snapshot_writer_bb);
|
||||
BB_ReleaseBuff(&msg_writer_bb);
|
||||
N_ReleaseHost(host);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -264,6 +264,14 @@ Struct(SharedUserState)
|
||||
Vec2 focus_send;
|
||||
} extern shared_user_state;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Swap types
|
||||
|
||||
Struct(SwappedUserState)
|
||||
{
|
||||
SharedUserState s;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Startup
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user