promote content scope to base layer, rename as 'access'; generalize based just on list of scope refcounts, + optional cvs; eliminate c_scope; replace dasm_scope with access as well

This commit is contained in:
Ryan Fleury
2025-09-18 15:21:22 -07:00
parent 5381307e90
commit 1b93dbd4bd
15 changed files with 203 additions and 308 deletions
+40 -110
View File
@@ -67,14 +67,14 @@ c_init(void)
Arena *arena = arena_alloc();
c_shared = push_array(arena, C_Shared, 1);
c_shared->arena = arena;
c_shared->slots_count = 4096;
c_shared->stripes_count = Min(c_shared->slots_count, os_get_system_info()->logical_processor_count);
c_shared->slots = push_array(arena, C_BlobSlot, c_shared->slots_count);
c_shared->stripes = push_array(arena, C_Stripe, c_shared->stripes_count);
c_shared->stripes_free_nodes = push_array(arena, C_BlobNode *, c_shared->stripes_count);
for(U64 idx = 0; idx < c_shared->stripes_count; idx += 1)
c_shared->blob_slots_count = 16384;
c_shared->blob_stripes_count = Min(c_shared->blob_slots_count, os_get_system_info()->logical_processor_count);
c_shared->blob_slots = push_array(arena, C_BlobSlot, c_shared->blob_slots_count);
c_shared->blob_stripes = push_array(arena, C_Stripe, c_shared->blob_stripes_count);
c_shared->blob_stripes_free_nodes = push_array(arena, C_BlobNode *, c_shared->blob_stripes_count);
for(U64 idx = 0; idx < c_shared->blob_stripes_count; idx += 1)
{
C_Stripe *stripe = &c_shared->stripes[idx];
C_Stripe *stripe = &c_shared->blob_stripes[idx];
stripe->arena = arena_alloc();
stripe->rw_mutex = rw_mutex_alloc();
stripe->cv = cond_var_alloc();
@@ -184,10 +184,10 @@ c_root_release(C_Root root)
for(U64 history_idx = 0; history_idx < C_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1)
{
U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)];
U64 hash_slot_idx = hash.u64[1]%c_shared->slots_count;
U64 hash_stripe_idx = hash_slot_idx%c_shared->stripes_count;
C_BlobSlot *hash_slot = &c_shared->slots[hash_slot_idx];
C_Stripe *hash_stripe = &c_shared->stripes[hash_stripe_idx];
U64 hash_slot_idx = hash.u64[1]%c_shared->blob_slots_count;
U64 hash_stripe_idx = hash_slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *hash_slot = &c_shared->blob_slots[hash_slot_idx];
C_Stripe *hash_stripe = &c_shared->blob_stripes[hash_stripe_idx];
MutexScopeR(hash_stripe->rw_mutex)
{
for(C_BlobNode *n = hash_slot->first; n != 0; n = n->next)
@@ -224,10 +224,10 @@ c_submit_data(C_Key key, Arena **data_arena, String8 data)
C_KeySlot *key_slot = &c_shared->key_slots[key_slot_idx];
C_Stripe *key_stripe = &c_shared->key_stripes[key_stripe_idx];
U128 hash = c_hash_from_data(data);
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
U64 slot_idx = hash.u64[1]%c_shared->blob_slots_count;
U64 stripe_idx = slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *slot = &c_shared->blob_slots[slot_idx];
C_Stripe *stripe = &c_shared->blob_stripes[stripe_idx];
//- rjf: commit data to cache - if already there, just bump key refcount
ProfScope("commit data to cache - if already there, just bump key refcount") MutexScopeW(stripe->rw_mutex)
@@ -243,10 +243,10 @@ c_submit_data(C_Key key, Arena **data_arena, String8 data)
}
if(existing_node == 0)
{
C_BlobNode *node = c_shared->stripes_free_nodes[stripe_idx];
C_BlobNode *node = c_shared->blob_stripes_free_nodes[stripe_idx];
if(node)
{
SLLStackPop(c_shared->stripes_free_nodes[stripe_idx]);
SLLStackPop(c_shared->blob_stripes_free_nodes[stripe_idx]);
}
else
{
@@ -357,10 +357,10 @@ c_submit_data(C_Key key, Arena **data_arena, String8 data)
ProfScope("decrement key ref count of expired hash")
if(!u128_match(key_expired_hash, u128_zero()))
{
U64 old_hash_slot_idx = key_expired_hash.u64[1]%c_shared->slots_count;
U64 old_hash_stripe_idx = old_hash_slot_idx%c_shared->stripes_count;
C_BlobSlot *old_hash_slot = &c_shared->slots[old_hash_slot_idx];
C_Stripe *old_hash_stripe = &c_shared->stripes[old_hash_stripe_idx];
U64 old_hash_slot_idx = key_expired_hash.u64[1]%c_shared->blob_slots_count;
U64 old_hash_stripe_idx = old_hash_slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *old_hash_slot = &c_shared->blob_slots[old_hash_slot_idx];
C_Stripe *old_hash_stripe = &c_shared->blob_stripes[old_hash_stripe_idx];
MutexScopeR(old_hash_stripe->rw_mutex)
{
for(C_BlobNode *n = old_hash_slot->first; n != 0; n = n->next)
@@ -377,86 +377,16 @@ c_submit_data(C_Key key, Arena **data_arena, String8 data)
return hash;
}
////////////////////////////////
//~ rjf: Scoped Access
internal C_Scope *
c_scope_open(void)
{
if(c_tctx == 0)
{
Arena *arena = arena_alloc();
c_tctx = push_array(arena, C_TCTX, 1);
c_tctx->arena = arena;
}
C_Scope *scope = c_tctx->free_scope;
if(scope)
{
SLLStackPop(c_tctx->free_scope);
}
else
{
scope = push_array_no_zero(c_tctx->arena, C_Scope, 1);
}
MemoryZeroStruct(scope);
return scope;
}
internal void
c_scope_close(C_Scope *scope)
{
for(C_Touch *touch = scope->top_touch, *next = 0; touch != 0; touch = next)
{
U128 hash = touch->hash;
next = touch->next;
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
MutexScopeR(stripe->rw_mutex)
{
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
{
if(u128_match(hash, n->hash))
{
ins_atomic_u64_dec_eval(&n->scope_ref_count);
break;
}
}
}
SLLStackPush(c_tctx->free_touch, touch);
}
SLLStackPush(c_tctx->free_scope, scope);
}
internal void
c_scope_touch_node__stripe_r_guarded(C_Scope *scope, C_BlobNode *node)
{
C_Touch *touch = c_tctx->free_touch;
ins_atomic_u64_inc_eval(&node->scope_ref_count);
if(touch != 0)
{
SLLStackPop(c_tctx->free_touch);
}
else
{
touch = push_array_no_zero(c_tctx->arena, C_Touch, 1);
}
MemoryZeroStruct(touch);
touch->hash = node->hash;
SLLStackPush(scope->top_touch, touch);
}
////////////////////////////////
//~ rjf: Downstream Accesses
internal void
c_hash_downstream_inc(U128 hash)
{
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
U64 slot_idx = hash.u64[1]%c_shared->blob_slots_count;
U64 stripe_idx = slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *slot = &c_shared->blob_slots[slot_idx];
C_Stripe *stripe = &c_shared->blob_stripes[stripe_idx];
MutexScopeR(stripe->rw_mutex)
{
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
@@ -473,10 +403,10 @@ c_hash_downstream_inc(U128 hash)
internal void
c_hash_downstream_dec(U128 hash)
{
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
U64 slot_idx = hash.u64[1]%c_shared->blob_slots_count;
U64 stripe_idx = slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *slot = &c_shared->blob_slots[slot_idx];
C_Stripe *stripe = &c_shared->blob_stripes[stripe_idx];
MutexScopeR(stripe->rw_mutex)
{
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
@@ -517,14 +447,14 @@ c_hash_from_key(C_Key key, U64 rewind_count)
}
internal String8
c_data_from_hash(C_Scope *scope, U128 hash)
c_data_from_hash(Access *access, U128 hash)
{
ProfBeginFunction();
String8 result = {0};
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
U64 slot_idx = hash.u64[1]%c_shared->blob_slots_count;
U64 stripe_idx = slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *slot = &c_shared->blob_slots[slot_idx];
C_Stripe *stripe = &c_shared->blob_stripes[stripe_idx];
MutexScopeR(stripe->rw_mutex)
{
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
@@ -532,7 +462,7 @@ c_data_from_hash(C_Scope *scope, U128 hash)
if(u128_match(n->hash, hash))
{
result = n->data;
c_scope_touch_node__stripe_r_guarded(scope, n);
access_touch(access, &n->scope_ref_count, stripe->cv);
break;
}
}
@@ -548,12 +478,12 @@ internal void
c_tick(void)
{
ProfBeginFunction();
Rng1U64 range = lane_range(c_shared->slots_count);
Rng1U64 range = lane_range(c_shared->blob_slots_count);
for EachInRange(slot_idx, range)
{
U64 stripe_idx = slot_idx%c_shared->stripes_count;
C_BlobSlot *slot = &c_shared->slots[slot_idx];
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
U64 stripe_idx = slot_idx%c_shared->blob_stripes_count;
C_BlobSlot *slot = &c_shared->blob_slots[slot_idx];
C_Stripe *stripe = &c_shared->blob_stripes[stripe_idx];
B32 slot_has_work = 0;
MutexScopeR(stripe->rw_mutex)
{
@@ -580,7 +510,7 @@ c_tick(void)
if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0)
{
DLLRemove(slot->first, slot->last, n);
SLLStackPush(c_shared->stripes_free_nodes[stripe_idx], n);
SLLStackPush(c_shared->blob_stripes_free_nodes[stripe_idx], n);
if(n->arena != 0)
{
arena_release(n->arena);
+7 -43
View File
@@ -155,34 +155,6 @@ struct C_Stripe
CondVar cv;
};
////////////////////////////////
//~ rjf: Scoped Access
typedef struct C_Touch C_Touch;
struct C_Touch
{
C_Touch *next;
U128 hash;
};
typedef struct C_Scope C_Scope;
struct C_Scope
{
C_Scope *next;
C_Touch *top_touch;
};
////////////////////////////////
//~ rjf: Thread Context
typedef struct C_TCTX C_TCTX;
struct C_TCTX
{
Arena *arena;
C_Scope *free_scope;
C_Touch *free_touch;
};
////////////////////////////////
//~ rjf: Shared State
@@ -191,12 +163,12 @@ struct C_Shared
{
Arena *arena;
// rjf: main data cache
U64 slots_count;
U64 stripes_count;
C_BlobSlot *slots;
C_Stripe *stripes;
C_BlobNode **stripes_free_nodes;
// rjf: main data blob cache
U64 blob_slots_count;
U64 blob_stripes_count;
C_BlobSlot *blob_slots;
C_Stripe *blob_stripes;
C_BlobNode **blob_stripes_free_nodes;
// rjf: key cache
U64 key_slots_count;
@@ -217,7 +189,6 @@ struct C_Shared
////////////////////////////////
//~ rjf: Globals
thread_static C_TCTX *c_tctx = 0;
global C_Shared *c_shared = 0;
////////////////////////////////
@@ -246,13 +217,6 @@ internal void c_root_release(C_Root root);
internal U128 c_submit_data(C_Key key, Arena **data_arena, String8 data);
////////////////////////////////
//~ rjf: Scoped Access
internal C_Scope *c_scope_open(void);
internal void c_scope_close(C_Scope *scope);
internal void c_scope_touch_node__stripe_r_guarded(C_Scope *scope, C_BlobNode *node);
////////////////////////////////
//~ rjf: Downstream Accesses
@@ -263,7 +227,7 @@ internal void c_hash_downstream_dec(U128 hash);
//~ rjf: Cache Lookups
internal U128 c_hash_from_key(C_Key key, U64 rewind_count);
internal String8 c_data_from_hash(C_Scope *scope, U128 hash);
internal String8 c_data_from_hash(Access *access, U128 hash);
////////////////////////////////
//~ rjf: Tick