diff options
author | David Young <dyoung@hdfgroup.org> | 2020-02-18 18:43:37 (GMT) |
---|---|---|
committer | David Young <dyoung@hdfgroup.org> | 2020-02-18 18:43:37 (GMT) |
commit | d19456dae2642a81371adb0539331283fd55eb10 (patch) | |
tree | fa0d357859f006a3bac444c26057a18e1609e27d /src/H5MF.c | |
parent | e43895e3b49eead0a5a90b537c012020c9d76036 (diff) | |
download | hdf5-d19456dae2642a81371adb0539331283fd55eb10.zip hdf5-d19456dae2642a81371adb0539331283fd55eb10.tar.gz hdf5-d19456dae2642a81371adb0539331283fd55eb10.tar.bz2 |
In process_deferred_frees(), remove *all* deferred frees from the
H5F_shared_t's queue before processing any, instead of removing just one,
processing it, removing another, processing it, and so on. While we processed
the first entry on the queue, we often called H5MF_xfree() again, which called
process_deferred_frees() again, which processed the first entry, calling
H5MF_xfree() again, and on and on, until the deferred frees list was exhausted.
This deep recursion showed up as a wide, tall stack in my flame graphs. Taking
all deferred entries off of the queue to start definitely breaks the recursion
and saves processing time.
Diffstat (limited to 'src/H5MF.c')
-rw-r--r-- | src/H5MF.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -158,8 +158,11 @@ process_deferred_frees(H5F_t *f) herr_t err = SUCCEED; H5F_shared_t *shared = f->shared; const uint64_t tick_num = shared->tick_num; + lower_defree_queue_t defrees = SIMPLEQ_HEAD_INITIALIZER(defrees); - while ((df = SIMPLEQ_FIRST(&shared->lower_defrees)) != NULL) { + SIMPLEQ_CONCAT(&defrees, &shared->lower_defrees); + + while ((df = SIMPLEQ_FIRST(&defrees)) != NULL) { if (tick_num <= df->free_after_tick) break; /* Have to remove the item before processing it because we @@ -167,7 +170,7 @@ process_deferred_frees(H5F_t *f) * the item was still on the queue, it would be processed * a second time, and that's not good. */ - SIMPLEQ_REMOVE_HEAD(&shared->lower_defrees, link); + SIMPLEQ_REMOVE_HEAD(&defrees, link); if (H5MF__xfree_impl(f, df->alloc_type, df->addr, df->size) < 0) err = FAIL; free(df); |