summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2020-02-18 18:43:37 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2020-02-18 18:43:37 (GMT)
commitd19456dae2642a81371adb0539331283fd55eb10 (patch)
treefa0d357859f006a3bac444c26057a18e1609e27d /src/H5MF.c
parente43895e3b49eead0a5a90b537c012020c9d76036 (diff)
downloadhdf5-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.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/H5MF.c b/src/H5MF.c
index e7b934e..769f060 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -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);