Implements simple bitmap allocation.

This commit is contained in:
Felix Queißner 2016-05-03 09:23:38 +02:00
parent 782fddf606
commit 99704be202

View file

@ -1,16 +1,88 @@
#include <inttypes.h>
#include "pmm.hpp"
/**
* Number stored of pages in the bitmap
*/
static const uint32_t BitmapSize = 4096; /* 16 MB */
/**
* Number of 32-bit tuples in the bitmap.
*/
static const uint32_t BitmapLength = BitmapSize / 32;
/**
* Bitmap that stores the page status.
* A set bit marks a used page
* An unset bit marks an unused page
*/
static uint32_t bitmap[BitmapLength];
static uint32_t ptrcast(void *ptr)
{
return reinterpret_cast<uint32_t>(ptr);
}
static void *ptrcast(uint32_t ptr)
{
return reinterpret_cast<void*>(ptr);
}
static bool isAligned(uint32_t ptr)
{
return (ptr % 4096) == 0;
}
bool PMM::markOccupied(void *page)
{
return false;
uint32_t ptr = ptrcast(page);
if(!isAligned(ptr))
; // Do something about it!
uint32_t pageId = ptr / 4096;
uint32_t idx = pageId / 32;
uint32_t bit = pageId % 32;
bool wasSet = (bitmap[idx] & (1<<bit)) != 0;
bitmap[idx] |= (1<<bit);
return wasSet;
}
void *PMM::alloc()
{
for(uint32_t idx = 0; idx < BitmapLength; idx++) {
// fast skip when all bits are set
if(bitmap[idx] == 0xFFFFFFFF) {
continue;
}
for(uint32_t bit = 0; bit < 32; bit++) {
uint32_t mask = (1<<bit);
if((bitmap[idx] & mask) != 0) {
continue;
}
// Mark the selected bit as used.
bitmap[idx] |= mask;
uint32_t pageId = 32 * idx + bit;
uint32_t ptr = 4096 * pageId;
return ptrcast(ptr);
}
}
// Do something here!
return nullptr;
}
void PMM::free(void *page)
{
uint32_t ptr = ptrcast(page);
if(!isAligned(ptr))
; // Do something about it!
uint32_t pageId = ptr / 4096;
uint32_t idx = pageId / 32;
uint32_t bit = pageId % 32;
bitmap[idx] &= ~(1<<bit);
}