swap without events

This commit is contained in:
jacob 2025-10-24 06:28:08 -05:00
parent 05f6c937cb
commit a8bc77fab3
7 changed files with 23 additions and 58 deletions

View File

@ -126,7 +126,7 @@ String SwappedStateFromName(Arena *arena, String name)
{ {
TempArena scratch = BeginScratch(arena); TempArena scratch = BeginScratch(arena);
String result = ZI; String result = ZI;
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name)); String path = StringF(scratch.arena, "ppswap/%F.swp", FmtString(name));
wchar_t *path_wstr = WstrFromString(scratch.arena, path); 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); HANDLE handle = CreateFileW(path_wstr, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (handle != INVALID_HANDLE_VALUE) if (handle != INVALID_HANDLE_VALUE)
@ -154,8 +154,10 @@ String SwappedStateFromName(Arena *arena, String name)
void WriteSwappedState(String name, String data) void WriteSwappedState(String name, String data)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
/* TODO: Use directory non-relative to executable */
CreateDirectoryW(L"ppswap", 0);
String result = ZI; String result = ZI;
String path = StringF(scratch.arena, "swap/%F.swp", FmtString(name)); String path = StringF(scratch.arena, "ppswap/%F.swp", FmtString(name));
wchar_t *path_wstr = WstrFromString(scratch.arena, path); 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); HANDLE handle = CreateFileW(path_wstr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (handle != INVALID_HANDLE_VALUE) if (handle != INVALID_HANDLE_VALUE)
@ -316,11 +318,6 @@ i32 W32_Main(void)
} }
/* Set up exit events */ /* Set up exit events */
#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->panic_event = CreateEventW(0, 1, 0, 0);
g->startup_end_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_begin_event = CreateEventW(0, 1, 0, 0);
@ -369,7 +366,6 @@ i32 W32_Main(void)
HANDLE handles[] = { HANDLE handles[] = {
g->exit_begin_event, g->exit_begin_event,
g->panic_event, g->panic_event,
g->swap_event,
}; };
DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE); DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
} }

View File

@ -38,7 +38,6 @@ Struct(W32_SharedState)
Atomic32 panicking; Atomic32 panicking;
wchar_t panic_wstr[4096]; wchar_t panic_wstr[4096];
HANDLE panic_event; HANDLE panic_event;
HANDLE swap_event;
HANDLE startup_end_event; HANDLE startup_end_event;
HANDLE exit_begin_event; HANDLE exit_begin_event;
HANDLE exit_end_event; HANDLE exit_end_event;

View File

