diff options
author | Eric Wong <e@80x24.org> | 2022-11-20 09:14:24 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2022-12-02 09:40:01 +0000 |
commit | e20367559b8bd677b7386818cb8a672b003f2e25 (patch) | |
tree | e0828951efa30bf5d058e98b68cdcd824519f908 | |
parent | 45c7129666ba9e1f82f23f5d6211e0805b04c999 (diff) | |
download | mwrap-e20367559b8bd677b7386818cb8a672b003f2e25.tar.gz |
There's no need to worry about race conditions if operating on idle arenas, so clean them up immediately rather than cleaning them up after a pthread_create (which may never come). We'll also inform active threads about the trim earlier so they have more cycles to react to the lazy trim request.
-rw-r--r-- | mymalloc.h | 29 |
1 files changed, 18 insertions, 11 deletions
@@ -150,23 +150,30 @@ static void remote_free_finish(mstate ms) int malloc_trim(size_t pad) { - mstate ms = ms_tsd; + mstate m; + int ret = 0; CHECK(int, 0, pthread_mutex_lock(&global_mtx)); - { /* be lazy for sibling threads, readers are not synchronized */ - mstate m; - cds_list_for_each_entry(m, &arenas_unused, arena_node) - uatomic_set(&m->trim_check, 0); - cds_list_for_each_entry(m, &arenas_active, arena_node) - uatomic_set(&m->trim_check, 0); + + /* be lazy for active sibling threads, readers are not synchronized */ + cds_list_for_each_entry(m, &arenas_active, arena_node) + uatomic_set(&m->trim_check, 0); + + /* nobody is using idle arenas, clean immediately */ + cds_list_for_each_entry(m, &arenas_unused, arena_node) { + m->trim_check = 0; + remote_free_finish(m); + ret |= sys_trim(m, pad); } + CHECK(int, 0, pthread_mutex_unlock(&global_mtx)); - if (ms) { /* trim our own arena immediately */ - remote_free_finish(ms); - return sys_trim(ms, pad); + m = ms_tsd; + if (m) { /* trim our own arena immediately */ + remote_free_finish(m); + ret |= sys_trim(m, pad); } - return 0; + return ret; } static void remote_free_enqueue(mstate fm, void *mem) |