avoid mid-scope change to reloaded sprite
This commit is contained in:
parent
885652082d
commit
8310bba397
73
src/sprite.c
73
src/sprite.c
@ -91,6 +91,7 @@ struct cache_entry {
|
|||||||
struct cache_bin {
|
struct cache_bin {
|
||||||
struct sys_mutex mutex;
|
struct sys_mutex mutex;
|
||||||
struct cache_entry *first;
|
struct cache_entry *first;
|
||||||
|
struct cache_entry *last;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cache {
|
struct cache {
|
||||||
@ -798,58 +799,44 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_lookup_touch(struct sprite_s
|
|||||||
__prof;
|
__prof;
|
||||||
|
|
||||||
struct sprite_scope_cache_ref *scope_ref = NULL;
|
struct sprite_scope_cache_ref *scope_ref = NULL;
|
||||||
struct cache_entry *entry = NULL;
|
|
||||||
struct cache_entry *nonmatching = NULL;
|
|
||||||
struct cache_entry **nonmatching_next = NULL;
|
|
||||||
|
|
||||||
struct cache_entry_hash hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
struct cache_entry_hash hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
||||||
u64 bin_index = hash.v % CACHE_BINS_COUNT;
|
u64 bin_index = hash.v % CACHE_BINS_COUNT;
|
||||||
struct cache_bin *bin = &G.cache.bins[bin_index];
|
struct cache_bin *bin = &G.cache.bins[bin_index];
|
||||||
|
|
||||||
/* Lookup */
|
/* Lookup */
|
||||||
/* TODO: Spinlock */
|
|
||||||
{
|
{
|
||||||
struct sys_lock bin_lock = sys_mutex_lock_s(&bin->mutex);
|
struct sys_lock bin_lock = sys_mutex_lock_s(&bin->mutex);
|
||||||
nonmatching_next = &bin->first;
|
struct cache_entry *match = NULL;
|
||||||
entry = *nonmatching_next;
|
for (struct cache_entry *entry = bin->first; entry; entry = entry->next_in_bin) {
|
||||||
while (entry) {
|
|
||||||
b32 match = false;
|
|
||||||
if (entry->hash.v == hash.v) {
|
if (entry->hash.v == hash.v) {
|
||||||
#if RESOURCE_RELOADING
|
#if RESOURCE_RELOADING
|
||||||
scope_ref = scope_get_ref_or_null(scope, entry, bin_index, &bin_lock);
|
b32 has_ref = scope_get_ref_or_null(scope, entry, bin_index, &bin_lock) != NULL;
|
||||||
if (scope_ref) {
|
if (has_ref) {
|
||||||
match = true;
|
match = entry;
|
||||||
} else {
|
break;
|
||||||
if (atomic_i32_eval(&entry->out_of_date)) {
|
} else if (!atomic_i32_eval(&entry->out_of_date)) {
|
||||||
/* If entry is out of date and the scope doesn't already hold a reference to it, then ignore entry */
|
match = entry;
|
||||||
} else {
|
|
||||||
match = true;
|
|
||||||
scope_ref = scope_ensure_ref(scope, entry, bin_index, &bin_lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
scope_ref = scope_ensure_ref(scope, entry, ref_node, &bin_lock);
|
match = entry;
|
||||||
match = true;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (match) {
|
if (match) {
|
||||||
break;
|
scope_ref = scope_ensure_ref(scope, match, bin_index, &bin_lock);
|
||||||
} else {
|
|
||||||
nonmatching = entry;
|
|
||||||
nonmatching_next = &nonmatching->next_in_bin;
|
|
||||||
entry = *nonmatching_next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sys_mutex_unlock(&bin_lock);
|
sys_mutex_unlock(&bin_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate new entry if necessary */
|
/* Allocate new entry if necessary */
|
||||||
if (!entry) {
|
if (!scope_ref) {
|
||||||
__profscope(entry_lookup_allocate);
|
__profscope(entry_lookup_allocate);
|
||||||
struct sys_lock bin_lock = sys_mutex_lock_e(&bin->mutex);
|
struct sys_lock bin_lock = sys_mutex_lock_e(&bin->mutex);
|
||||||
{
|
{
|
||||||
/* Alloc entry */
|
/* Alloc entry */
|
||||||
|
struct cache_entry *entry = NULL;
|
||||||
{
|
{
|
||||||
struct sys_lock pool_lock = sys_mutex_lock_e(&G.cache.entry_pool_mutex);
|
struct sys_lock pool_lock = sys_mutex_lock_e(&G.cache.entry_pool_mutex);
|
||||||
if (G.cache.entry_pool_first_free) {
|
if (G.cache.entry_pool_first_free) {
|
||||||
@ -864,10 +851,14 @@ INTERNAL struct sprite_scope_cache_ref *cache_entry_lookup_touch(struct sprite_s
|
|||||||
|
|
||||||
/* Init node and add to bin */
|
/* Init node and add to bin */
|
||||||
scope_ref = scope_ensure_ref(scope, entry, bin_index, &bin_lock);
|
scope_ref = scope_ensure_ref(scope, entry, bin_index, &bin_lock);
|
||||||
*nonmatching_next = entry;
|
{
|
||||||
if (nonmatching) {
|
if (bin->last) {
|
||||||
nonmatching->next_in_bin = entry;
|
bin->last->next_in_bin = entry;
|
||||||
entry->prev_in_bin = nonmatching;
|
entry->prev_in_bin = bin->last;
|
||||||
|
} else {
|
||||||
|
bin->first = entry;
|
||||||
|
}
|
||||||
|
bin->last = entry;
|
||||||
}
|
}
|
||||||
entry->hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
entry->hash = cache_entry_hash_from_tag_hash(tag.hash, kind);
|
||||||
entry->kind = kind;
|
entry->kind = kind;
|
||||||
@ -1098,7 +1089,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, name)
|
|||||||
{
|
{
|
||||||
for (struct cache_entry *n = bin->first; n; n = n->next_in_bin) {
|
for (struct cache_entry *n = bin->first; n; n = n->next_in_bin) {
|
||||||
if (n->hash.v == hash.v) {
|
if (n->hash.v == hash.v) {
|
||||||
logf_info("Sprite resource file \"%F\" has changed and will be reloaded.", FMT_STR(name));
|
logf_info("Sprite resource file \"%F\" has changed.", FMT_STR(name));
|
||||||
atomic_i32_eval_exchange(&n->out_of_date, 1);
|
atomic_i32_eval_exchange(&n->out_of_date, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1218,13 +1209,17 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(sprite_evictor_thread_entry_point, arg)
|
|||||||
/* Cache node has been referenced since scan, skip node. */
|
/* Cache node has been referenced since scan, skip node. */
|
||||||
} else if (cache_over_budget_target || last_ref_cycle == 0) {
|
} else if (cache_over_budget_target || last_ref_cycle == 0) {
|
||||||
/* Remove from cache bin */
|
/* Remove from cache bin */
|
||||||
if (entry->prev_in_bin) {
|
struct cache_entry *prev = entry->prev_in_bin;
|
||||||
entry->prev_in_bin->next_in_bin = entry->next_in_bin;
|
struct cache_entry *next = entry->next_in_bin;
|
||||||
|
if (prev) {
|
||||||
|
prev->next_in_bin = next;
|
||||||
} else {
|
} else {
|
||||||
bin->first = entry->next_in_bin;
|
bin->first = next;
|
||||||
}
|
}
|
||||||
if (entry->next_in_bin) {
|
if (next) {
|
||||||
entry->next_in_bin->prev_in_bin = entry->prev_in_bin;
|
next->prev_in_bin = prev;
|
||||||
|
} else {
|
||||||
|
bin->last = prev;
|
||||||
}
|
}
|
||||||
atomic_u64_eval_add_i64(&G.cache.memory_usage, -((i64)entry->memory_usage));
|
atomic_u64_eval_add_i64(&G.cache.memory_usage, -((i64)entry->memory_usage));
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user