mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-09-07 13:21:20 +01:00
lib: sbi_heap: Simplify allocation algorithm
Now that the allocator cannot run out of nodes in the middle of an allocation, the code can be simplified greatly. First it moves bytes from the beginning and/or end of the node to new nodes in the free list as necessary. These new nodes are inserted into the free list in address order. Then it moves the original node to the used list. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org> Tested-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20250617032306.1494528-4-samuel.holland@sifive.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:

committed by
Anup Patel

parent
8dcd1448e7
commit
153cdeea53
@@ -73,7 +73,7 @@ static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
||||
size_t align, size_t size)
|
||||
{
|
||||
void *ret = NULL;
|
||||
struct heap_node *n, *np, *rem;
|
||||
struct heap_node *n, *np;
|
||||
unsigned long lowest_aligned;
|
||||
size_t pad;
|
||||
|
||||
@@ -107,40 +107,30 @@ static void *alloc_with_align(struct sbi_heap_control *hpctrl,
|
||||
struct heap_node, head);
|
||||
sbi_list_del(&n->head);
|
||||
|
||||
if (size + pad < np->size) {
|
||||
rem = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||
struct heap_node, head);
|
||||
sbi_list_del(&rem->head);
|
||||
rem->addr = np->addr + (size + pad);
|
||||
rem->size = np->size - (size + pad);
|
||||
sbi_list_add_tail(&rem->head,
|
||||
&hpctrl->free_space_list);
|
||||
}
|
||||
n->addr = np->addr;
|
||||
n->size = pad;
|
||||
sbi_list_add_tail(&n->head, &np->head);
|
||||
|
||||
n->addr = lowest_aligned;
|
||||
n->size = size;
|
||||
sbi_list_add_tail(&n->head, &hpctrl->used_space_list);
|
||||
|
||||
np->size = pad;
|
||||
ret = (void *)n->addr;
|
||||
} else {
|
||||
if (size < np->size) {
|
||||
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||
struct heap_node, head);
|
||||
sbi_list_del(&n->head);
|
||||
n->addr = np->addr;
|
||||
n->size = size;
|
||||
np->addr += size;
|
||||
np->size -= size;
|
||||
sbi_list_add_tail(&n->head, &hpctrl->used_space_list);
|
||||
ret = (void *)n->addr;
|
||||
} else {
|
||||
sbi_list_del(&np->head);
|
||||
sbi_list_add_tail(&np->head, &hpctrl->used_space_list);
|
||||
ret = (void *)np->addr;
|
||||
}
|
||||
np->addr += pad;
|
||||
np->size -= pad;
|
||||
}
|
||||
|
||||
if (size < np->size) {
|
||||
n = sbi_list_first_entry(&hpctrl->free_node_list,
|
||||
struct heap_node, head);
|
||||
sbi_list_del(&n->head);
|
||||
|
||||
n->addr = np->addr + size;
|
||||
n->size = np->size - size;
|
||||
sbi_list_add(&n->head, &np->head);
|
||||
|
||||
np->size = size;
|
||||
}
|
||||
|
||||
sbi_list_del(&np->head);
|
||||
sbi_list_add_tail(&np->head, &hpctrl->used_space_list);
|
||||
ret = (void *)np->addr;
|
||||
|
||||
out:
|
||||
spin_unlock(&hpctrl->lock);
|
||||
|
||||
|
Reference in New Issue
Block a user