On 64-bit targets, casting from pointer to unsigned can lose data.
Instead, cast to uintptr_t. This causes no code change on 32-bit
platforms, since the types have the same width, but preserves all bits
on systems where pointers are 64 bits.
The tlsf_control_functions.h and tlsf_block_functions.h
are moved to the root dir.
The tlsf.h header (the only public header has it contains
the public API) is kept in include folder.
The tlsf_common.h header is deleted and its content is
split accross all header files since this file was originally
containain the definition of structures such as block_header_t
and control_t that can now be moved to tlsf_block_functions.h
(respectively tlsf_control_functions.h).
The function will find a suitable free block that can contain
the malloc size at the given address in the memory pool, split
the free block to create the block that will contain the allocated
memory, update the status of the newly created blocks (free / used)
and return the pointer to the memory allocated at the given address.
If no block is found (the status of the heap doesn't allow for an
allocation at the given address) the function will return NULL.
It needs to include the rounding done by `mapping_search()`
otherwise we'll trim the block too much and not be able to
re-allocate the same amount of space after the block is freed.
In the paper's version of mapping_search, this is subtle because
r is marked as "in out". http://www.gii.upv.es/tlsf/files/papers/jrts2008.pdf
To reproduce:
* Allocate an amount that is rounded up.
* Allocate a second block that takes up the remaining space. This
prevents the second allocation from occurring in a new spot.
* Free the first block.
* Allocate the first amount a second time. It will fail without this
change even though the requested space is actually available because the
free block was added to the non-rounded segmented list.
This commit adds a return boolean value to the tlsf_walker
function allowing users to interrupt the traversal of the
pool when returning from any call to the tlsf_walker.
The good fit mechanism should not be applied for small blocks.
If the size in parameter is inferior to control->small_block_size.
then the function tlsf_fit_size should return size directly.
Previously the hook was called from tlsf_check function leading to only check the free blocks
and leaving the used blocks unchecked by the hook. By moving the function hook call to the
integrity_walker function, free and used blocks are now passed to the function hook.
- the control_t structure should not be available to the user so it
was moved to tlsf.c. In addition bitfields are now used in control_t
when possible which reduces the size of the structure from 56 bytes
to 36 bytes.
- fix an assert message to place it in the tlsf_assert
- add comment about the index count log2 field in control_t
The calculation of fl index max is changed to always be the smallest
number that includes the size of the registered memory.
The control_construct() function now checks for minimum size as the control structure
parameters are calculated.
There is no longer a minimum configuration for fl index max so the tlsf_config
enum is striped down to remove unecessary compile time values.
the tlsf_size() function will fail if no tlsf pointer is passed as parameter since there
is no way to calculate a default tlsf size anymore.
In this commit:
The call to tlsf_asssert is removed from tlsf_insist to allow the tlsf_check()
function to return when one or more of the tlsf_insist() calls fails. In the previous
implementation any failing tlsf_assist() was causing the tlsf_assert to terminate the
execution of the application which doesn't allow the user to handle failures in tlsf_check()
eventhough tlsf_check() returns a value.
In this commit:
- We add a weak delcaration of tlsf_check_hook() in tlsf.h.
- We call tlsf_check_hook() in tlsf_check() if the function has a defintion
This hook function allows the user to implement application specific checks on
the memory of every free blocks (e.g. check for memory corruption).
Note: block_absorb() is called in tlsf_free(), which is eventually called in multi_heap_free()
after the memory fill is done. As the block_absorb merges 2 blocks together, the previous block
header of the merged block is now in the middle of the memory block but not filled with 0xfe.
- Remove dependencies with the heap component of the IDF.
- The tlsf_poison_fill_region_hook() function is defined as weak in IDF and checked for NULL
in block_absorb() function in order to minimize the dependencies between IDF and the TLSF.
- The the implementation of tlsf_poison_fill_region_hook() must be provided at the discretion
of the user.