diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-05-23 17:21:24 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-05-23 17:30:29 +0200 |
commit | d9e5895829a2c20e7624326ce391f0e56762b855 (patch) | |
tree | c7ba4fa9322d5038da8e53aef200a47d01558604 /lib/sqfs/block_processor/serial.c | |
parent | 4587a56466f0c55d91ece168f0dc872f81a8196c (diff) |
block processor: move the block consolidation to the worker thread
Instead of merging fragments into the fragment block inside the
process_completed_fragment function, store a linked list of fragments
in the fragment block and do the actual merging (several memcpy calls
totaling of up to 1M of data in worst case) in the worker thread
instead of the locked, serial path.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs/block_processor/serial.c')
-rw-r--r-- | lib/sqfs/block_processor/serial.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/lib/sqfs/block_processor/serial.c b/lib/sqfs/block_processor/serial.c index a9190b1..54edda1 100644 --- a/lib/sqfs/block_processor/serial.c +++ b/lib/sqfs/block_processor/serial.c @@ -13,19 +13,29 @@ typedef struct { sqfs_u8 scratch[]; } serial_block_processor_t; -static void block_processor_destroy(sqfs_object_t *obj) +static void free_block_list(sqfs_block_t *list) { - sqfs_block_processor_t *proc = (sqfs_block_processor_t *)obj; sqfs_block_t *blk; - while (proc->free_list != NULL) { - blk = proc->free_list; - proc->free_list = blk->next; + while (list != NULL) { + blk = list; + list = blk->next; free(blk); } +} + +static void block_processor_destroy(sqfs_object_t *obj) +{ + sqfs_block_processor_t *proc = (sqfs_block_processor_t *)obj; + + free_block_list(proc->free_list); + + if (proc->frag_block != NULL) { + free_block_list(proc->frag_block->frag_list); + free(proc->frag_block); + } free(proc->blk_current); - free(proc->frag_block); free(proc); } @@ -57,16 +67,14 @@ int append_to_work_queue(sqfs_block_processor_t *proc, sqfs_block_t *block) serial_block_processor_t *sproc = (serial_block_processor_t *)proc; sqfs_block_t *fragblk = NULL; - if (sproc->status != 0) { - free(block); - return sproc->status; - } + if (sproc->status != 0) + goto fail; sproc->status = block_processor_do_block(block, proc->cmp, sproc->scratch, proc->max_block_size); if (sproc->status != 0) - return sproc->status; + goto fail; if (block->flags & SQFS_BLK_IS_FRAGMENT) { sproc->status = process_completed_fragment(proc, block, @@ -74,15 +82,20 @@ int append_to_work_queue(sqfs_block_processor_t *proc, sqfs_block_t *block) if (fragblk == NULL) return sproc->status; - sproc->status = block_processor_do_block(fragblk, proc->cmp, + block = fragblk; + sproc->status = block_processor_do_block(block, proc->cmp, sproc->scratch, proc->max_block_size); if (sproc->status != 0) - return sproc->status; + goto fail; } sproc->status = process_completed_block(proc, block); return sproc->status; +fail: + free_block_list(block->frag_list); + free(block); + return sproc->status; } int sqfs_block_processor_sync(sqfs_block_processor_t *proc) @@ -104,9 +117,13 @@ int sqfs_block_processor_finish(sqfs_block_processor_t *proc) goto fail; sproc->status = process_completed_block(proc, proc->frag_block); + proc->frag_block = NULL; return sproc->status; fail: - free(proc->frag_block); - proc->frag_block = NULL; + if (proc->frag_block != NULL) { + free_block_list(proc->frag_block->frag_list); + free(proc->frag_block); + proc->frag_block = NULL; + } return sproc->status; } |