Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tlsf_extend_pool function #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 42 additions & 14 deletions tlsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,45 +977,68 @@ size_t tlsf_alloc_overhead(void)
return block_header_overhead;
}

pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
pool_t tlsf_extend_pool(tlsf_t tlsf, void* mem, size_t bytes, size_t incr)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API is ambiguous. I'd prefer:
pool_t tlsf_extend_pool(tlsf_t tlsf, pool_t pool, size_t incr);

Copy link
Author

@xiaoxiang781216 xiaoxiang781216 Mar 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I also think your prototype is better, but since the alignment may happen, it's impossible to recover the original size by finding the sentinal block. That's why the caller need pass the old size again.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about:
pool_t tlsf_resize_pool(tlsf_t tlsf, pool_t pool, size_t oldBytes, size_t newBytes)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's also my initial thinking, but it's very hard(if not possible) to reduce the running pool size since some memory may be using by user. That's why I:

  1. Name the new function tlsf_extend_pool
  2. Pass the increased bytes instead new size(newBytes may smaller than oldBytes)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's very hard(if not possible) to reduce the running pool size since some memory may be using by user.

Documentation will warn about dangerousness of reducing running pool size.
User anyway should know what he is doing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function just try to extend the pool:

  1. The algo to reduce pool is totally different
  2. And the condition to call reduce is also different

so the function is better to indicate what it can do and what not to do explicitly.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, looks reasonable.

{
block_header_t* block;
block_header_t* next;

control_t* control = tlsf_cast(control_t*, tlsf);
const size_t pool_overhead = tlsf_pool_overhead();
const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE);

if (((ptrdiff_t)mem % ALIGN_SIZE) != 0)
{
printf("tlsf_add_pool: Memory must be aligned by %u bytes.\n",
printf("tlsf_extend_pool: Memory must be aligned by %u bytes.\n",
(unsigned int)ALIGN_SIZE);
return 0;
}

if (pool_bytes < block_size_min || pool_bytes > block_size_max)
{
#if defined (TLSF_64BIT)
printf("tlsf_add_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n",
printf("tlsf_extend_pool: Memory size must be between 0x%x and 0x%x00 bytes.\n",
(unsigned int)(pool_overhead + block_size_min),
(unsigned int)((pool_overhead + block_size_max) / 256));
#else
printf("tlsf_add_pool: Memory size must be between %u and %u bytes.\n",
printf("tlsf_extend_pool: Memory size must be between %u and %u bytes.\n",
(unsigned int)(pool_overhead + block_size_min),
(unsigned int)(pool_overhead + block_size_max));
#endif
return 0;
}

/*
** Create the main free block. Offset the start of the block slightly
** so that the prev_phys_block field falls outside of the pool -
** it will never be used.
*/
block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
block_set_size(block, pool_bytes);
block_set_free(block);
block_set_prev_used(block);
block_insert(tlsf_cast(control_t*, tlsf), block);
if (incr > 0 && incr < tlsf_block_size_min())
{
printf("tlsf_extend_pool: Increased size must be at least %u bytes.\n",
(unsigned int)tlsf_block_size_min());
return 0;
}

if (incr == 0) /* Initialize the pool */
{
/*
** Create the main free block. Offset the start of the block slightly
** so that the prev_phys_block field falls outside of the pool -
** it will never be used.
*/
block = offset_to_block(mem, -(tlsfptr_t)block_header_overhead);
block_set_size(block, pool_bytes);
block_set_free(block);
block_set_prev_used(block);
block_insert(control, block);
}
else /* Extend the pool */
{
/* Extend the sentinel block */
const size_t new_bytes = align_down((bytes + incr) -
(pool_overhead + pool_bytes) - block_header_overhead, ALIGN_SIZE);

block = offset_to_block(mem, pool_bytes);
block_set_size(block, new_bytes);
block_set_free(block);
block = block_merge_prev(control, block);
block_insert(control, block);
}

/* Split the block to create a zero-size sentinel block. */
next = block_link_next(block);
Expand All @@ -1026,6 +1049,11 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
return mem;
}

pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
{
return tlsf_extend_pool(tlsf, mem, bytes, 0);
}

void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
{
control_t* control = tlsf_cast(control_t*, tlsf);
Expand Down
1 change: 1 addition & 0 deletions tlsf.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pool_t tlsf_get_pool(tlsf_t tlsf);

/* Add/remove memory pools. */
pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
pool_t tlsf_extend_pool(tlsf_t tlsf, void* mem, size_t bytes, size_t incr);
void tlsf_remove_pool(tlsf_t tlsf, pool_t pool);

/* malloc/memalign/realloc/free replacements. */
Expand Down