@ -100,36 +100,6 @@ LineCol LineColFromPos(String data, i64 pos)
return result; 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 //~ OS command job
@ -905,8 +875,6 @@ JobDef(Build, _, __)
} }
} }
u64 swap_start = SignalSwapStart();
////////////////////////////// //////////////////////////////
//- Args //- Args
@ -1085,9 +1053,14 @@ JobDef(Build, _, __)
//- Link //- Link
WaitForSwapEnd(swap_start, NsFromSeconds(0.5f / 1000.f));
String exe_file = Lit("pp.exe"); String exe_file = Lit("pp.exe");
{
/* Wait for exe to become writable (once program closes) */
i64 timeout_ns = NsFromSeconds(0.5);
OS_File file = OS_OpenFile(exe_file, OS_FileFlag_Write, timeout_ns);
OS_CloseFile(file);
}
i64 link_elapsed_ns = 0; i64 link_elapsed_ns = 0;
if (ret == 0) if (ret == 0)
{ {

View File

@ -87,7 +87,7 @@ String F_ExtensionFromFile(String path)
String F_DataFromFile(Arena *arena, String path) String F_DataFromFile(Arena *arena, String path)
{ {
String result = ZI; String result = ZI;
OS_File file = OS_OpenFile(path, OS_FileFlag_Read); OS_File file = OS_OpenFile(path, OS_FileFlag_Read, I64Max);
result = OS_ReadEntireFile(arena, file); result = OS_ReadEntireFile(arena, file);
OS_CloseFile(file); OS_CloseFile(file);
return result; return result;
@ -98,7 +98,7 @@ String F_DataFromFile(Arena *arena, String path)
void F_ClearWrite(String path, String data) void F_ClearWrite(String path, String data)
{ {
OS_File file = OS_OpenFile(path, OS_FileFlag_Write | OS_FileFlag_Create); OS_File file = OS_OpenFile(path, OS_FileFlag_Write | OS_FileFlag_Create, I64Max);
OS_ClearWriteFile(file, data); OS_ClearWriteFile(file, data);
OS_CloseFile(file); OS_CloseFile(file);
} }

View File

@ -7,7 +7,6 @@ Enum(OS_FileFlag)
OS_FileFlag_Read = (1 << 0), OS_FileFlag_Read = (1 << 0),
OS_FileFlag_Write = (1 << 1), OS_FileFlag_Write = (1 << 1),
OS_FileFlag_Create = (1 << 2), OS_FileFlag_Create = (1 << 2),
OS_FileFlag_NoWait = (1 << 3)
}; };
Struct(OS_File) Struct(OS_File)
@ -32,7 +31,7 @@ void OS_Startup(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdecl File system operations //~ @hookdecl File system operations
OS_File OS_OpenFile(String path, OS_FileFlag flags); OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns);
void OS_CloseFile(OS_File file); void OS_CloseFile(OS_File file);
String OS_ReadEntireFile(Arena *arena, OS_File file); String OS_ReadEntireFile(Arena *arena, OS_File file);
void OS_ClearWriteFile(OS_File file, String data); void OS_ClearWriteFile(OS_File file, String data);

View File

@ -35,30 +35,29 @@ void OS_Startup(void)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdef File system hooks //~ @hookdef File system hooks
OS_File OS_OpenFile(String path, OS_FileFlag flags) OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
OS_File result = ZI; OS_File result = ZI;
wchar_t *path_wstr = WstrFromString(scratch.arena, path); wchar_t *path_wstr = WstrFromString(scratch.arena, path);
b32 wait_for_access = 1;
u32 share_mode = FILE_SHARE_READ; u32 share_mode = FILE_SHARE_READ;
u32 create_mode = OPEN_EXISTING; u32 create_mode = OPEN_EXISTING;
u32 access_flags = 0; u32 access_flags = 0;
if (flags & OS_FileFlag_Read) access_flags |= GENERIC_READ; if (flags & OS_FileFlag_Read) access_flags |= GENERIC_READ;
if (flags & OS_FileFlag_Write) access_flags |= GENERIC_WRITE; if (flags & OS_FileFlag_Write) access_flags |= GENERIC_WRITE;
if (flags & OS_FileFlag_Create) create_mode = OPEN_ALWAYS; if (flags & OS_FileFlag_Create) create_mode = OPEN_ALWAYS;
if (flags & OS_FileFlag_NoWait) wait_for_access = 0; i32 timeout_ms = timeout_ns / 1000000;
i32 elapsed_ms = 0;
i32 delay_ms = 1; i32 delay_ms = 1;
HANDLE handle; HANDLE handle = INVALID_HANDLE_VALUE;
while ((handle = CreateFileW(path_wstr, access_flags, share_mode, 0, create_mode, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE && wait_for_access) for (;;)
{ {
if (GetLastError() == ERROR_SHARING_VIOLATION) handle = CreateFileW(path_wstr, access_flags, share_mode, 0, create_mode, FILE_ATTRIBUTE_NORMAL, 0);
if (handle == INVALID_HANDLE_VALUE && elapsed_ms < timeout_ms && GetLastError() == ERROR_SHARING_VIOLATION)
{ {
Sleep(delay_ms); Sleep(delay_ms);
if (delay_ms < 1024) elapsed_ms += delay_ms;
{ delay_ms = MinI32(delay_ms * 2, 1024);
delay_ms *= 2;
}
} }
else else
{ {

View File

@ -92,7 +92,6 @@ ExitFuncDef(ShutdownUser)
SwappedUserState *swap = PushStruct(scratch.arena, SwappedUserState); SwappedUserState *swap = PushStruct(scratch.arena, SwappedUserState);
swap->s = *g; swap->s = *g;
WriteSwappedState(Lit("pp_user"), StringFromStruct(swap)); WriteSwappedState(Lit("pp_user"), StringFromStruct(swap));
EndScratch(scratch); EndScratch(scratch);
} }