Skip to content

Commit 48df0e2

Browse files
committed
Mark allocator panic paths as unlikely()
Errors that trigger kernel panic in the memory allocator are expected to almost never occur during normal operation. Hint these branches with unlikely() so the compiler can better optimize the common fast path. This change wraps validation failures and other fatal checks with unlikely(), without altering runtime behavior.
1 parent bc8ac16 commit 48df0e2

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

lib/malloc.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,21 @@ static uint32_t free_blocks_count; /* track fragmentation */
4545
/* Validate block integrity */
4646
static inline bool validate_block(memblock_t *block)
4747
{
48-
if (!IS_VALID_BLOCK(block))
48+
if (unlikely(!IS_VALID_BLOCK(block)))
4949
return false;
5050

5151
size_t size = GET_SIZE(block);
52-
if (!size || size > MALLOC_MAX_SIZE)
52+
if (unlikely(!size || size > MALLOC_MAX_SIZE))
5353
return false;
5454

5555
/* Check if block extends beyond heap */
56-
if ((uint8_t *) block + sizeof(memblock_t) + size > (uint8_t *) heap_end)
56+
if (unlikely((uint8_t *) block + sizeof(memblock_t) + size >
57+
(uint8_t *) heap_end))
5758
return false;
5859

59-
if (block->next &&
60-
(uint8_t *) block + sizeof(memblock_t) + GET_SIZE(block) !=
61-
(uint8_t *) block->next)
60+
if (unlikely(block->next &&
61+
(uint8_t *) block + sizeof(memblock_t) + GET_SIZE(block) !=
62+
(uint8_t *) block->next))
6263
return false;
6364

6465
return true;
@@ -75,7 +76,7 @@ void free(void *ptr)
7576
memblock_t *p = ((memblock_t *) ptr) - 1;
7677

7778
/* Validate the block being freed */
78-
if (!validate_block(p) || !IS_USED(p)) {
79+
if (unlikely(!validate_block(p) || !IS_USED(p))) {
7980
CRITICAL_LEAVE();
8081
panic(ERR_HEAP_CORRUPT);
8182
return; /* Invalid or double-free */
@@ -100,7 +101,7 @@ void free(void *ptr)
100101
}
101102

102103
if (prev && !IS_USED(prev)) {
103-
if (!validate_block(prev)) {
104+
if (unlikely(!validate_block(prev))) {
104105
CRITICAL_LEAVE();
105106
panic(ERR_HEAP_CORRUPT);
106107
return;
@@ -120,7 +121,7 @@ static void selective_coalesce(void)
120121

121122
while (p && p->next) {
122123
/* Merge only when blocks are FREE *and* adjacent in memory */
123-
if (!validate_block(p)) {
124+
if (unlikely(!validate_block(p))) {
124125
panic(ERR_HEAP_CORRUPT);
125126
return;
126127
}
@@ -155,7 +156,7 @@ void *malloc(uint32_t size)
155156

156157
memblock_t *p = first_free;
157158
while (p) {
158-
if (!validate_block(p)) {
159+
if (unlikely(!validate_block(p))) {
159160
CRITICAL_LEAVE();
160161
panic(ERR_HEAP_CORRUPT);
161162
return NULL; /* Heap corruption detected */
@@ -254,7 +255,7 @@ void *realloc(void *ptr, uint32_t size)
254255
memblock_t *old_block = ((memblock_t *) ptr) - 1;
255256

256257
/* Validate the existing block */
257-
if (!validate_block(old_block) || !IS_USED(old_block)) {
258+
if (unlikely(!validate_block(old_block) || !IS_USED(old_block))) {
258259
panic(ERR_HEAP_CORRUPT);
259260
return NULL;
260261
}

0 commit comments

Comments
 (0)