Code: Select all
struct entry {
struct entry *next;
uintptr_t bitmap;
};
Code: Select all
page_t alloc_page(void)
{
int bit = __builtin_ffsll(~head->bitmap) - 1;
head->bitmap |= (1 << i);
struct entry *tmp = head;
if (~head->bitmap == 0) {
head = head->next;
tmp->next = NULL;
}
return ((tmp - bitmap_base) * PAGES_PER_ENTRY + bit) * PAGE_SIZE;
}
Code: Select all
void free_page(page_t page)
{
struct entry *e = &bitmap_base[(page / PAGE_SIZE) / PAGES_PER_ENTRY];
int bit = (page / PAGE_SIZE) % PAGES_PER_ENTRY;
bool was_full = (~e->bitmap == 0);
e->bitmap &= ~(1 << bit);
/* Push back onto the stack if needed */
if (e->next == NULL && was_full) {
e->next = head;
head = entry;
}
}
Code: Select all
bool test_page(page_t page)
{
struct entry *e = &bitmap_base[(page / PAGE_SIZE) / PAGES_PER_ENTRY];
int bit = (page / PAGE_SIZE) % PAGES_PER_ENTRY;
return e->bitmap & (1 << bit);
}
What are the pros and cons of this approach compared to other allocators?