txti layer -> open files in write-shared mode, to prevent locking file from e.g. an editor which is writing; also only enable change detection when ui is actively updating

This commit is contained in:
Ryan Fleury
2024-01-18 10:04:00 -08:00
parent d2d72bd7ab
commit 3567e6c53d
8 changed files with 54 additions and 27 deletions
+3 -3
View File
@@ -499,7 +499,7 @@ dbgi_parse_thread_entry_point(void *p)
void *exe_file_base = 0;
if(do_task)
{
exe_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, exe_path);
exe_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, exe_path);
exe_file_props = os_properties_from_file(exe_file);
exe_file_map = os_file_map_open(OS_AccessFlag_Read, exe_file);
exe_file_base = os_file_map_view_open(exe_file_map, OS_AccessFlag_Read, r1u64(0, exe_file_props.size));
@@ -558,7 +558,7 @@ dbgi_parse_thread_entry_point(void *p)
FileProperties og_dbg_props = {0};
if(do_task) ProfScope("analyze O.G. dbg file")
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, og_dbg_path);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, og_dbg_path);
OS_Handle file_map = os_file_map_open(OS_AccessFlag_Read, file);
FileProperties props = og_dbg_props = os_properties_from_file(file);
void *base = os_file_map_view_open(file_map, OS_AccessFlag_Read, r1u64(0, props.size));
@@ -709,7 +709,7 @@ dbgi_parse_thread_entry_point(void *p)
void *raddbg_file_base = 0;
if(do_task && raddbg_file_is_up_to_date)
{
raddbg_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, raddbg_path);
raddbg_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, raddbg_path);
raddbg_file_map = os_file_map_open(OS_AccessFlag_Read, raddbg_file);
raddbg_file_props = os_properties_from_file(raddbg_file);
raddbg_file_base = os_file_map_view_open(raddbg_file_map, OS_AccessFlag_Read, r1u64(0, raddbg_file_props.size));
+2 -2
View File
@@ -7334,7 +7334,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
FileProperties props = {0};
String8 data = {0};
{
OS_Handle file = os_file_open(OS_AccessFlag_Shared|OS_AccessFlag_Read, new_path);
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, new_path);
props = os_properties_from_file(file);
data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size));
os_file_close(file);
@@ -7380,7 +7380,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{
DF_Entity *file_entity = cfg_files[src];
String8 path = df_full_path_from_entity(scratch.arena, file_entity);
OS_Handle file = os_file_open(OS_AccessFlag_Shared|OS_AccessFlag_Read, path);
OS_Handle file = os_file_open(OS_AccessFlag_ShareRead|OS_AccessFlag_Read, path);
FileProperties props = os_properties_from_file(file);
String8 data = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size));
if(data.size != 0)
+3 -3
View File
@@ -86,7 +86,7 @@ os_relaunch_self(void){
internal String8
os_data_from_file_path(Arena *arena, String8 path)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, path);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
FileProperties props = os_properties_from_file(file);
String8 data = os_string_from_file_range(arena, file, r1u64(0, props.size));
os_file_close(file);
@@ -129,7 +129,7 @@ os_write_data_list_to_file_path(String8 path, String8List list)
internal FileProperties
os_properties_from_file_path(String8 path)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, path);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
FileProperties props = os_properties_from_file(file);
os_file_close(file);
return props;
@@ -138,7 +138,7 @@ os_properties_from_file_path(String8 path)
internal OS_FileID
os_id_from_file_path(String8 path)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, path);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead, path);
OS_FileID id = os_id_from_file(file);
os_file_close(file);
return id;
+5 -4
View File
@@ -10,10 +10,11 @@
typedef U32 OS_AccessFlags;
enum
{
OS_AccessFlag_Read = (1<<0),
OS_AccessFlag_Write = (1<<1),
OS_AccessFlag_Execute = (1<<2),
OS_AccessFlag_Shared = (1<<3),
OS_AccessFlag_Read = (1<<0),
OS_AccessFlag_Write = (1<<1),
OS_AccessFlag_Execute = (1<<2),
OS_AccessFlag_ShareRead = (1<<3),
OS_AccessFlag_ShareWrite = (1<<4),
};
////////////////////////////////
+2 -1
View File
@@ -612,7 +612,8 @@ os_file_open(OS_AccessFlags flags, String8 path)
if(flags & OS_AccessFlag_Read) {access_flags |= GENERIC_READ;}
if(flags & OS_AccessFlag_Write) {access_flags |= GENERIC_WRITE;}
if(flags & OS_AccessFlag_Execute) {access_flags |= GENERIC_EXECUTE;}
if(flags & OS_AccessFlag_Shared) {share_mode = (!!(flags & OS_AccessFlag_Write)*FILE_SHARE_WRITE)|FILE_SHARE_READ;}
if(flags & OS_AccessFlag_ShareRead) {share_mode |= FILE_SHARE_READ;}
if(flags & OS_AccessFlag_ShareWrite) {share_mode |= FILE_SHARE_WRITE;}
if(flags & OS_AccessFlag_Write) {creation_disposition = CREATE_ALWAYS;}
HANDLE file = CreateFileW((WCHAR *)path16.str, access_flags, share_mode, 0, creation_disposition, FILE_ATTRIBUTE_NORMAL, 0);
if(file != INVALID_HANDLE_VALUE)
+9
View File
@@ -55,6 +55,12 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
//- rjf: target Hz -> delta time
F32 dt = 1.f/target_hz;
//- rjf: last frame before sleep -> disable txti change detection
if(df_gfx_state->num_frames_requested == 0)
{
txti_set_external_change_detection_enabled(0);
}
//- rjf: get events from the OS
OS_EventList events = {0};
if(os_handle_match(repaint_window_handle, os_handle_zero()))
@@ -62,6 +68,9 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data)
events = os_get_events(scratch.arena, df_gfx_state->num_frames_requested == 0);
}
//- rjf: enable txti change detection
txti_set_external_change_detection_enabled(1);
//- rjf: begin measuring actual per-frame work
U64 begin_time_us = os_now_microseconds();
+26 -14
View File
@@ -923,6 +923,15 @@ txti_append(TXTI_Handle handle, String8 string)
os_condition_variable_broadcast(mut_thread->msg_cv);
}
//- rjf: buffer external change detection enabling/disabling
internal void
txti_set_external_change_detection_enabled(B32 enabled)
{
U64 enabled_u64 = (U64)enabled;
ins_atomic_u64_eval_assign(&txti_state->detector_thread_enabled, enabled_u64);
}
////////////////////////////////
//~ rjf: Mutator Threads
@@ -972,7 +981,7 @@ txti_mut_thread_entry_point(void *p)
U64 timestamp = 0;
if(msg->kind == TXTI_MsgKind_Reload)
{
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Shared, msg->string);
OS_Handle file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, msg->string);
FileProperties props = os_properties_from_file(file);
timestamp = props.modified;
file_contents = os_string_from_file_range(scratch.arena, file, r1u64(0, props.size));
@@ -1228,23 +1237,26 @@ txti_detector_thread_entry_point(void *p)
ProfThreadName("[txti] detector");
for(;;)
{
U64 slots_per_stripe = txti_state->entity_map.slots_count/txti_state->entity_map_stripes.count;
for(U64 stripe_idx = 0; stripe_idx < txti_state->entity_map_stripes.count; stripe_idx += 1)
if(ins_atomic_u64_eval(&txti_state->detector_thread_enabled))
{
TXTI_Stripe *stripe = &txti_state->entity_map_stripes.v[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex) for(U64 slot_in_stripe_idx = 0; slot_in_stripe_idx < slots_per_stripe; slot_in_stripe_idx += 1)
U64 slots_per_stripe = txti_state->entity_map.slots_count/txti_state->entity_map_stripes.count;
for(U64 stripe_idx = 0; stripe_idx < txti_state->entity_map_stripes.count; stripe_idx += 1)
{
U64 slot_idx = stripe_idx*slots_per_stripe + slot_in_stripe_idx;
TXTI_EntitySlot *slot = &txti_state->entity_map.slots[slot_idx];
for(TXTI_Entity *entity = slot->first; entity != 0; entity = entity->next)
TXTI_Stripe *stripe = &txti_state->entity_map_stripes.v[stripe_idx];
OS_MutexScopeR(stripe->rw_mutex) for(U64 slot_in_stripe_idx = 0; slot_in_stripe_idx < slots_per_stripe; slot_in_stripe_idx += 1)
{
FileProperties props = os_properties_from_file_path(entity->path);
U64 entity_timestamp = entity->timestamp;
if(props.modified != entity_timestamp && ins_atomic_u64_eval(&entity->working_count) == 0)
U64 slot_idx = stripe_idx*slots_per_stripe + slot_in_stripe_idx;
TXTI_EntitySlot *slot = &txti_state->entity_map.slots[slot_idx];
for(TXTI_Entity *entity = slot->first; entity != 0; entity = entity->next)
{
TXTI_Handle handle = {txti_hash_from_string(entity->path), entity->id};
txti_reload(handle, entity->path);
ins_atomic_u64_inc_eval(&entity->working_count);
FileProperties props = os_properties_from_file_path(entity->path);
U64 entity_timestamp = entity->timestamp;
if(props.modified != entity_timestamp && ins_atomic_u64_eval(&entity->working_count) == 0)
{
TXTI_Handle handle = {txti_hash_from_string(entity->path), entity->id};
txti_reload(handle, entity->path);
ins_atomic_u64_inc_eval(&entity->working_count);
}
}
}
}
+4
View File
@@ -322,6 +322,7 @@ struct TXTI_State
TXTI_MutThread *mut_threads;
// rjf: detector thread
U64 detector_thread_enabled;
OS_Handle detector_thread;
};
@@ -379,6 +380,9 @@ internal TxtRng txti_expr_range_from_handle_pt(TXTI_Handle handle, TxtPt pt);
internal void txti_reload(TXTI_Handle handle, String8 path);
internal void txti_append(TXTI_Handle handle, String8 string);
//- rjf: buffer external change detection enabling/disabling
internal void txti_set_external_change_detection_enabled(B32 enabled);
////////////////////////////////
//~ rjf: Mutator Threads