Fix insufficient pool-growing logic in bli_pool.c. (#559)

Details:
- The current mechanism for growing a pool_t doubles the length of the
  block_ptrs array every time the array length needs to be increased
  due to new blocks being added. However, that logic did not take in
  account the new total number of blocks, and the fact that the caller
  may be requesting more blocks that would fit even after doubling the
  current length of block_ptrs. The code comments now contain two 
  illustrating examples that show why, even after doubling, we must 
  always have at least enough room to fit all of the old blocks plus
  the newly requested blocks.
- This commit also happens to fix a memory corruption issue that stems
  from growing any pool_t that is initialized with a block_ptrs length
  of 0. (Previously, the memory pool for packed buffers of C was 
  initialized with a block_ptrs length of 0, but because it is unused 
  this bug did not manifest by default.)
- Co-authored-by: Minh Quan Ho <minh-quan.ho@kalray.eu>
This commit is contained in:
Minh Quan Ho
2021-10-12 19:53:04 +02:00
committed by GitHub
parent 32a6d93ef6
commit 327481a4b0

View File

@@ -373,7 +373,15 @@ void bli_pool_grow
{
// To prevent this from happening often, we double the current
// length of the block_ptrs array.
const siz_t block_ptrs_len_new = 2 * block_ptrs_len_cur;
// Sanity: make sure that the block_ptrs_len_new will be at least
// num_blocks_new, in case doubling the block_ptrs_len_cur is not enough.
// Example 1:
// - block_ptrs_len_cur == num_blocks_cur == 0 and num_blocks_add = 1
// - So doubling: 2 * block_ptrs_len_cur = 0, whereas 1 is expected
// Example 2:
// - block_ptrs_len_cur == num_blocks_cur == 10 and num_blocks_add = 30
// - So doubling: 2 * block_ptrs_len_cur = 20, whereas 40 is expected
const siz_t block_ptrs_len_new = bli_max( (2 * block_ptrs_len_cur), num_blocks_new );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "bli_pool_grow(): growing block_ptrs_len (%d -> %d): ",