WIP: implement basic of alloc area
This commit is contained in:
parent
a2d2e1de60
commit
b077d54e7f
146
core/allocArea.c
Normal file
146
core/allocArea.c
Normal file
@ -0,0 +1,146 @@
|
||||
#include "allocArea.h"
|
||||
#include "alloc.h"
|
||||
#include "assert.h"
|
||||
#include "kernel.h"
|
||||
#include "list.h"
|
||||
#include "mem.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
struct memArea {
|
||||
vaddr_t startAddr;
|
||||
uint nbPages;
|
||||
struct memArea *next;
|
||||
struct memArea *prev;
|
||||
};
|
||||
|
||||
static struct memArea *freeArea;
|
||||
static struct memArea *usedArea;
|
||||
|
||||
void areaInit(void)
|
||||
{
|
||||
list_init(freeArea);
|
||||
list_init(usedArea);
|
||||
}
|
||||
|
||||
struct memArea *areaFindFit(unsigned int nbPages)
|
||||
{
|
||||
struct memArea *area;
|
||||
int count;
|
||||
|
||||
list_foreach(freeArea, area, count)
|
||||
{
|
||||
if (area->nbPages >= nbPages)
|
||||
return area;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void insertSorted(struct memArea *list, struct memArea *item)
|
||||
{
|
||||
struct memArea *prev, *cur;
|
||||
int count;
|
||||
prev = NULL;
|
||||
|
||||
list_foreach(list, cur, count)
|
||||
{
|
||||
if (cur->startAddr > item->startAddr)
|
||||
break;
|
||||
prev = cur;
|
||||
}
|
||||
if (prev)
|
||||
list_insert_after(list, prev, item);
|
||||
else
|
||||
list_add_tail(list, item);
|
||||
}
|
||||
|
||||
vaddr_t areaAlloc(unsigned int nbPages)
|
||||
{
|
||||
struct memArea *area, *allocated;
|
||||
|
||||
area = areaFindFit(nbPages);
|
||||
if (!area)
|
||||
return (vaddr_t)NULL;
|
||||
|
||||
if (area->nbPages == nbPages) {
|
||||
list_delete(freeArea, area);
|
||||
insertSorted(usedArea, area);
|
||||
allocated = area;
|
||||
}
|
||||
|
||||
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea));
|
||||
if (!newArea)
|
||||
return (vaddr_t)NULL;
|
||||
|
||||
// Avoid insertSorted(freeArea, newArea) call by modifying area
|
||||
|
||||
newArea->nbPages = nbPages;
|
||||
newArea->startAddr = area->startAddr;
|
||||
|
||||
area->nbPages -= nbPages;
|
||||
area->startAddr += nbPages * PAGE_SIZE;
|
||||
|
||||
insertSorted(usedArea, newArea);
|
||||
|
||||
allocated = newArea;
|
||||
|
||||
for (uint i = 0; i < nbPages; i++) {
|
||||
paddr_t page = allocPhyPage(1);
|
||||
if (page) {
|
||||
pageMap(area->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
||||
} else {
|
||||
// TODO
|
||||
assert(1);
|
||||
}
|
||||
}
|
||||
|
||||
return allocated->startAddr;
|
||||
}
|
||||
|
||||
static int areaMergeFreeArea(struct memArea *prev, struct memArea *next)
|
||||
{
|
||||
if (prev->startAddr + prev->nbPages * PAGE_SIZE != next->startAddr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
prev->nbPages += next->nbPages;
|
||||
list_delete(freeArea, next);
|
||||
free(next);
|
||||
|
||||
next = prev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct memArea *areaFindMemArea(struct memArea *list, vaddr_t addr)
|
||||
{
|
||||
struct memArea *area;
|
||||
int count;
|
||||
list_foreach(list, area, count)
|
||||
{
|
||||
if (area->startAddr <= addr && addr <= area->startAddr + area->nbPages * PAGE_SIZE)
|
||||
return area;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int areaFree(vaddr_t addr)
|
||||
{
|
||||
struct memArea *area;
|
||||
|
||||
area = areaFindMemArea(usedArea, addr);
|
||||
if (!area) {
|
||||
pr_info("Cannot find memArea associated to %p\n", addr);
|
||||
return -1;
|
||||
}
|
||||
list_delete(usedArea, area);
|
||||
insertSorted(freeArea, area);
|
||||
|
||||
if (area->prev)
|
||||
areaMergeFreeArea(area->prev, area);
|
||||
|
||||
if (area->next)
|
||||
areaMergeFreeArea(area, area->next);
|
||||
|
||||
return 0;
|
||||
}
|
4
core/allocArea.h
Normal file
4
core/allocArea.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "paging.h"
|
||||
|
||||
void areaInit(void);
|
Loading…
Reference in New Issue
Block a user