ukboot/boot.c /* try to use memory region to initialize allocator * if it fails, we will try again with the next region. * As soon we have an allocator, we simply add every * subsequent region to it */ if (!a) { #if CONFIG_LIBUKBOOT_INITBBUDDY a = uk_allocbbuddy_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITREGION a = uk_allocregion_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITMIMALLOC a = uk_mimalloc_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITTLSF a = uk_tlsf_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITTINYALLOC a = uk_tinyalloc_init(md.base, md.len); #endif } else { uk_alloc_addmem(a, md.base, md.len); }
根据unikraft 论文,uk_alloc共有五个allocator后端:”a buddy system, the Two-Level Segregated Fits [53] (TLSF) real-time memory allocator, tinyalloc [67], Mimalloc [42] (version1.6.1) and the Oscar [12] secure memory allocator”, 实际上在只实现了2个 ukallocbbuddy 和 ukallocregion ; 实际运行时只使用ukallocbbuddy(写死的)
UK_ASSERT(a != NULL); b = (struct uk_bbpalloc *)&a->priv;
size_t order = (size_t)num_pages_to_order(num_pages);
/* Find smallest order which can satisfy the request. */ for (i = order; i < FREELIST_SIZE; i++) { if (!FREELIST_EMPTY(b->free_head[i])) break; } if (i == FREELIST_SIZE) goto no_memory;
/* We may have to break the chunk a number of times. */ while (i != order) { /* Split into two equal parts. */ i--; spare_ch = (chunk_head_t *)((char *)alloc_ch + (1UL << (i + __PAGE_SHIFT))); spare_ct = (chunk_tail_t *)((char *)spare_ch + (1UL << (i + __PAGE_SHIFT))) - 1;
/* Create new header for spare chunk. */ spare_ch->level = i; spare_ch->next = b->free_head[i]; spare_ch->pprev = &b->free_head[i]; spare_ct->level = i;
/* Link in the spare chunk. */ spare_ch->next->pprev = &spare_ch->next; b->free_head[i] = spare_ch; } map_alloc(b, (uintptr_t)alloc_ch, 1UL << order);
/* try to use memory region to initialize allocator * if it fails, we will try again with the next region. * As soon we have an allocator, we simply add every * subsequent region to it */ /* 将内存块交给allocator管理 */ if (!a) { #if CONFIG_LIBUKBOOT_INITBBUDDY a = uk_allocbbuddy_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITREGION a = uk_allocregion_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITMIMALLOC a = uk_mimalloc_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITTLSF a = uk_tlsf_init(md.base, md.len); #elif CONFIG_LIBUKBOOT_INITTINYALLOC a = uk_tinyalloc_init(md.base, md.len); #endif } else { uk_alloc_addmem(a, md.base, md.len); } } if (unlikely(!a)) uk_pr_warn("No suitable memory region for memory allocator. Continue without heap\n"); else { rc = ukplat_memallocator_set(a); if (unlikely(rc != 0)) UK_CRASH("Could not set the platform memory allocator\n"); } #endif