artifact cache fixes, move ctrl process memory streaming to artifact cache

This commit is contained in:
Ryan Fleury
2025-09-25 10:35:47 -07:00
parent ca7bfab7ea
commit a338b3413e
6 changed files with 87 additions and 68 deletions
+12 -4
View File
@@ -81,14 +81,15 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
{
if(str8_match(n->key, key, 0))
{
if(ins_atomic_u64_eval(&n->completion_count) != 0 && (n->gen == params->gen || !(params->flags & AC_Flag_WaitForFresh)))
B32 is_stale = (n->gen != params->gen);
if(ins_atomic_u64_eval(&n->completion_count) != 0 && (!is_stale || !(params->flags & AC_Flag_WaitForFresh)))
{
got_artifact = 1;
artifact_is_stale = (n->gen == params->gen);
artifact_is_stale = is_stale;
artifact = n->val;
access_touch(access, &n->access_pt, stripe->cv);
}
if(n->gen != params->gen)
if(is_stale)
{
B32 got_task = (ins_atomic_u64_eval_cond_assign(&n->working_count, 1, 0) == 0);
need_request = got_task;
@@ -135,6 +136,8 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
node->key = str8_copy(stripe->arena, key);
node->working_count = 1;
node->evict_threshold_us = params->evict_threshold_us;
node->access_pt.last_time_touched_us = os_now_microseconds();
node->access_pt.last_update_idx_touched = update_tick_idx();
}
// rjf: request
@@ -304,6 +307,7 @@ ac_async_tick(void)
}
lane_sync_u64(&tasks, 0);
lane_sync_u64(&tasks_count, 0);
lane_sync();
//////////////////////////////
//- rjf: do all requests
@@ -318,6 +322,7 @@ ac_async_tick(void)
{
for EachIndex(idx, task->wide_count)
{
lane_sync();
AC_Request *r = &task->wide[idx];
// rjf: compute val
@@ -341,7 +346,7 @@ ac_async_tick(void)
// rjf: create function -> cache
AC_Cache *cache = 0;
if(!retry)
if(!retry && lane_idx() == 0)
{
U64 cache_hash = u64_hash_from_str8(str8_struct(&r->create));
U64 cache_slot_idx = cache_hash%ac_shared->cache_slots_count;
@@ -383,6 +388,7 @@ ac_async_tick(void)
}
}
}
lane_sync();
//- rjf: do all thin requests for this priority
ProfScope("thin requests (p%I64u)", task_idx)
@@ -462,7 +468,9 @@ ac_async_tick(void)
cond_var_broadcast(stripe->cv);
}
}
lane_sync();
}
lane_sync();
}
lane_sync();
+2 -2
View File
@@ -2,6 +2,7 @@
// Licensed under the MIT license (https://opensource.org/license/mit/)
global U64 global_update_tick_idx = 0;
global U64 async_threads_count = 0;
global CondVar async_tick_start_cond_var = {0};
global Mutex async_tick_start_mutex = {0};
global Mutex async_tick_stop_mutex = {0};
@@ -103,7 +104,6 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
//- rjf: launch async threads
Thread *async_threads = 0;
U64 async_threads_count = 0;
U64 lane_broadcast_val = 0;
{
U64 num_main_threads = 1;
@@ -121,7 +121,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
for EachIndex(idx, num_async_threads)
{
lane_ctxs[idx].lane_idx = idx;
lane_ctxs[idx].lane_count = num_async_threads;
lane_ctxs[idx].lane_count = async_threads_count;
lane_ctxs[idx].barrier = barrier;
lane_ctxs[idx].broadcast_memory = &lane_broadcast_val;
async_threads[idx] = thread_launch(async_thread_entry_point, &lane_ctxs[idx]);
+4 -2
View File
@@ -1866,7 +1866,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
{
U64 page_base_vaddr = page_range.min + page_idx*page_size;
B32 page_is_stale = 0;
C_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale);
C_Key page_key = ctrl_key_from_process_vaddr_range_new(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale);
U128 page_hash = c_hash_from_key(page_key, 0);
U128 page_last_hash = c_hash_from_key(page_key, 1);
result.stale = (result.stale || page_is_stale);
@@ -7610,13 +7610,15 @@ ctrl_key_from_process_vaddr_range_new(CTRL_Handle process, Rng1U64 vaddr_range,
CTRL_Handle process;
Rng1U64 vaddr_range;
B32 zero_terminated;
B32 _padding_;
} key_data = {process, vaddr_range, zero_terminated};
String8 key = str8_struct(&key_data);
Access *access = access_open();
AC_Artifact artifact = ac_artifact_from_key(access, key, ctrl_memory_artifact_create, ctrl_memory_artifact_destroy, endt_us,
.gen = ctrl_mem_gen(),
.slots_count = 2048,
.stale_out = out_is_stale);
.stale_out = out_is_stale,
.evict_threshold_us = 30000000);
C_Key content_key = {0};
MemoryCopyStruct(&content_key, &artifact);
access_close(access);
+68 -57
View File
@@ -31,16 +31,6 @@ fs_change_gen(void)
////////////////////////////////
//~ rjf: Cache Interaction
internal C_Key
fs_content_key_from_artifact_key(String8 key)
{
C_Key content_key = {0};
{
content_key.id.u128[0] = u128_hash_from_str8(key);
}
return content_key;
}
internal AC_Artifact
fs_artifact_create(String8 key, B32 *retry_out)
{
@@ -59,60 +49,75 @@ fs_artifact_create(String8 key, B32 *retry_out)
}
//- rjf: measure file properties *before* read
B32 file_is_good = 0;
FileProperties pre_props = {0};
if(lane_idx() == 0)
{
pre_props = os_properties_from_file_path(path);
file_is_good = (pre_props.modified != 0);
}
lane_sync_u64(&file_is_good, 0);
//- rjf: setup output data
Arena *data_arena = 0;
U64 data_buffer_size = 0;
U8 *data_buffer = 0;
if(lane_idx() == 0)
if(file_is_good)
{
U64 range_size = dim_1u64(range);
U64 read_size = Min(pre_props.size - range.min, range_size);
U64 data_arena_size = read_size+ARENA_HEADER_SIZE;
data_arena_size += KB(4)-1;
data_arena_size -= data_arena_size%KB(4);
data_arena = arena_alloc(.reserve_size = data_arena_size, .commit_size = data_arena_size);
data_buffer_size = read_size;
data_buffer = push_array_no_zero(data_arena, U8, data_buffer_size);
if(lane_idx() == 0)
{
U64 range_size = dim_1u64(range);
U64 read_size = Min(pre_props.size - range.min, range_size);
U64 data_arena_size = read_size+ARENA_HEADER_SIZE;
data_arena_size += KB(4)-1;
data_arena_size -= data_arena_size%KB(4);
data_arena = arena_alloc(.reserve_size = data_arena_size, .commit_size = data_arena_size);
data_buffer_size = read_size;
data_buffer = push_array_no_zero(data_arena, U8, data_buffer_size);
}
lane_sync_u64(&data_buffer, 0);
lane_sync_u64(&data_buffer_size, 0);
}
lane_sync_u64(&data_buffer, 0);
lane_sync_u64(&data_buffer_size, 0);
//- rjf: open file
OS_Handle file = {0};
if(lane_idx() == 0)
if(file_is_good)
{
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path);
if(lane_idx() == 0)
{
file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_ShareRead|OS_AccessFlag_ShareWrite, path);
}
lane_sync_u64(&file, 0);
}
lane_sync_u64(&file, 0);
B32 file_handle_is_valid = !os_handle_match(os_handle_zero(), file);
//- rjf: do read
U64 total_bytes_read = 0;
U64 *total_bytes_read_ptr = 0;
if(lane_idx() == 0)
if(file_handle_is_valid)
{
total_bytes_read_ptr = &total_bytes_read;
U64 *total_bytes_read_ptr = 0;
if(lane_idx() == 0)
{
total_bytes_read_ptr = &total_bytes_read;
}
lane_sync_u64(&total_bytes_read_ptr, 0);
ProfScope("read \"%.*s\" [0x%I64x, 0x%I64x)", str8_varg(path), range.min, range.max)
{
Rng1U64 lane_read_range = lane_range(data_buffer_size);
U64 bytes_read = os_file_read(file, shift_1u64(lane_read_range, range.min), data_buffer + lane_read_range.min);
ins_atomic_u64_add_eval(total_bytes_read_ptr, bytes_read);
}
lane_sync();
lane_sync_u64(&total_bytes_read, 0);
}
lane_sync_u64(&total_bytes_read_ptr, 0);
ProfScope("read \"%.*s\" [0x%I64x, 0x%I64x)", str8_varg(path), range.min, range.max)
{
Rng1U64 lane_read_range = lane_range(data_buffer_size);
U64 bytes_read = os_file_read(file, shift_1u64(lane_read_range, range.min), data_buffer + lane_read_range.min);
ins_atomic_u64_add_eval(total_bytes_read_ptr, bytes_read);
}
lane_sync();
lane_sync_u64(&total_bytes_read, 0);
//- rjf: close file
if(lane_idx() == 0)
if(file_handle_is_valid)
{
os_file_close(file);
if(lane_idx() == 0)
{
os_file_close(file);
}
}
//- rjf: measure file properties *after* read
@@ -123,35 +128,41 @@ fs_artifact_create(String8 key, B32 *retry_out)
}
//- rjf: form content key
C_Key content_key = fs_content_key_from_artifact_key(key);
C_Key content_key = {0};
{
content_key.id.u128[0] = u128_hash_from_str8(key);
}
//- rjf: abort if modification timestamps or sizes differ - we did not successfully read the file;
// otherwise submit data
B32 read_good = 0;
if(lane_idx() == 0)
if(file_is_good)
{
read_good = (pre_props.modified == post_props.modified &&
pre_props.size == post_props.size &&
data_buffer_size == total_bytes_read &&
(file_handle_is_valid || pre_props.flags & FilePropertyFlag_IsFolder));
if(!read_good)
if(lane_idx() == 0)
{
retry_out[0] = 1;
ProfScope("abort")
read_good = (pre_props.modified == post_props.modified &&
pre_props.size == post_props.size &&
data_buffer_size == total_bytes_read &&
(file_handle_is_valid || pre_props.flags & FilePropertyFlag_IsFolder));
if(!read_good)
{
arena_release(data_arena);
MemoryZeroStruct(&content_key);
}
}
else
{
ProfScope("submit")
{
c_submit_data(content_key, &data_arena, str8(data_buffer, data_buffer_size));
retry_out[0] = 1;
ProfScope("abort")
{
arena_release(data_arena);
MemoryZeroStruct(&content_key);
}
}
else
{
ProfScope("submit")
{
c_submit_data(content_key, &data_arena, str8(data_buffer, data_buffer_size));
}
}
}
lane_sync();
}
lane_sync();
//- rjf: if the read was good, record this path's timestamp in this layer's path info cache
U64 path_hash = u64_hash_from_str8(path);
-2
View File
@@ -55,8 +55,6 @@ internal U64 fs_change_gen(void);
////////////////////////////////
//~ rjf: Artifact Cache Hooks / Accessing API
internal C_Key fs_content_key_from_artifact_key(String8 key);
internal AC_Artifact fs_artifact_create(String8 key, B32 *retry_out);
internal void fs_artifact_destroy(AC_Artifact artifact);
+1 -1
View File
@@ -2160,7 +2160,7 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated)
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space);
if(entity->kind == CTRL_EntityKind_Process)
{
result = ctrl_key_from_process_vaddr_range(entity->handle, range, zero_terminated, 0, 0);
result = ctrl_key_from_process_vaddr_range_new(entity->handle, range, zero_terminated, 0, 0);
}
}break;
}