user_space #4
95
core/alloc.c
95
core/alloc.c
@ -17,7 +17,7 @@ static struct slabDesc *slub;
|
|||||||
static int allocInitialized = FALSE;
|
static int allocInitialized = FALSE;
|
||||||
|
|
||||||
static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab,
|
static int allocSlab(struct slabDesc **desc, size_t sizeEl, size_t sizeSlab,
|
||||||
int self_containing);
|
int self_containing, int neverEmpty);
|
||||||
static int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSlab,
|
static int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSlab,
|
||||||
int selfContained);
|
int selfContained);
|
||||||
static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained);
|
static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained);
|
||||||
@ -28,27 +28,29 @@ static struct {
|
|||||||
size_t elementSize;
|
size_t elementSize;
|
||||||
size_t slabSize;
|
size_t slabSize;
|
||||||
unsigned char isSelf;
|
unsigned char isSelf;
|
||||||
} initSlab[] = {{4, PAGE_SIZE, 0},
|
unsigned char neverEmpty;
|
||||||
{8, PAGE_SIZE, 0},
|
} initSlab[] = {{4, PAGE_SIZE, 0, 0},
|
||||||
{16, PAGE_SIZE, 0},
|
{8, PAGE_SIZE, 0, 0},
|
||||||
{32, PAGE_SIZE, 0},
|
{16, PAGE_SIZE, 0, 0},
|
||||||
{64, PAGE_SIZE, 0},
|
{32, PAGE_SIZE, 0, 0},
|
||||||
{128, PAGE_SIZE, 0},
|
{64, PAGE_SIZE, 0, 0},
|
||||||
{256, 2 * PAGE_SIZE, 0},
|
{128, PAGE_SIZE, 0, 0},
|
||||||
{1024, 2 * PAGE_SIZE, 0},
|
{256, 2 * PAGE_SIZE, 0, 0},
|
||||||
{2048, 3 * PAGE_SIZE, 0},
|
{1024, 2 * PAGE_SIZE, 0, 0},
|
||||||
{4096, 4 * PAGE_SIZE, 0},
|
{2048, 3 * PAGE_SIZE, 0, 0},
|
||||||
{0, 0, 0}};
|
{4096, 4 * PAGE_SIZE, 0, 0},
|
||||||
|
{0, 0, 0, 0}};
|
||||||
|
|
||||||
int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr)
|
int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr)
|
||||||
{
|
{
|
||||||
list_init(slub);
|
list_init(slub);
|
||||||
|
|
||||||
assert(allocBookSlab(sizeof(struct slabDesc), PAGE_SIZE, TRUE) == 0);
|
assert(allocBookSlab(sizeof(struct slabDesc), PAGE_SIZE, TRUE, FALSE) == 0);
|
||||||
*descAddr = (vaddr_t)allocGetSlab(sizeof(struct slabDesc));
|
*descAddr = (vaddr_t)allocGetSlab(sizeof(struct slabDesc));
|
||||||
assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE) == 0);
|
assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE, FALSE) == 0);
|
||||||
*entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry));
|
*entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry));
|
||||||
assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE) == 0);
|
printf("allocSetup for sizeOfArea %d\n", sizeOfArea);
|
||||||
|
assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE, TRUE) == 0);
|
||||||
*areaAddr = (vaddr_t)allocGetSlab(sizeOfArea);
|
*areaAddr = (vaddr_t)allocGetSlab(sizeOfArea);
|
||||||
allocInitialized = TRUE;
|
allocInitialized = TRUE;
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ int allocPopulate()
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((ret = allocBookSlab(initSlab[i].elementSize, initSlab[i].slabSize,
|
if ((ret = allocBookSlab(initSlab[i].elementSize, initSlab[i].slabSize,
|
||||||
initSlab[i].isSelf))) {
|
initSlab[i].isSelf, initSlab[i].neverEmpty))) {
|
||||||
if (ret == -EEXIST)
|
if (ret == -EEXIST)
|
||||||
continue;
|
continue;
|
||||||
pr_err("Fail to allocBookSlab %d for %d \n", ret, (1U << i));
|
pr_err("Fail to allocBookSlab %d for %d \n", ret, (1U << i));
|
||||||
@ -73,7 +75,7 @@ int allocPopulate()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained)
|
int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained, int neverEmpty)
|
||||||
{
|
{
|
||||||
struct slabDesc *slab = NULL;
|
struct slabDesc *slab = NULL;
|
||||||
struct slabDesc *newSlab = NULL;
|
struct slabDesc *newSlab = NULL;
|
||||||
@ -95,7 +97,7 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = allocSlab(&newSlab, sizeEl, sizeSlab, selfContained))) {
|
if ((ret = allocSlab(&newSlab, sizeEl, sizeSlab, selfContained, neverEmpty))) {
|
||||||
pr_devel("Failed to alloc Slab\n");
|
pr_devel("Failed to alloc Slab\n");
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
return ret;
|
return ret;
|
||||||
@ -112,7 +114,8 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfContained)
|
static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int selfContained,
|
||||||
|
int neverEmpty)
|
||||||
{
|
{
|
||||||
uint nbPage, i;
|
uint nbPage, i;
|
||||||
vaddr_t alloc;
|
vaddr_t alloc;
|
||||||
@ -153,10 +156,11 @@ static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int s
|
|||||||
|
|
||||||
struct slabEntry *slab = &(*desc)->slab;
|
struct slabEntry *slab = &(*desc)->slab;
|
||||||
list_singleton(slab, slab);
|
list_singleton(slab, slab);
|
||||||
slab->page = (vaddr_t)alloc;
|
slab->page = (vaddr_t)alloc;
|
||||||
slab->full = 0;
|
slab->full = 0;
|
||||||
slab->size = sizeSlab;
|
slab->size = sizeSlab;
|
||||||
(*desc)->size = size;
|
(*desc)->neverEmpty = neverEmpty;
|
||||||
|
(*desc)->size = size;
|
||||||
|
|
||||||
return formatPage(&(*desc)->slab, size, sizeSlab, selfContained);
|
return formatPage(&(*desc)->slab, size, sizeSlab, selfContained);
|
||||||
|
|
||||||
@ -202,8 +206,6 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
|
|||||||
(*desc)->size = sizeSlab;
|
(*desc)->size = sizeSlab;
|
||||||
|
|
||||||
return formatPage((*desc), size, sizeSlab, selfContained);
|
return formatPage((*desc), size, sizeSlab, selfContained);
|
||||||
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained)
|
static int formatPage(struct slabEntry *desc, size_t size, size_t sizeSlab, int selfContained)
|
||||||
@ -261,7 +263,7 @@ void *malloc(size_t size)
|
|||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
|
|
||||||
if (size >= PAGE_SIZE){
|
if (size >= PAGE_SIZE) {
|
||||||
vaddr_t area = areaAlloc(DIV_ROUND_UP(size, PAGE_SIZE), AREA_PHY_MAP);
|
vaddr_t area = areaAlloc(DIV_ROUND_UP(size, PAGE_SIZE), AREA_PHY_MAP);
|
||||||
|
|
||||||
return (void *)area;
|
return (void *)area;
|
||||||
@ -271,12 +273,36 @@ void *malloc(size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct slabEntry *slabList = &slab->slab;
|
||||||
list_foreach(&slab->slab, slabEntry, slabIdx)
|
list_foreach(&slab->slab, slabEntry, slabIdx)
|
||||||
{
|
{
|
||||||
if (!slabEntry->full) {
|
if (!slabEntry->full) {
|
||||||
// pr_devel("found place in slub %d at idx %d for size %d\n", slubIdx,
|
// pr_devel("found place in slab idx %d for size %d\n", slabIdx, slab->size);
|
||||||
// slabIdx, size);
|
|
||||||
ret = allocFromSlab(slabEntry);
|
ret = allocFromSlab(slabEntry);
|
||||||
|
if (slabEntry->full && slab->neverEmpty) {
|
||||||
|
|
||||||
|
pr_devel("Prealloc place for slab for object size %d\n", slab->size);
|
||||||
|
assert(IS_SELF_CONTAINED(slabEntry));
|
||||||
|
size_t slabSize = slabEntry->size;
|
||||||
|
int nbPages = DIV_ROUND_UP(slabSize, PAGE_SIZE);
|
||||||
|
struct slabEntry *entry = (struct slabEntry *)areaBook(nbPages, AREA_PHY_MAP);
|
||||||
|
if (entry == NULL) {
|
||||||
|
restore_IRQs(flags);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
(entry)->freeEl = (char *)(entry) + sizeof(struct slabEntry);
|
||||||
|
list_singleton(entry, entry);
|
||||||
|
entry->page = (vaddr_t)entry;
|
||||||
|
entry->full = 0;
|
||||||
|
entry->size = slabSize;
|
||||||
|
|
||||||
|
formatPage(entry, slab->size, slabSize, 1);
|
||||||
|
list_add_tail(slabList, entry);
|
||||||
|
areaAdd((vaddr_t)entry, (vaddr_t)entry + nbPages * PAGE_SIZE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -284,8 +310,7 @@ void *malloc(size_t size)
|
|||||||
|
|
||||||
// No room found
|
// No room found
|
||||||
struct slabEntry *newSlabEntry;
|
struct slabEntry *newSlabEntry;
|
||||||
struct slabEntry *slabList = &slab->slab;
|
size_t slabSize = MAX(PAGE_SIZE, size);
|
||||||
size_t slabSize = MAX(PAGE_SIZE, size);
|
|
||||||
int retSlab;
|
int retSlab;
|
||||||
|
|
||||||
if ((retSlab = allocSlabEntry(&newSlabEntry, slab->size, slabSize,
|
if ((retSlab = allocSlabEntry(&newSlabEntry, slab->size, slabSize,
|
||||||
@ -304,7 +329,8 @@ void *malloc(size_t size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *zalloc(size_t size){
|
void *zalloc(size_t size)
|
||||||
|
{
|
||||||
void *alloc = malloc(size);
|
void *alloc = malloc(size);
|
||||||
|
|
||||||
if (alloc != NULL)
|
if (alloc != NULL)
|
||||||
@ -333,7 +359,8 @@ static int freeFromSlab(void *ptr, struct slabEntry *slab)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int freeSlabAllocated(void *ptr){
|
int freeSlabAllocated(void *ptr)
|
||||||
|
{
|
||||||
struct slabDesc *slab;
|
struct slabDesc *slab;
|
||||||
int slabIdx;
|
int slabIdx;
|
||||||
int flags;
|
int flags;
|
||||||
@ -361,8 +388,8 @@ void free(void *ptr)
|
|||||||
{
|
{
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
if(!freeSlabAllocated(ptr))
|
if (!freeSlabAllocated(ptr))
|
||||||
return;
|
return;
|
||||||
if(areaFree((vaddr_t)ptr))
|
if (areaFree((vaddr_t)ptr))
|
||||||
pr_err("free: cannot found origin\n");
|
pr_err("free: cannot found origin\n");
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ int allocPopulate();
|
|||||||
* Allow malloc to allocate elements of this precise size.
|
* Allow malloc to allocate elements of this precise size.
|
||||||
* Otherwise the allocation will be in the closest biggest pool.
|
* Otherwise the allocation will be in the closest biggest pool.
|
||||||
* */
|
* */
|
||||||
int allocBookSlab(size_t size, size_t sizeSlab, int selfContained);
|
int allocBookSlab(size_t size, size_t sizeSlab, int selfContained, int neverEmpty);
|
||||||
|
|
||||||
void *malloc(size_t size);
|
void *malloc(size_t size);
|
||||||
void *zalloc(size_t size);
|
void *zalloc(size_t size);
|
||||||
@ -22,9 +22,9 @@ void free(void *ptr);
|
|||||||
*/
|
*/
|
||||||
struct slabEntry {
|
struct slabEntry {
|
||||||
vaddr_t page;
|
vaddr_t page;
|
||||||
size_t size;
|
|
||||||
void *freeEl;
|
void *freeEl;
|
||||||
char full;
|
size_t size;
|
||||||
|
bool_t full;//TODO replace by freeEl == NULL
|
||||||
struct slabEntry *next;
|
struct slabEntry *next;
|
||||||
struct slabEntry *prev;
|
struct slabEntry *prev;
|
||||||
};
|
};
|
||||||
@ -32,6 +32,7 @@ struct slabEntry {
|
|||||||
struct slabDesc {
|
struct slabDesc {
|
||||||
struct slabEntry slab;
|
struct slabEntry slab;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
bool_t neverEmpty;
|
||||||
struct slabDesc *next;
|
struct slabDesc *next;
|
||||||
struct slabDesc *prev;
|
struct slabDesc *prev;
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "irq.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
@ -71,13 +72,64 @@ static void insertSorted(struct memArea **list, struct memArea *item)
|
|||||||
list_add_tail(*list, item);
|
list_add_tail(*list, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vaddr_t areaBook(unsigned int nbPages, uint32_t flags){
|
||||||
|
|
||||||
|
struct memArea *area;
|
||||||
|
vaddr_t allocated;
|
||||||
|
uint32_t irqFlags;
|
||||||
|
|
||||||
|
disable_IRQs(irqFlags);
|
||||||
|
|
||||||
|
area = areaFindFit(nbPages);
|
||||||
|
if (!area){
|
||||||
|
printf("NULL<\n");
|
||||||
|
restore_IRQs(irqFlags);
|
||||||
|
|
||||||
|
return (vaddr_t)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (area->nbPages == nbPages) {
|
||||||
|
list_delete(freeArea, area);
|
||||||
|
allocated = area->startAddr;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
allocated = area->startAddr;
|
||||||
|
|
||||||
|
area->nbPages -= nbPages;
|
||||||
|
area->startAddr += nbPages * PAGE_SIZE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & AREA_PHY_MAP) {
|
||||||
|
for (uint i = 0; i < nbPages; i++) {
|
||||||
|
paddr_t page = allocPhyPage(1);
|
||||||
|
if (page) {
|
||||||
|
pageMap(allocated + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
||||||
|
} else {
|
||||||
|
printf("Ooops\n");
|
||||||
|
// TODO
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
restore_IRQs(irqFlags);
|
||||||
|
return allocated;
|
||||||
|
}
|
||||||
|
|
||||||
vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags)
|
vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags)
|
||||||
{
|
{
|
||||||
struct memArea *area, *allocated;
|
struct memArea *area, *allocated;
|
||||||
|
uint32_t irqFlags;
|
||||||
|
|
||||||
|
disable_IRQs(irqFlags);
|
||||||
|
|
||||||
area = areaFindFit(nbPages);
|
area = areaFindFit(nbPages);
|
||||||
if (!area)
|
if (!area){
|
||||||
|
restore_IRQs(irqFlags);
|
||||||
|
|
||||||
return (vaddr_t)NULL;
|
return (vaddr_t)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (area->nbPages == nbPages) {
|
if (area->nbPages == nbPages) {
|
||||||
list_delete(freeArea, area);
|
list_delete(freeArea, area);
|
||||||
@ -87,6 +139,7 @@ vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags)
|
|||||||
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea));
|
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea));
|
||||||
if (!newArea) {
|
if (!newArea) {
|
||||||
pr_devel("Failed to allocated area of %d pages\n", nbPages);
|
pr_devel("Failed to allocated area of %d pages\n", nbPages);
|
||||||
|
restore_IRQs(irqFlags);
|
||||||
return (vaddr_t)NULL;
|
return (vaddr_t)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,12 +162,14 @@ vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags)
|
|||||||
if (page) {
|
if (page) {
|
||||||
pageMap(allocated->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
pageMap(allocated->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
||||||
} else {
|
} else {
|
||||||
|
printf("Ooops\n");
|
||||||
// TODO
|
// TODO
|
||||||
assert(1);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_IRQs(irqFlags);
|
||||||
return allocated->startAddr;
|
return allocated->startAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,5 +18,9 @@ struct memArea {
|
|||||||
|
|
||||||
void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed, vaddr_t stack_bottom, vaddr_t stack_top);
|
void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed, vaddr_t stack_bottom, vaddr_t stack_top);
|
||||||
vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags);
|
vaddr_t areaAlloc(unsigned int nbPages, uint32_t flags);
|
||||||
|
// Remove an area from the free ones but do not add it into used ones.
|
||||||
|
// This area should be latter added woth areaAdd.
|
||||||
|
// Used by malloc to avoid recursivity issue
|
||||||
|
vaddr_t areaBook(unsigned int nbPages, uint32_t flags);
|
||||||
int areaFree(vaddr_t addr);
|
int areaFree(vaddr_t addr);
|
||||||
int areaAdd(vaddr_t begin, vaddr_t end, int isFree);
|
int areaAdd(vaddr_t begin, vaddr_t end, int isFree);
|
||||||
|
@ -133,6 +133,7 @@ paddr_t allocPhyPage(uint nbPage)
|
|||||||
next = mem->next;
|
next = mem->next;
|
||||||
}
|
}
|
||||||
allocatedPage += nbPage;
|
allocatedPage += nbPage;
|
||||||
|
|
||||||
return head->phy_addr;
|
return head->phy_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user