diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/sys/common/erl_mseg.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c index a79ff5a82f..94f9f76a20 100644 --- a/erts/emulator/sys/common/erl_mseg.c +++ b/erts/emulator/sys/common/erl_mseg.c @@ -636,14 +636,16 @@ static ERTS_INLINE void *cache_get_segment(MemKind *mk, Uint *size_p) { cache_t *c, *pc; Uint csize; Uint bad_max_abs = mk->ma->abs_max_cache_bad_fit; - /* Uint bad_max_rel = mk->ma->rel_max_cache_bad_fit; */ + Uint bad_max_rel = mk->ma->rel_max_cache_bad_fit; c = mk->cache_unpowered; pc = c; while (c) { csize = c->size; - if (csize >= size && (csize - size) < bad_max_abs ) { + if (csize >= size && + ((csize - size)*100 < bad_max_rel*size) && + (csize - size) < bad_max_abs ) { /* unlink from cache area */ seg = c->seg; @@ -700,10 +702,10 @@ static ERTS_INLINE Uint mseg_drop_one_memkind_cache_size(MemKind *mk, cache_t ** return mk->cache_size; } -static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, int ix) { +static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, cache_t **head) { cache_t *c = NULL, *next = NULL; - c = mk->cache_area[ix]; + c = *head; ASSERT( c != NULL ); while (c) { @@ -722,7 +724,7 @@ static ERTS_INLINE Uint mseg_drop_memkind_cache_size(MemKind *mk, int ix) { c = next; } - mk->cache_area[ix] = NULL; + *head = NULL; ASSERT( mk->cache_size >= 0 ); @@ -740,14 +742,14 @@ static Uint mseg_check_memkind_cache(MemKind *mk) { ERTS_DBG_MK_CHK_THR_ACCESS(mk); - if (mk->cache_unpowered) - return mseg_drop_one_memkind_cache_size(mk, &(mk->cache_unpowered)); - for (i = 0; i < CACHE_AREAS; i++) { if (mk->cache_area[i] != NULL) return mseg_drop_one_memkind_cache_size(mk, &(mk->cache_area[i])); } + if (mk->cache_unpowered) + return mseg_drop_one_memkind_cache_size(mk, &(mk->cache_unpowered)); + return 0; } @@ -800,13 +802,19 @@ void erts_mseg_cache_check(void) { static void mseg_clear_memkind_cache(MemKind *mk) { int i; + /* drop pow2 caches */ for (i = 0; i < CACHE_AREAS; i++) { if (mk->cache_area[i] == NULL) continue; - mseg_drop_memkind_cache_size(mk, i); + mseg_drop_memkind_cache_size(mk, &(mk->cache_area[i])); + ASSERT(mk->cache_area[i] == NULL); } + /* drop varied caches */ + if(mk->cache_unpowered) + mseg_drop_memkind_cache_size(mk, &(mk->cache_unpowered)); + ASSERT(mk->cache_unpowered == NULL); ASSERT(mk->cache_size == 0); } |