bucket artifact cache requests by wideness/priority; do high/wide, high/thin, low/wide, low/thin

This commit is contained in:
Ryan Fleury
2025-09-24 17:08:08 -07:00
parent 10e8a10d9b
commit ca7bfab7ea
12 changed files with 289 additions and 121 deletions
+212 -70
View File
@@ -13,8 +13,11 @@ ac_init(void)
ac_shared->cache_slots_count = 256; ac_shared->cache_slots_count = 256;
ac_shared->cache_slots = push_array(arena, AC_Cache *, ac_shared->cache_slots_count); ac_shared->cache_slots = push_array(arena, AC_Cache *, ac_shared->cache_slots_count);
ac_shared->cache_stripes = stripe_array_alloc(arena); ac_shared->cache_stripes = stripe_array_alloc(arena);
ac_shared->req_mutex = mutex_alloc(); for EachElement(idx, ac_shared->req_batches)
ac_shared->req_arena = arena_alloc(); {
ac_shared->req_batches[idx].mutex = mutex_alloc();
ac_shared->req_batches[idx].arena = arena_alloc();
}
} }
//////////////////////////////// ////////////////////////////////
@@ -23,6 +26,8 @@ ac_init(void)
internal AC_Artifact internal AC_Artifact
ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U64 endt_us) ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U64 endt_us)
{ {
AC_RequestBatch *req_batch = &ac_shared->req_batches[params->flags & AC_Flag_HighPriority ? 0 : 1];
//- rjf: create function -> cache //- rjf: create function -> cache
AC_Cache *cache = 0; AC_Cache *cache = 0;
{ {
@@ -76,7 +81,7 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
{ {
if(str8_match(n->key, key, 0)) if(str8_match(n->key, key, 0))
{ {
if(ins_atomic_u64_eval(&n->completion_count) != 0 && (n->gen == params->gen || !params->wait_for_fresh)) if(ins_atomic_u64_eval(&n->completion_count) != 0 && (n->gen == params->gen || !(params->flags & AC_Flag_WaitForFresh)))
{ {
got_artifact = 1; got_artifact = 1;
artifact_is_stale = (n->gen == params->gen); artifact_is_stale = (n->gen == params->gen);
@@ -129,18 +134,27 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
// TODO(rjf): string allocator for keys // TODO(rjf): string allocator for keys
node->key = str8_copy(stripe->arena, key); node->key = str8_copy(stripe->arena, key);
node->working_count = 1; node->working_count = 1;
node->evict_threshold_us = params->evict_threshold_us;
} }
// rjf: request // rjf: request
if(need_request) if(need_request)
{ {
need_request = 0; need_request = 0;
MutexScope(ac_shared->req_mutex) MutexScope(req_batch->mutex)
{ {
AC_RequestNode *n = push_array(ac_shared->req_arena, AC_RequestNode, 1); AC_RequestNode *n = push_array(req_batch->arena, AC_RequestNode, 1);
SLLQueuePush(ac_shared->first_req, ac_shared->last_req, n); if(params->flags & AC_Flag_Wide)
ac_shared->req_count += 1; {
n->v.key = str8_copy(ac_shared->req_arena, key); SLLQueuePush(req_batch->first_wide, req_batch->last_wide, n);
req_batch->wide_count += 1;
}
else
{
SLLQueuePush(req_batch->first_thin, req_batch->last_thin, n);
req_batch->thin_count += 1;
}
n->v.key = str8_copy(req_batch->arena, key);
n->v.gen = params->gen; n->v.gen = params->gen;
n->v.create = params->create; n->v.create = params->create;
} }
@@ -149,7 +163,7 @@ ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U6
} }
// rjf: get value from node, if possible // rjf: get value from node, if possible
if(!got_artifact && ins_atomic_u64_eval(&node->completion_count) != 0 && ((node->gen == params->gen) || !params->wait_for_fresh || out_of_time)) if(!got_artifact && ins_atomic_u64_eval(&node->completion_count) != 0 && ((node->gen == params->gen) || !(params->flags & AC_Flag_WaitForFresh) || out_of_time))
{ {
got_artifact = 1; got_artifact = 1;
artifact_is_stale = (node->gen == params->gen); artifact_is_stale = (node->gen == params->gen);
@@ -185,7 +199,9 @@ ac_async_tick(void)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
//////////////////////////////
//- rjf: do eviction pass across all caches //- rjf: do eviction pass across all caches
//
for EachIndex(cache_slot_idx, ac_shared->cache_slots_count) for EachIndex(cache_slot_idx, ac_shared->cache_slots_count)
{ {
Stripe *cache_stripe = stripe_from_slot_idx(&ac_shared->cache_stripes, cache_slot_idx); Stripe *cache_stripe = stripe_from_slot_idx(&ac_shared->cache_stripes, cache_slot_idx);
@@ -206,7 +222,7 @@ ac_async_tick(void)
for(AC_Node *n = slot->first, *next = 0; n != 0; n = next) for(AC_Node *n = slot->first, *next = 0; n != 0; n = next)
{ {
next = n->next; next = n->next;
if(access_pt_is_expired(&n->access_pt) && ins_atomic_u64_eval(&n->working_count) == 0) if(access_pt_is_expired(&n->access_pt, .time = n->evict_threshold_us) && ins_atomic_u64_eval(&n->working_count) == 0)
{ {
slot_has_work = 1; slot_has_work = 1;
if(!write_mode) if(!write_mode)
@@ -236,90 +252,216 @@ ac_async_tick(void)
} }
} }
//- rjf: gather all requests //////////////////////////////
local_persist AC_Request *reqs = 0; //- rjf: gather requests
local_persist U64 reqs_count = 0; //
if(lane_idx() == 0) MutexScope(ac_shared->req_mutex) typedef struct RequestBatchTask RequestBatchTask;
struct RequestBatchTask
{ {
reqs_count = ac_shared->req_count; AC_Request *wide;
reqs = push_array(scratch.arena, AC_Request, reqs_count); U64 wide_count;
U64 idx = 0; AC_Request *thin;
for EachNode(r, AC_RequestNode, ac_shared->first_req) U64 thin_count;
};
RequestBatchTask *tasks = 0;
U64 tasks_count = 0;
if(lane_idx() == 0)
{
tasks_count = 2;
tasks = push_array(scratch.arena, RequestBatchTask, tasks_count);
for EachElement(task_idx, ac_shared->req_batches)
{ {
MemoryCopyStruct(&reqs[idx], &r->v); AC_RequestBatch *batch = &ac_shared->req_batches[task_idx];
reqs[idx].key = str8_copy(scratch.arena, reqs[idx].key); MutexScope(batch->mutex)
idx += 1; {
tasks[task_idx].wide_count = batch->wide_count;
tasks[task_idx].thin_count = batch->thin_count;
tasks[task_idx].wide = push_array(scratch.arena, AC_Request, tasks[task_idx].wide_count);
tasks[task_idx].thin = push_array(scratch.arena, AC_Request, tasks[task_idx].thin_count);
{
U64 idx = 0;
for EachNode(n, AC_RequestNode, batch->first_wide)
{
MemoryCopyStruct(&tasks[task_idx].wide[idx], &n->v);
tasks[task_idx].wide[idx].key = str8_copy(scratch.arena, tasks[task_idx].wide[idx].key);
idx += 1;
}
}
{
U64 idx = 0;
for EachNode(n, AC_RequestNode, batch->first_thin)
{
MemoryCopyStruct(&tasks[task_idx].thin[idx], &n->v);
tasks[task_idx].thin[idx].key = str8_copy(scratch.arena, tasks[task_idx].thin[idx].key);
idx += 1;
}
}
arena_clear(batch->arena);
batch->first_wide = batch->last_wide = batch->first_thin = batch->last_thin = 0;
batch->wide_count = batch->thin_count = 0;
}
} }
arena_clear(ac_shared->req_arena);
ac_shared->first_req = ac_shared->last_req = 0;
ac_shared->req_count = 0;
} }
lane_sync(); lane_sync_u64(&tasks, 0);
lane_sync_u64(&tasks_count, 0);
//- rjf: do all requests on all lanes //////////////////////////////
for EachIndex(idx, reqs_count) //- rjf: do all requests
//
for EachIndex(task_idx, tasks_count)
{ {
lane_sync(); lane_sync();
RequestBatchTask *task = &tasks[task_idx];
// rjf: compute val //- rjf: do all wide requests for this priority
B32 retry = 0; ProfScope("wide requests (p%I64u)", task_idx)
AC_Artifact val = reqs[idx].create(reqs[idx].key, &retry);
// rjf: retry? -> resubmit request
if(retry && lane_idx() == 0)
{ {
MutexScope(ac_shared->req_mutex) for EachIndex(idx, task->wide_count)
{ {
AC_RequestNode *n = push_array(ac_shared->req_arena, AC_RequestNode, 1); AC_Request *r = &task->wide[idx];
SLLQueuePush(ac_shared->first_req, ac_shared->last_req, n);
ac_shared->req_count += 1; // rjf: compute val
MemoryCopyStruct(&n->v, &reqs[idx]); B32 retry = 0;
n->v.key = str8_copy(ac_shared->req_arena, n->v.key); AC_Artifact val = r->create(r->key, &retry);
}
ins_atomic_u32_eval_assign(&async_loop_again, 1); // rjf: retry? -> resubmit request
} if(retry && lane_idx() == 0)
// rjf: create function -> cache
AC_Cache *cache = 0;
if(!retry)
{
U64 cache_hash = u64_hash_from_str8(str8_struct(&reqs[idx].create));
U64 cache_slot_idx = cache_hash%ac_shared->cache_slots_count;
Stripe *cache_stripe = stripe_from_slot_idx(&ac_shared->cache_stripes, cache_slot_idx);
RWMutexScope(cache_stripe->rw_mutex, 0)
{
for(AC_Cache *c = ac_shared->cache_slots[cache_slot_idx]; c != 0; c = c->next)
{ {
if(c->create == reqs[idx].create) AC_RequestBatch *batch = &ac_shared->req_batches[task_idx];
MutexScope(batch->mutex)
{ {
cache = c; AC_RequestNode *n = push_array(batch->arena, AC_RequestNode, 1);
break; SLLQueuePush(batch->first_wide, batch->last_wide, n);
batch->wide_count += 1;
MemoryCopyStruct(&n->v, r);
n->v.key = str8_copy(batch->arena, n->v.key);
} }
ins_atomic_u32_eval_assign(&async_loop_again, 1);
}
// rjf: create function -> cache
AC_Cache *cache = 0;
if(!retry)
{
U64 cache_hash = u64_hash_from_str8(str8_struct(&r->create));
U64 cache_slot_idx = cache_hash%ac_shared->cache_slots_count;
Stripe *cache_stripe = stripe_from_slot_idx(&ac_shared->cache_stripes, cache_slot_idx);
RWMutexScope(cache_stripe->rw_mutex, 0)
{
for(AC_Cache *c = ac_shared->cache_slots[cache_slot_idx]; c != 0; c = c->next)
{
if(c->create == r->create)
{
cache = c;
break;
}
}
}
}
// rjf: write value into cache
if(!retry && lane_idx() == 0)
{
U64 hash = u64_hash_from_str8(r->key);
U64 slot_idx = hash%cache->slots_count;
AC_Slot *slot = &cache->slots[slot_idx];
Stripe *stripe = stripe_from_slot_idx(&cache->stripes, slot_idx);
RWMutexScope(stripe->rw_mutex, 1)
{
for(AC_Node *n = slot->first; n != 0; n = n->next)
{
if(str8_match(n->key, r->key, 0))
{
n->gen = r->gen;
n->val = val;
ins_atomic_u64_dec_eval(&n->working_count);
ins_atomic_u64_inc_eval(&n->completion_count);
}
}
}
cond_var_broadcast(stripe->cv);
} }
} }
} }
// rjf: write value into cache //- rjf: do all thin requests for this priority
if(!retry && lane_idx() == 0) ProfScope("thin requests (p%I64u)", task_idx)
{ {
U64 hash = u64_hash_from_str8(reqs[idx].key); U64 req_take_counter = 0;
U64 slot_idx = hash%cache->slots_count; U64 *req_take_counter_ptr = 0;
AC_Slot *slot = &cache->slots[slot_idx]; if(lane_idx() == 0)
Stripe *stripe = stripe_from_slot_idx(&cache->stripes, slot_idx);
RWMutexScope(stripe->rw_mutex, 1)
{ {
for(AC_Node *n = slot->first; n != 0; n = n->next) req_take_counter_ptr = &req_take_counter;
}
lane_sync_u64(&req_take_counter_ptr, 0);
for(;;)
{
U64 req_idx = ins_atomic_u64_inc_eval(req_take_counter_ptr) - 1;
if(req_idx >= task->thin_count) { break; }
AC_Request *r = &task->thin[req_idx];
// rjf: compute val
B32 retry = 0;
AC_Artifact val = r->create(r->key, &retry);
// rjf: retry? -> resubmit request
if(retry)
{ {
if(str8_match(n->key, reqs[idx].key, 0)) AC_RequestBatch *batch = &ac_shared->req_batches[task_idx];
MutexScope(batch->mutex)
{ {
n->gen = reqs[idx].gen; AC_RequestNode *n = push_array(batch->arena, AC_RequestNode, 1);
n->val = val; SLLQueuePush(batch->first_thin, batch->last_thin, n);
ins_atomic_u64_dec_eval(&n->working_count); batch->thin_count += 1;
ins_atomic_u64_inc_eval(&n->completion_count); MemoryCopyStruct(&n->v, r);
n->v.key = str8_copy(batch->arena, n->v.key);
}
ins_atomic_u32_eval_assign(&async_loop_again, 1);
}
// rjf: create function -> cache
AC_Cache *cache = 0;
if(!retry)
{
U64 cache_hash = u64_hash_from_str8(str8_struct(&r->create));
U64 cache_slot_idx = cache_hash%ac_shared->cache_slots_count;
Stripe *cache_stripe = stripe_from_slot_idx(&ac_shared->cache_stripes, cache_slot_idx);
RWMutexScope(cache_stripe->rw_mutex, 0)
{
for(AC_Cache *c = ac_shared->cache_slots[cache_slot_idx]; c != 0; c = c->next)
{
if(c->create == r->create)
{
cache = c;
break;
}
}
} }
} }
// rjf: write value into cache
if(!retry)
{
U64 hash = u64_hash_from_str8(r->key);
U64 slot_idx = hash%cache->slots_count;
AC_Slot *slot = &cache->slots[slot_idx];
Stripe *stripe = stripe_from_slot_idx(&cache->stripes, slot_idx);
RWMutexScope(stripe->rw_mutex, 1)
{
for(AC_Node *n = slot->first; n != 0; n = n->next)
{
if(str8_match(n->key, r->key, 0))
{
n->gen = r->gen;
n->val = val;
ins_atomic_u64_dec_eval(&n->working_count);
ins_atomic_u64_inc_eval(&n->completion_count);
}
}
}
cond_var_broadcast(stripe->cv);
}
} }
cond_var_broadcast(stripe->cv);
} }
} }
lane_sync(); lane_sync();
+27 -7
View File
@@ -19,6 +19,15 @@ struct AC_Artifact
typedef AC_Artifact AC_CreateFunctionType(String8 key, B32 *retry_out); typedef AC_Artifact AC_CreateFunctionType(String8 key, B32 *retry_out);
typedef void AC_DestroyFunctionType(AC_Artifact artifact); typedef void AC_DestroyFunctionType(AC_Artifact artifact);
typedef U32 AC_Flags;
typedef enum AC_FlagsEnum
{
AC_Flag_WaitForFresh = (1<<0),
AC_Flag_HighPriority = (1<<1),
AC_Flag_Wide = (1<<2),
}
AC_FlagsEnum;
typedef struct AC_ArtifactParams AC_ArtifactParams; typedef struct AC_ArtifactParams AC_ArtifactParams;
struct AC_ArtifactParams struct AC_ArtifactParams
{ {
@@ -26,8 +35,9 @@ struct AC_ArtifactParams
AC_DestroyFunctionType *destroy; AC_DestroyFunctionType *destroy;
U64 slots_count; U64 slots_count;
U64 gen; U64 gen;
B32 wait_for_fresh; U64 evict_threshold_us;
B32 *stale_out; B32 *stale_out;
AC_Flags flags;
}; };
//////////////////////////////// ////////////////////////////////
@@ -63,6 +73,7 @@ struct AC_Node
AccessPt access_pt; AccessPt access_pt;
U64 working_count; U64 working_count;
U64 completion_count; U64 completion_count;
U64 evict_threshold_us;
}; };
typedef struct AC_Slot AC_Slot; typedef struct AC_Slot AC_Slot;
@@ -86,6 +97,19 @@ struct AC_Cache
StripeArray stripes; StripeArray stripes;
}; };
typedef struct AC_RequestBatch AC_RequestBatch;
struct AC_RequestBatch
{
Mutex mutex;
Arena *arena;
AC_RequestNode *first_wide;
AC_RequestNode *last_wide;
AC_RequestNode *first_thin;
AC_RequestNode *last_thin;
U64 wide_count;
U64 thin_count;
};
typedef struct AC_Shared AC_Shared; typedef struct AC_Shared AC_Shared;
struct AC_Shared struct AC_Shared
{ {
@@ -97,11 +121,7 @@ struct AC_Shared
StripeArray cache_stripes; StripeArray cache_stripes;
// rjf: requests // rjf: requests
Mutex req_mutex; AC_RequestBatch req_batches[2]; // 0: high priority, 1: low priority
Arena *req_arena;
AC_RequestNode *first_req;
AC_RequestNode *last_req;
U64 req_count;
}; };
//////////////////////////////// ////////////////////////////////
@@ -118,7 +138,7 @@ internal void ac_init(void);
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal AC_Artifact ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U64 endt_us); internal AC_Artifact ac_artifact_from_key_(Access *access, String8 key, AC_ArtifactParams *params, U64 endt_us);
#define ac_artifact_from_key(access, key, create_fn, destroy_fn, endt_us, ...) ac_artifact_from_key_((access), (key), &(AC_ArtifactParams){.create = (create_fn), .destroy = (destroy_fn), __VA_ARGS__}, (endt_us)) #define ac_artifact_from_key(access, key, create_fn, destroy_fn, endt_us, ...) ac_artifact_from_key_((access), (key), &(AC_ArtifactParams){.create = (create_fn), .destroy = (destroy_fn), .evict_threshold_us = (2000000), __VA_ARGS__}, (endt_us))
//////////////////////////////// ////////////////////////////////
//~ rjf: Asynchronous Tick //~ rjf: Asynchronous Tick
+3 -3
View File
@@ -213,13 +213,13 @@ access_touch(Access *access, AccessPt *pt, CondVar cv)
//- rjf: access points //- rjf: access points
internal B32 internal B32
access_pt_is_expired(AccessPt *pt) access_pt_is_expired_(AccessPt *pt, AccessPtExpireParams *params)
{ {
U64 access_refcount = ins_atomic_u64_eval(&pt->access_refcount); U64 access_refcount = ins_atomic_u64_eval(&pt->access_refcount);
U64 last_time_touched_us = ins_atomic_u64_eval(&pt->last_time_touched_us); U64 last_time_touched_us = ins_atomic_u64_eval(&pt->last_time_touched_us);
U64 last_update_idx_touched = ins_atomic_u64_eval(&pt->last_update_idx_touched); U64 last_update_idx_touched = ins_atomic_u64_eval(&pt->last_update_idx_touched);
B32 result = (access_refcount == 0 && B32 result = (access_refcount == 0 &&
last_time_touched_us + 2000000 < os_now_microseconds() && last_time_touched_us + params->time < os_now_microseconds() &&
last_update_idx_touched + 10 < update_tick_idx()); last_update_idx_touched + params->update_idxs < update_tick_idx());
return result; return result;
} }
+9 -1
View File
@@ -27,6 +27,13 @@ struct AccessPt
U64 last_update_idx_touched; U64 last_update_idx_touched;
}; };
typedef struct AccessPtExpireParams AccessPtExpireParams;
struct AccessPtExpireParams
{
U64 time;
U64 update_idxs;
};
typedef struct Touch Touch; typedef struct Touch Touch;
struct Touch struct Touch
{ {
@@ -112,7 +119,8 @@ internal void access_close(Access *access);
internal void access_touch(Access *access, AccessPt *pt, CondVar cv); internal void access_touch(Access *access, AccessPt *pt, CondVar cv);
//- rjf: access points //- rjf: access points
internal B32 access_pt_is_expired(AccessPt *pt); internal B32 access_pt_is_expired_(AccessPt *pt, AccessPtExpireParams *params);
#define access_pt_is_expired(pt, ...) access_pt_is_expired_((pt), &(AccessPtExpireParams){.time = 2000000, .update_idxs = 10, __VA_ARGS__})
//- rjf: progress counters //- rjf: progress counters
#define set_progress_ptr(ptr) (tctx_selected()->progress_counter_ptr = (ptr)) #define set_progress_ptr(ptr) (tctx_selected()->progress_counter_ptr = (ptr))
+8 -10
View File
@@ -7467,7 +7467,6 @@ internal AC_Artifact
ctrl_memory_artifact_create(String8 key, B32 *retry_out) ctrl_memory_artifact_create(String8 key, B32 *retry_out)
{ {
AC_Artifact artifact = {0}; AC_Artifact artifact = {0};
if(lane_idx() == 0)
{ {
//- rjf: unpack key //- rjf: unpack key
CTRL_Handle process = {0}; CTRL_Handle process = {0};
@@ -7591,10 +7590,6 @@ ctrl_memory_artifact_create(String8 key, B32 *retry_out)
StaticAssert(sizeof(content_key) == sizeof(artifact), artifact_key_size_check); StaticAssert(sizeof(content_key) == sizeof(artifact), artifact_key_size_check);
MemoryCopyStruct(&artifact, &content_key); MemoryCopyStruct(&artifact, &content_key);
} }
lane_sync_u64(&artifact.u64[0], 0);
lane_sync_u64(&artifact.u64[1], 0);
lane_sync_u64(&artifact.u64[2], 0);
lane_sync_u64(&artifact.u64[3], 0);
return artifact; return artifact;
} }
@@ -7618,7 +7613,10 @@ ctrl_key_from_process_vaddr_range_new(CTRL_Handle process, Rng1U64 vaddr_range,
} key_data = {process, vaddr_range, zero_terminated}; } key_data = {process, vaddr_range, zero_terminated};
String8 key = str8_struct(&key_data); String8 key = str8_struct(&key_data);
Access *access = access_open(); 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); 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);
C_Key content_key = {0}; C_Key content_key = {0};
MemoryCopyStruct(&content_key, &artifact); MemoryCopyStruct(&content_key, &artifact);
access_close(access); access_close(access);
@@ -7633,7 +7631,6 @@ internal AC_Artifact
ctrl_call_stack_artifact_create(String8 key, B32 *retry_out) ctrl_call_stack_artifact_create(String8 key, B32 *retry_out)
{ {
AC_Artifact artifact = {0}; AC_Artifact artifact = {0};
if(lane_idx() == 0)
{ {
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
@@ -7785,8 +7782,6 @@ ctrl_call_stack_artifact_create(String8 key, B32 *retry_out)
scratch_end(scratch); scratch_end(scratch);
} }
lane_sync_u64(&artifact.u64[0], 0);
lane_sync_u64(&artifact.u64[1], 0);
return artifact; return artifact;
} }
@@ -7805,7 +7800,10 @@ ctrl_call_stack_from_thread_new(Access *access, CTRL_Handle thread_handle, B32 h
{ {
CTRL_CallStack result = {0}; CTRL_CallStack result = {0};
{ {
AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&thread_handle), ctrl_call_stack_artifact_create, ctrl_call_stack_artifact_destroy, endt_us, .gen = ctrl_mem_gen() + ctrl_reg_gen()); AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&thread_handle), ctrl_call_stack_artifact_create, ctrl_call_stack_artifact_destroy, endt_us,
.gen = ctrl_mem_gen() + ctrl_reg_gen(),
.evict_threshold_us = 10000000,
.flags = high_priority ? AC_Flag_HighPriority : 0);
if(artifact.u64[1] != 0) if(artifact.u64[1] != 0)
{ {
MemoryCopyStruct(&result, (CTRL_CallStack *)artifact.u64[1]); MemoryCopyStruct(&result, (CTRL_CallStack *)artifact.u64[1]);
+6 -6
View File
@@ -1208,13 +1208,13 @@ d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count)
} }
else else
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, thread->handle, 1, 0); CTRL_CallStack callstack = ctrl_call_stack_from_thread_new(access, thread->handle, 1, 0);
if(callstack.concrete_frames_count != 0) if(callstack.concrete_frames_count != 0)
{ {
result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs); result = regs_rip_from_arch_block(thread->arch, callstack.concrete_frames[unwind_count%callstack.concrete_frames_count]->regs);
} }
ctrl_scope_close(ctrl_scope); access_close(access);
} }
return result; return result;
} }
@@ -1886,10 +1886,10 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break; case D_CmdKind_StepOverLine: {traps = d_trap_net_from_thread__step_over_line(scratch.arena, thread);}break;
case D_CmdKind_StepOut: case D_CmdKind_StepOut:
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
// rjf: thread => call stack // rjf: thread => call stack
CTRL_CallStack callstack = ctrl_call_stack_from_thread(ctrl_scope, thread->handle, 1, os_now_microseconds()+10000); CTRL_CallStack callstack = ctrl_call_stack_from_thread_new(access, thread->handle, 1, os_now_microseconds()+10000);
// rjf: use first unwind frame to generate trap // rjf: use first unwind frame to generate trap
if(callstack.concrete_frames_count > 1) if(callstack.concrete_frames_count > 1)
@@ -1904,7 +1904,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P
good = 0; good = 0;
} }
ctrl_scope_close(ctrl_scope); access_close(access);
}break; }break;
} }
if(good && traps.count != 0) if(good && traps.count != 0)
+1 -1
View File
@@ -512,7 +512,7 @@ dasm_info_from_hash_params(Access *access, U128 hash, DASM_Params *params)
String8 key = str8_list_join(scratch.arena, &key_parts, 0); String8 key = str8_list_join(scratch.arena, &key_parts, 0);
// rjf: get info // rjf: get info
AC_Artifact artifact = ac_artifact_from_key(access, key, dasm_artifact_create, dasm_artifact_destroy, 0, .gen = fs_change_gen()); AC_Artifact artifact = ac_artifact_from_key(access, key, dasm_artifact_create, dasm_artifact_destroy, 0, .gen = fs_change_gen(), .flags = AC_Flag_Wide);
DASM_Artifact *dasm_artifact = (DASM_Artifact *)artifact.u64[0]; DASM_Artifact *dasm_artifact = (DASM_Artifact *)artifact.u64[0];
if(dasm_artifact) if(dasm_artifact)
{ {
+1 -1
View File
@@ -244,7 +244,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
} }
//- rjf: map to artifact //- rjf: map to artifact
AC_Artifact artifact = ac_artifact_from_key(access, key, fs_artifact_create, fs_artifact_destroy, endt_us, .gen = gen); AC_Artifact artifact = ac_artifact_from_key(access, key, fs_artifact_create, fs_artifact_destroy, endt_us, .gen = gen, .flags = AC_Flag_Wide);
MemoryCopyStruct(&result, &artifact); MemoryCopyStruct(&result, &artifact);
} }
access_close(access); access_close(access);
+12 -12
View File
@@ -1816,8 +1816,8 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
}break; }break;
case CTRL_EntityKind_Thread: case CTRL_EntityKind_Thread:
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity->handle, 1, rd_state->frame_eval_memread_endt_us); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, entity->handle, 1, rd_state->frame_eval_memread_endt_us);
U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count; U64 concrete_frame_idx = e_interpret_ctx->reg_unwind_count;
if(concrete_frame_idx < call_stack.concrete_frames_count) if(concrete_frame_idx < call_stack.concrete_frames_count)
{ {
@@ -1829,7 +1829,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size); MemoryCopy(out, (U8 *)f->regs + read_range.min, read_size);
result = (read_size == dim_1u64(range)); result = (read_size == dim_1u64(range));
} }
ctrl_scope_close(ctrl_scope); access_close(access);
}break; }break;
} }
}break; }break;
@@ -6464,12 +6464,12 @@ rd_window_frame(void)
// rjf: unwind // rjf: unwind
if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code) if(ctrl_entity->kind == CTRL_EntityKind_Thread) RD_Font(RD_FontSlot_Code)
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
Vec4F32 code_color = ui_color_from_name(str8_lit("code_default")); Vec4F32 code_color = ui_color_from_name(str8_lit("code_default"));
Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol"));
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(ctrl_entity, CTRL_EntityKind_Process);
B32 call_stack_high_priority = ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread); B32 call_stack_high_priority = ctrl_handle_match(ctrl_entity->handle, rd_base_regs()->thread);
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, ctrl_entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, ctrl_entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0);
if(call_stack.frames_count != 0) if(call_stack.frames_count != 0)
{ {
ui_spacer(ui_em(1.5f, 1.f)); ui_spacer(ui_em(1.5f, 1.f));
@@ -6486,7 +6486,7 @@ rd_window_frame(void)
String8 rip_value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, rip_eval); String8 rip_value_string = rd_value_string_from_eval(scratch.arena, str8_zero(), &string_params, ui_top_font(), ui_top_font_size(), ui_top_font_size()*40.f, rip_eval);
rd_code_label(1, 0, code_color, rip_value_string); rd_code_label(1, 0, code_color, rip_value_string);
} }
ctrl_scope_close(ctrl_scope); access_close(access);
} }
}break; }break;
@@ -16258,9 +16258,9 @@ rd_frame(void)
}break; }break;
case RD_CmdKind_SelectUnwind: case RD_CmdKind_SelectUnwind:
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread->handle, 1, os_now_microseconds()+10000); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, thread->handle, 1, os_now_microseconds()+10000);
CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
if(frame == 0) if(frame == 0)
{ {
@@ -16272,14 +16272,14 @@ rd_frame(void)
rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth; rd_state->base_regs.v.inline_depth = rd_regs()->inline_depth;
} }
rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth); rd_cmd(RD_CmdKind_FindThread, .thread = thread->handle, .unwind_count = rd_state->base_regs.v.unwind_count, .inline_depth = rd_state->base_regs.v.inline_depth);
ctrl_scope_close(ctrl_scope); access_close(access);
}break; }break;
case RD_CmdKind_UpOneFrame: case RD_CmdKind_UpOneFrame:
case RD_CmdKind_DownOneFrame: case RD_CmdKind_DownOneFrame:
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread); CTRL_Entity *thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_base_regs()->thread);
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, thread->handle, 1, os_now_microseconds()+10000); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, thread->handle, 1, os_now_microseconds()+10000);
CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth); CTRL_CallStackFrame *current_frame = ctrl_call_stack_frame_from_unwind_and_inline_depth(&call_stack, rd_regs()->unwind_count, rd_regs()->inline_depth);
CTRL_CallStackFrame *next_frame = current_frame; CTRL_CallStackFrame *next_frame = current_frame;
if(current_frame != 0) switch(kind) if(current_frame != 0) switch(kind)
@@ -16303,7 +16303,7 @@ rd_frame(void)
.unwind_count = next_frame->unwind_count, .unwind_count = next_frame->unwind_count,
.inline_depth = next_frame->inline_depth); .inline_depth = next_frame->inline_depth);
} }
ctrl_scope_close(ctrl_scope); access_close(access);
}break; }break;
//- rjf: meta controls //- rjf: meta controls
+6 -6
View File
@@ -1026,11 +1026,11 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row)
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(block_eval.space);
if(entity->kind == CTRL_EntityKind_Thread) if(entity->kind == CTRL_EntityKind_Thread)
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
info.callstack_thread = entity; info.callstack_thread = entity;
U64 frame_num = ev_block_num_from_id(block, key.child_id); U64 frame_num = ev_block_num_from_id(block, key.child_id);
B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread); B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread);
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0);
if(1 <= frame_num && frame_num <= call_stack.frames_count) if(1 <= frame_num && frame_num <= call_stack.frames_count)
{ {
CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1];
@@ -1038,7 +1038,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row)
info.callstack_inline_depth = f->inline_depth; info.callstack_inline_depth = f->inline_depth;
info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs); info.callstack_vaddr = regs_rip_from_arch_block(entity->arch, f->regs);
} }
ctrl_scope_close(ctrl_scope); access_close(access);
} }
} }
@@ -2930,10 +2930,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
}; };
AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size); AnnotationList *visible_memory_annotations = push_array(scratch.arena, AnnotationList, visible_memory_size);
{ {
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread); CTRL_Entity *selected_thread = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->thread);
CTRL_Entity *selected_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process); CTRL_Entity *selected_process = ctrl_entity_ancestor_from_kind(selected_thread, CTRL_EntityKind_Process);
CTRL_CallStack selected_call_stack = ctrl_call_stack_from_thread(ctrl_scope, selected_thread->handle, 1, 0); CTRL_CallStack selected_call_stack = ctrl_call_stack_from_thread_new(access, selected_thread->handle, 1, 0);
CTRL_Entity *eval_process = &ctrl_entity_nil; CTRL_Entity *eval_process = &ctrl_entity_nil;
if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity) if(eval.space.kind == RD_EvalSpaceKind_CtrlEntity)
{ {
@@ -3203,7 +3203,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
} }
} }
ctrl_scope_close(ctrl_scope); access_close(access);
} }
////////////////////////////// //////////////////////////////
+3 -3
View File
@@ -547,12 +547,12 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
{ {
Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol")); Vec4F32 symbol_color = ui_color_from_name(str8_lit("code_symbol"));
dr_fstrs_push_new(arena, &result, &params, str8_lit(" ")); dr_fstrs_push_new(arena, &result, &params, str8_lit(" "));
CTRL_Scope *ctrl_scope = ctrl_scope_open(); Access *access = access_open();
DI_Scope *di_scope = di_scope_open(); DI_Scope *di_scope = di_scope_open();
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); CTRL_Entity *process = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process);
Arch arch = entity->arch; Arch arch = entity->arch;
B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread); B32 call_stack_high_priority = ctrl_handle_match(entity->handle, rd_base_regs()->thread);
CTRL_CallStack call_stack = ctrl_call_stack_from_thread(ctrl_scope, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); CTRL_CallStack call_stack = ctrl_call_stack_from_thread_new(access, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0);
B32 did_first_known = 0; B32 did_first_known = 0;
for(U64 idx = 0, limit = 10; for(U64 idx = 0, limit = 10;
idx < call_stack.frames_count && idx < limit; idx < call_stack.frames_count && idx < limit;
@@ -592,7 +592,7 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
} }
} }
di_scope_close(di_scope); di_scope_close(di_scope);
ctrl_scope_close(ctrl_scope); access_close(access);
} }
//- rjf: modules get debug info status extras //- rjf: modules get debug info status extras
+1 -1
View File
@@ -2254,7 +2254,7 @@ txt_text_info_from_hash_lang(Access *access, U128 hash, TXT_LangKind lang)
TXT_LangKind lang; TXT_LangKind lang;
} key = {hash, lang}; } key = {hash, lang};
String8 key_string = str8_struct(&key); String8 key_string = str8_struct(&key);
AC_Artifact artifact = ac_artifact_from_key(access, key_string, txt_artifact_create, txt_artifact_destroy, 0); AC_Artifact artifact = ac_artifact_from_key(access, key_string, txt_artifact_create, txt_artifact_destroy, 0, .flags = AC_Flag_Wide);
TXT_Artifact *txt_artifact = (TXT_Artifact *)artifact.u64[0]; TXT_Artifact *txt_artifact = (TXT_Artifact *)artifact.u64[0];
TXT_TextInfo info = {0}; TXT_TextInfo info = {0};
if(txt_artifact != 0) if(txt_artifact != 0)