char *mem_pool::mem_pool_impl::alloc_page(int &index) { assert(inited == 1); if(free_pages == 0) { return 0; /* there are no pages to allocate */ } /* * find a free page index from bitmap */ int page_index; for(;; ++current_page) { if(current_page == total_pages) { current_page = 0; } if(TEST_BIT(page_bitmap, current_page) == 0) { /* found */ page_index = current_page++; break; } } index = page_index; --free_pages; SET_BIT(page_bitmap, index); return index_to_page(index); }
/* * Allocate physically contiguous memory region. * @param ord Block order (2^ord pages) * @param zero Zero out block content if true * @return Pointer to linear memory region */ void *Buddy::alloc (unsigned short ord, Fill fill) { Lock_guard <Spinlock> guard (lock); for (unsigned short j = ord; j < order; j++) { if (head[j].next == head + j) continue; Block *block = head[j].next; block->prev->next = block->next; block->next->prev = block->prev; block->ord = ord; block->tag = Block::Used; while (j-- != ord) { Block *buddy = block + (1ul << j); buddy->prev = buddy->next = head + j; buddy->ord = j; buddy->tag = Block::Free; head[j].next = head[j].prev = buddy; } mword virt = index_to_page (block_to_index (block)); // Ensure corresponding physical block is order-aligned assert ((virt_to_phys (virt) & ((1ul << (block->ord + PAGE_BITS)) - 1)) == 0); if (fill) memset (reinterpret_cast<void *>(virt), fill == FILL_0 ? 0 : -1, 1ul << (block->ord + PAGE_BITS)); return reinterpret_cast<void *>(virt); } Console::panic ("Out of memory"); }