lib/os/heap: option for optimizing for one heap size on 32-bit systems
The "small" heap is is way sufficient for most 32-bit systems. Let's provide the option to have only one type of heap allowing for smaller and faster heap code due to not having a bunch of runtime conditionals based on the heap size. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
b706316491
commit
46db2b491d
4 changed files with 66 additions and 3 deletions
|
@ -46,6 +46,53 @@ config SYS_HEAP_ALLOC_LOOPS
|
||||||
keeps the maximum runtime at a tight bound so that the heap
|
keeps the maximum runtime at a tight bound so that the heap
|
||||||
is useful in locked or ISR contexts.
|
is useful in locked or ISR contexts.
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Supported heap sizes"
|
||||||
|
depends on !64BIT
|
||||||
|
default SYS_HEAP_SMALL_ONLY if (SRAM_SIZE <= 256)
|
||||||
|
default SYS_HEAP_AUTO
|
||||||
|
help
|
||||||
|
Heaps using reduced-size chunk headers can accommodate so called
|
||||||
|
"small" heaps with a total size of 262136 bytes or less.
|
||||||
|
|
||||||
|
Heaps using full-size chunk headers can have a total size up to
|
||||||
|
16383 megabytes. The overhead is of course bigger.
|
||||||
|
|
||||||
|
On 32-bit system the tradeoff is selectable between:
|
||||||
|
|
||||||
|
- "small" heaps with low memory and runtime overhead;
|
||||||
|
|
||||||
|
- "big" heaps with bigger memory overhead even for small heaps;
|
||||||
|
|
||||||
|
- "auto" providing optimal memory overhead in all cases but with
|
||||||
|
a higher runtime overhead and somewhat bigger code footprint.
|
||||||
|
|
||||||
|
On 64-bit systems the "big" chunk header size conveniently provides
|
||||||
|
the needed alignment on returned memory allocations. Small chunk
|
||||||
|
headers would require alignment padding up to the big header size
|
||||||
|
anyway so "big" heap is the only option in that case.
|
||||||
|
|
||||||
|
config SYS_HEAP_SMALL_ONLY
|
||||||
|
bool "Support for small heaps only"
|
||||||
|
help
|
||||||
|
Select this to optimize the code and memory usage if all your
|
||||||
|
heaps are 262136 bytes or less.
|
||||||
|
|
||||||
|
config SYS_HEAP_BIG_ONLY
|
||||||
|
bool "Support for big heaps only"
|
||||||
|
help
|
||||||
|
Select this to optimize the code for big heaps only. This can
|
||||||
|
accommodate any heap size but memory usage won't be as
|
||||||
|
efficient with small sized heaps.
|
||||||
|
|
||||||
|
config SYS_HEAP_AUTO
|
||||||
|
bool "Support for both small and big heaps at run time"
|
||||||
|
help
|
||||||
|
This option optimizes memory usage for each heap according to
|
||||||
|
their size albeit with some overhead in code size and execution.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
config PRINTK_SYNC
|
config PRINTK_SYNC
|
||||||
bool "Serialize printk() calls"
|
bool "Serialize printk() calls"
|
||||||
default y if SMP && MP_NUM_CPUS > 1
|
default y if SMP && MP_NUM_CPUS > 1
|
||||||
|
|
|
@ -390,8 +390,13 @@ void *sys_heap_aligned_realloc(struct sys_heap *heap, void *ptr,
|
||||||
|
|
||||||
void sys_heap_init(struct sys_heap *heap, void *mem, size_t bytes)
|
void sys_heap_init(struct sys_heap *heap, void *mem, size_t bytes)
|
||||||
{
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_HEAP_SMALL_ONLY)) {
|
||||||
|
/* Must fit in a 15 bit count of HUNK_UNIT */
|
||||||
|
__ASSERT(bytes / CHUNK_UNIT <= 0x7fffU, "heap size is too big");
|
||||||
|
} else {
|
||||||
/* Must fit in a 31 bit count of HUNK_UNIT */
|
/* Must fit in a 31 bit count of HUNK_UNIT */
|
||||||
__ASSERT(bytes / CHUNK_UNIT <= 0x7fffffffU, "heap size is too big");
|
__ASSERT(bytes / CHUNK_UNIT <= 0x7fffffffU, "heap size is too big");
|
||||||
|
}
|
||||||
|
|
||||||
/* Reserve the end marker chunk's header */
|
/* Reserve the end marker chunk's header */
|
||||||
__ASSERT(bytes > heap_footer_bytes(bytes), "heap size is too small");
|
__ASSERT(bytes > heap_footer_bytes(bytes), "heap size is too small");
|
||||||
|
|
|
@ -74,7 +74,13 @@ struct z_heap {
|
||||||
|
|
||||||
static inline bool big_heap_chunks(chunksz_t chunks)
|
static inline bool big_heap_chunks(chunksz_t chunks)
|
||||||
{
|
{
|
||||||
return sizeof(void *) > 4U || chunks > 0x7fffU;
|
if (IS_ENABLED(CONFIG_SYS_HEAP_SMALL_ONLY)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_HEAP_BIG_ONLY) || sizeof(void *) > 4U) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return chunks > 0x7fffU;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool big_heap_bytes(size_t bytes)
|
static inline bool big_heap_bytes(size_t bytes)
|
||||||
|
|
|
@ -210,6 +210,11 @@ static void test_big_heap(void)
|
||||||
struct sys_heap heap;
|
struct sys_heap heap;
|
||||||
struct z_heap_stress_result result;
|
struct z_heap_stress_result result;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_SYS_HEAP_SMALL_ONLY)) {
|
||||||
|
TC_PRINT("big heap support is disabled\n");
|
||||||
|
ztest_test_skip();
|
||||||
|
}
|
||||||
|
|
||||||
TC_PRINT("Testing big (%d byte) heap\n", (int) BIG_HEAP_SZ);
|
TC_PRINT("Testing big (%d byte) heap\n", (int) BIG_HEAP_SZ);
|
||||||
|
|
||||||
sys_heap_init(&heap, heapmem, BIG_HEAP_SZ);
|
sys_heap_init(&heap, heapmem, BIG_HEAP_SZ);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue