diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2024-02-01 09:54:47 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2024-02-01 12:44:58 -0500 |
commit | 85e8344637ac4ac28e3638764f28d411781b8e96 (patch) | |
tree | e276e15612d3f190160880134e634b588c63481c | |
parent | 710c083ff02eb1cc5b8daa6778784f3d1cd3c08d (diff) | |
download | bfs-85e8344637ac4ac28e3638764f28d411781b8e96.tar.xz |
bftw: Always block in bftw_pop_dir() with multiple threads
-rw-r--r-- | src/bftw.c | 33 |
1 files changed, 22 insertions, 11 deletions
@@ -1191,27 +1191,38 @@ static void bftw_push_dir(struct bftw_state *state, struct bftw_file *file) { bftw_ioq_opendirs(state); } +/** Check if we should block on the ioq when popping a directory. */ +static bool bftw_block_for_dir(const struct bftw_state *state) { + // Always block with more than one background thread + if (state->nthreads > 1) { + return true; + } + + // Block if the cache is full + if (state->cache.capacity == 0) { + return true; + } + + // Block if we have no other files/dirs to visit + if (!bftw_queue_waiting(&state->dirq) && bftw_queue_empty(&state->fileq)) { + return true; + } + + return false; +} + /** Pop a directory to read from the queue. */ static bool bftw_pop_dir(struct bftw_state *state) { bfs_assert(!state->file); - struct bftw_cache *cache = &state->cache; - if (state->flags & BFTW_SORT) { // Keep strict breadth-first order when sorting - bool have_files = bftw_queue_ready(&state->fileq); - if (state->strategy == BFTW_BFS && have_files) { + if (state->strategy == BFTW_BFS && bftw_queue_ready(&state->fileq)) { return false; } } else { while (!bftw_queue_ready(&state->dirq)) { - // Block if we have no other files/dirs to visit, or no room in the cache - bool have_dirs = bftw_queue_waiting(&state->dirq); - bool have_files = !bftw_queue_empty(&state->fileq); - bool have_room = cache->capacity > 0; - bool block = !(have_dirs || have_files) || !have_room; - - if (bftw_ioq_pop(state, block) < 0) { + if (bftw_ioq_pop(state, bftw_block_for_dir(state)) < 0) { break; } } |