areaIntegration #1
116
core/alloc.c
116
core/alloc.c
@ -1,6 +1,8 @@
|
|||||||
#define pr_fmt(fmt) "[alloc]: " fmt
|
#define pr_fmt(fmt) "[alloc]: " fmt
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "allocArea.h"
|
||||||
|
#include "assert.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
@ -11,8 +13,8 @@
|
|||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
|
||||||
#define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc))
|
#define IS_SELF_CONTAINED(desc) ((vaddr_t)((desc)->page) == (vaddr_t)(desc))
|
||||||
// Slab will contains object from sizeof(void *) to PAGE_SIZE/2 by pow2
|
|
||||||
static struct slabDesc *slub;
|
static struct slabDesc *slub;
|
||||||
|
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);
|
||||||
@ -20,14 +22,13 @@ static int allocSlabEntry(struct slabEntry **desc, size_t sizeEl, size_t sizeSla
|
|||||||
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);
|
||||||
static int freeFromSlab(void *ptr, struct slabEntry *slab);
|
static int freeFromSlab(void *ptr, struct slabEntry *slab);
|
||||||
|
static struct slabDesc *allocGetSlab(size_t size);
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
size_t elementSize;
|
size_t elementSize;
|
||||||
size_t slabSize;
|
size_t slabSize;
|
||||||
unsigned char isSelf;
|
unsigned char isSelf;
|
||||||
} initSlab[] = {{sizeof(struct slabDesc), PAGE_SIZE, 1},
|
} initSlab[] = {{4, PAGE_SIZE, 0},
|
||||||
{sizeof(struct slabEntry), PAGE_SIZE, 1},
|
|
||||||
{4, PAGE_SIZE, 0},
|
|
||||||
{8, PAGE_SIZE, 0},
|
{8, PAGE_SIZE, 0},
|
||||||
{16, PAGE_SIZE, 0},
|
{16, PAGE_SIZE, 0},
|
||||||
{32, PAGE_SIZE, 0},
|
{32, PAGE_SIZE, 0},
|
||||||
@ -37,14 +38,25 @@ static struct {
|
|||||||
{1024, 2 * PAGE_SIZE, 0},
|
{1024, 2 * PAGE_SIZE, 0},
|
||||||
{2048, 3 * PAGE_SIZE, 0},
|
{2048, 3 * PAGE_SIZE, 0},
|
||||||
{4096, 4 * PAGE_SIZE, 0},
|
{4096, 4 * PAGE_SIZE, 0},
|
||||||
{8192, 8 * PAGE_SIZE, 0},
|
|
||||||
{16384, 12 * PAGE_SIZE, 0},
|
|
||||||
{0, 0, 0}};
|
{0, 0, 0}};
|
||||||
|
|
||||||
int allocSetup(void)
|
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);
|
||||||
|
*descAddr = (vaddr_t)allocGetSlab(sizeof(struct slabDesc));
|
||||||
|
assert(allocBookSlab(sizeof(struct slabEntry), PAGE_SIZE, TRUE) == 0);
|
||||||
|
*entryAddr = (vaddr_t)allocGetSlab(sizeof(struct slabEntry));
|
||||||
|
assert(allocBookSlab(sizeOfArea, PAGE_SIZE, TRUE) == 0);
|
||||||
|
*areaAddr = (vaddr_t)allocGetSlab(sizeOfArea);
|
||||||
|
allocInitialized = TRUE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int allocPopulate()
|
||||||
|
{
|
||||||
for (uint i = 0; initSlab[i].elementSize != 0; i++) {
|
for (uint i = 0; initSlab[i].elementSize != 0; i++) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -52,7 +64,7 @@ int allocSetup(void)
|
|||||||
initSlab[i].isSelf))) {
|
initSlab[i].isSelf))) {
|
||||||
if (ret == -EEXIST)
|
if (ret == -EEXIST)
|
||||||
continue;
|
continue;
|
||||||
pr_devel("Fail to allocBookSlab %d for %d \n", ret, (1U << i));
|
pr_err("Fail to allocBookSlab %d for %d \n", ret, (1U << i));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -84,6 +96,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))) {
|
||||||
|
pr_devel("Failed to alloc Slab\n");
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -102,6 +115,7 @@ int allocBookSlab(size_t sizeEl, size_t sizeSlab, int selfContained)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
uint nbPage, i;
|
uint nbPage, i;
|
||||||
|
vaddr_t alloc;
|
||||||
|
|
||||||
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained);
|
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained);
|
||||||
|
|
||||||
@ -111,21 +125,27 @@ static int allocSlab(struct slabDesc **desc, size_t size, size_t sizeSlab, int s
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
|
nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
|
||||||
paddr_t alloc = allocPhyPage(nbPage);
|
if (allocInitialized) {
|
||||||
if (alloc == (paddr_t)NULL)
|
alloc = areaAlloc(nbPage);
|
||||||
return -ENOMEM;
|
if (alloc == (paddr_t)NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
} else {
|
||||||
|
alloc = (vaddr_t)allocPhyPage(nbPage);
|
||||||
|
if (alloc == (paddr_t)NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < nbPage; i++) {
|
for (i = 0; i < nbPage; i++) {
|
||||||
if (pageMap((vaddr_t)alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE))
|
if (pageMap(alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE))
|
||||||
goto free_page;
|
goto free_page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selfContained) {
|
if (selfContained) {
|
||||||
*desc = (struct slabDesc *)alloc;
|
*desc = (struct slabDesc *)alloc;
|
||||||
((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc);
|
((*desc)->slab).freeEl = (char *)(*desc) + sizeof(struct slabDesc);
|
||||||
} else {
|
} else {
|
||||||
*desc = malloc(sizeof(struct slabDesc));
|
*desc = malloc(sizeof(struct slabDesc));
|
||||||
if (*desc == NULL)
|
if (*desc == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
(*desc)->slab.freeEl = (void *)alloc;
|
(*desc)->slab.freeEl = (void *)alloc;
|
||||||
@ -151,7 +171,7 @@ free_page:
|
|||||||
static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
|
static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
|
||||||
int selfContained)
|
int selfContained)
|
||||||
{
|
{
|
||||||
uint nbPage, i;
|
uint nbPage;
|
||||||
|
|
||||||
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained);
|
pr_devel("%s for size %d is self %d\n", __func__, size, selfContained);
|
||||||
|
|
||||||
@ -162,20 +182,15 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
|
nbPage = DIV_ROUND_UP(sizeSlab, PAGE_SIZE);
|
||||||
paddr_t alloc = allocPhyPage(nbPage);
|
vaddr_t alloc = areaAlloc(nbPage);
|
||||||
if (alloc == (paddr_t)NULL)
|
if (alloc == (paddr_t)NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < nbPage; i++) {
|
|
||||||
if (pageMap((vaddr_t)alloc + i * PAGE_SIZE, alloc + i * PAGE_SIZE, PAGING_MEM_WRITE))
|
|
||||||
goto free_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selfContained) {
|
if (selfContained) {
|
||||||
*desc = (struct slabEntry *)alloc;
|
*desc = (struct slabEntry *)alloc;
|
||||||
(*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry);
|
(*desc)->freeEl = (char *)(*desc) + sizeof(struct slabEntry);
|
||||||
} else {
|
} else {
|
||||||
*desc = malloc(sizeof(struct slabEntry));
|
*desc = malloc(sizeof(struct slabEntry));
|
||||||
if (*desc == NULL)
|
if (*desc == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
(*desc)->freeEl = (void *)alloc;
|
(*desc)->freeEl = (void *)alloc;
|
||||||
@ -188,11 +203,6 @@ static int allocSlabEntry(struct slabEntry **desc, size_t size, size_t sizeSlab,
|
|||||||
|
|
||||||
return formatPage((*desc), size, sizeSlab, selfContained);
|
return formatPage((*desc), size, sizeSlab, selfContained);
|
||||||
|
|
||||||
free_page:
|
|
||||||
for (uint j = 0; j < i; j++) {
|
|
||||||
pageUnmap((vaddr_t)alloc + i * PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,24 +237,36 @@ static void *allocFromSlab(struct slabEntry *slab)
|
|||||||
return (void *)next;
|
return (void *)next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct slabDesc *allocGetSlab(size_t size)
|
||||||
|
{
|
||||||
|
struct slabDesc *slab = NULL;
|
||||||
|
uint slubIdx;
|
||||||
|
|
||||||
|
list_foreach(slub, slab, slubIdx)
|
||||||
|
{
|
||||||
|
if (size <= slab->size)
|
||||||
|
return slab;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void *malloc(size_t size)
|
void *malloc(size_t size)
|
||||||
{
|
{
|
||||||
struct slabEntry *slabEntry;
|
struct slabEntry *slabEntry;
|
||||||
struct slabDesc *slab = NULL;
|
struct slabDesc *slab = NULL;
|
||||||
uint slubIdx;
|
|
||||||
void *ret;
|
void *ret;
|
||||||
int flags;
|
int flags;
|
||||||
int slabIdx;
|
int slabIdx;
|
||||||
|
|
||||||
disable_IRQs(flags);
|
disable_IRQs(flags);
|
||||||
|
|
||||||
list_foreach(slub, slab, slubIdx)
|
if (size >= PAGE_SIZE){
|
||||||
{
|
vaddr_t area = areaAlloc(DIV_ROUND_UP(size, PAGE_SIZE));
|
||||||
if (size <= slab->size)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!list_foreach_early_break(slub, slab, slubIdx)) {
|
return (void *)area;
|
||||||
|
}
|
||||||
|
if ((slab = allocGetSlab(size)) == NULL) {
|
||||||
pr_devel("No slab found for %d\n", size);
|
pr_devel("No slab found for %d\n", size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -302,11 +324,7 @@ static int freeFromSlab(void *ptr, struct slabEntry *slab)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void *ptr)
|
int freeSlabAllocated(void *ptr){
|
||||||
{
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct slabDesc *slab;
|
struct slabDesc *slab;
|
||||||
int slabIdx;
|
int slabIdx;
|
||||||
int flags;
|
int flags;
|
||||||
@ -321,11 +339,21 @@ void free(void *ptr)
|
|||||||
{
|
{
|
||||||
if (freeFromSlab(ptr, slabEntry)) {
|
if (freeFromSlab(ptr, slabEntry)) {
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_IRQs(flags);
|
restore_IRQs(flags);
|
||||||
pr_devel("free: slab not found\n");
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(void *ptr)
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
if(!freeSlabAllocated(ptr))
|
||||||
|
return;
|
||||||
|
if(areaFree((vaddr_t)ptr))
|
||||||
|
pr_err("free: cannot found origin\n");
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
/*
|
/*
|
||||||
* Initialize malloc system
|
* Initialize malloc system
|
||||||
*/
|
*/
|
||||||
int allocSetup(void);
|
int allocSetup(size_t sizeOfArea, vaddr_t *areaAddr, vaddr_t *descAddr, vaddr_t *entryAddr);
|
||||||
|
|
||||||
|
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.
|
||||||
|
@ -6,20 +6,29 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
|
|
||||||
struct memArea {
|
|
||||||
vaddr_t startAddr;
|
|
||||||
uint nbPages;
|
|
||||||
struct memArea *next;
|
|
||||||
struct memArea *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct memArea *freeArea;
|
static struct memArea *freeArea;
|
||||||
static struct memArea *usedArea;
|
static struct memArea *usedArea;
|
||||||
|
|
||||||
void areaInit(void)
|
static int areaMergeFreeArea(struct memArea *prev, struct memArea *next);
|
||||||
|
|
||||||
|
void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed)
|
||||||
{
|
{
|
||||||
list_init(freeArea);
|
list_init(freeArea);
|
||||||
list_init(usedArea);
|
list_init(usedArea);
|
||||||
|
|
||||||
|
vaddr_t areaAddr, descAddr, entryAddr;
|
||||||
|
allocSetup(sizeof(struct memArea), &areaAddr, &descAddr, &entryAddr);
|
||||||
|
areaAdd(descAddr, PAGE_SIZE, FALSE);
|
||||||
|
if (entryAddr != descAddr)
|
||||||
|
areaAdd(entryAddr, PAGE_SIZE, FALSE);
|
||||||
|
if (areaAddr != descAddr && areaAddr != entryAddr)
|
||||||
|
areaAdd(areaAddr, PAGE_SIZE, FALSE);
|
||||||
|
|
||||||
|
int nbPages = DIV_ROUND_UP((lastUsed - firstMemUsed), PAGE_SIZE);
|
||||||
|
areaAdd(ALIGN_DOWN(firstMemUsed, PAGE_SIZE), nbPages, FALSE);
|
||||||
|
areaAdd(ALIGN_DOWN(areaAddr + PAGE_SIZE, PAGE_SIZE), 300 , TRUE);
|
||||||
|
allocPopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct memArea *areaFindFit(unsigned int nbPages)
|
struct memArea *areaFindFit(unsigned int nbPages)
|
||||||
@ -35,22 +44,22 @@ struct memArea *areaFindFit(unsigned int nbPages)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void insertSorted(struct memArea *list, struct memArea *item)
|
static void insertSorted(struct memArea **list, struct memArea *item)
|
||||||
{
|
{
|
||||||
struct memArea *prev, *cur;
|
struct memArea *prev, *cur;
|
||||||
int count;
|
int count;
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
|
|
||||||
list_foreach(list, cur, count)
|
list_foreach(*list, cur, count)
|
||||||
{
|
{
|
||||||
if (cur->startAddr > item->startAddr)
|
if (cur->startAddr > item->startAddr)
|
||||||
break;
|
break;
|
||||||
prev = cur;
|
prev = cur;
|
||||||
}
|
}
|
||||||
if (prev)
|
if (prev)
|
||||||
list_insert_after(list, prev, item);
|
list_insert_after(*list, prev, item);
|
||||||
else
|
else
|
||||||
list_add_tail(list, item);
|
list_add_tail(*list, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
vaddr_t areaAlloc(unsigned int nbPages)
|
vaddr_t areaAlloc(unsigned int nbPages)
|
||||||
@ -63,13 +72,15 @@ vaddr_t areaAlloc(unsigned int nbPages)
|
|||||||
|
|
||||||
if (area->nbPages == nbPages) {
|
if (area->nbPages == nbPages) {
|
||||||
list_delete(freeArea, area);
|
list_delete(freeArea, area);
|
||||||
insertSorted(usedArea, area);
|
insertSorted(&usedArea, area);
|
||||||
allocated = area;
|
allocated = area;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
return (vaddr_t)NULL;
|
return (vaddr_t)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid insertSorted(freeArea, newArea) call by modifying area
|
// Avoid insertSorted(freeArea, newArea) call by modifying area
|
||||||
|
|
||||||
@ -79,14 +90,14 @@ vaddr_t areaAlloc(unsigned int nbPages)
|
|||||||
area->nbPages -= nbPages;
|
area->nbPages -= nbPages;
|
||||||
area->startAddr += nbPages * PAGE_SIZE;
|
area->startAddr += nbPages * PAGE_SIZE;
|
||||||
|
|
||||||
insertSorted(usedArea, newArea);
|
insertSorted(&usedArea, newArea);
|
||||||
|
|
||||||
allocated = newArea;
|
allocated = newArea;
|
||||||
|
|
||||||
for (uint i = 0; i < nbPages; i++) {
|
for (uint i = 0; i < nbPages; i++) {
|
||||||
paddr_t page = allocPhyPage(1);
|
paddr_t page = allocPhyPage(1);
|
||||||
if (page) {
|
if (page) {
|
||||||
pageMap(area->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
pageMap(newArea->startAddr + i * PAGE_SIZE, page, PAGING_MEM_WRITE);
|
||||||
} else {
|
} else {
|
||||||
// TODO
|
// TODO
|
||||||
assert(1);
|
assert(1);
|
||||||
@ -96,6 +107,36 @@ vaddr_t areaAlloc(unsigned int nbPages)
|
|||||||
return allocated->startAddr;
|
return allocated->startAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int areaAdd(vaddr_t addr, uint nbPages, int isFree)
|
||||||
|
{
|
||||||
|
struct memArea **area;
|
||||||
|
|
||||||
|
struct memArea *newArea = (struct memArea *)malloc(sizeof(struct memArea));
|
||||||
|
if (!newArea)
|
||||||
|
return (vaddr_t)NULL;
|
||||||
|
|
||||||
|
newArea->nbPages = nbPages;
|
||||||
|
newArea->startAddr = addr;
|
||||||
|
|
||||||
|
if (isFree) {
|
||||||
|
area = &freeArea;
|
||||||
|
} else {
|
||||||
|
area = &usedArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
insertSorted(area, newArea);
|
||||||
|
|
||||||
|
if (isFree) {
|
||||||
|
if (newArea->prev)
|
||||||
|
areaMergeFreeArea(newArea->prev, *area);
|
||||||
|
|
||||||
|
if (newArea->next)
|
||||||
|
areaMergeFreeArea(*area, newArea->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int areaMergeFreeArea(struct memArea *prev, struct memArea *next)
|
static int areaMergeFreeArea(struct memArea *prev, struct memArea *next)
|
||||||
{
|
{
|
||||||
if (prev->startAddr + prev->nbPages * PAGE_SIZE != next->startAddr) {
|
if (prev->startAddr + prev->nbPages * PAGE_SIZE != next->startAddr) {
|
||||||
@ -134,7 +175,7 @@ int areaFree(vaddr_t addr)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
list_delete(usedArea, area);
|
list_delete(usedArea, area);
|
||||||
insertSorted(freeArea, area);
|
insertSorted(&freeArea, area);
|
||||||
|
|
||||||
if (area->prev)
|
if (area->prev)
|
||||||
areaMergeFreeArea(area->prev, area);
|
areaMergeFreeArea(area->prev, area);
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
|
#include "stdarg.h"
|
||||||
|
|
||||||
void areaInit(void);
|
struct memArea {
|
||||||
|
vaddr_t startAddr;
|
||||||
|
uint nbPages;
|
||||||
|
|
||||||
|
struct memArea *next;
|
||||||
|
struct memArea *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
void areaInit(vaddr_t firstMemUsed, vaddr_t lastUsed);
|
||||||
vaddr_t areaAlloc(unsigned int nbPages);
|
vaddr_t areaAlloc(unsigned int nbPages);
|
||||||
int areaFree(vaddr_t addr);
|
int areaFree(vaddr_t addr);
|
||||||
|
int areaAdd(vaddr_t addr, uint nbPages, int isFree);
|
||||||
|
@ -51,3 +51,4 @@ int vasprintf(char **strp, const char *fmt, va_list ap);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__)
|
#define pr_info(fmt, ...) printf(pr_fmt(fmt), ##__VA_ARGS__)
|
||||||
|
#define pr_err(fmt, ...) {printf(pr_fmt(fmt), ##__VA_ARGS__); assert(0);}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "allocArea.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
@ -143,7 +144,8 @@ void kmain(unsigned long magic, unsigned long addr)
|
|||||||
serialSetup(115200);
|
serialSetup(115200);
|
||||||
|
|
||||||
printf("Setting up allocation system\n");
|
printf("Setting up allocation system\n");
|
||||||
allocSetup();
|
areaInit(firstUsedByMem, lastUsedByMem);
|
||||||
|
//allocSetup();
|
||||||
|
|
||||||
printf("Setting up thread system\n");
|
printf("Setting up thread system\n");
|
||||||
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
|
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
|
||||||
|
@ -136,6 +136,92 @@ class PhyMemDescListDumpCmd(gdb.Command):
|
|||||||
print(self._phy_memDesc_lit_to_str(desc))
|
print(self._phy_memDesc_lit_to_str(desc))
|
||||||
|
|
||||||
|
|
||||||
|
class PrintStructC99Cmd(gdb.Command):
|
||||||
|
def __init__(self):
|
||||||
|
super(PrintStructC99Cmd, self).__init__(
|
||||||
|
"print_struct_c99",
|
||||||
|
gdb.COMMAND_USER,
|
||||||
|
)
|
||||||
|
|
||||||
|
def complete(self, text, word):
|
||||||
|
return gdb.COMPLETE_SYMBOL
|
||||||
|
|
||||||
|
def get_count_heading(self, string):
|
||||||
|
for i, s in enumerate(string):
|
||||||
|
if s != ' ':
|
||||||
|
break
|
||||||
|
return i
|
||||||
|
|
||||||
|
def extract_typename(self, string):
|
||||||
|
first_line = string.split('\n')[0]
|
||||||
|
return first_line.split('=')[1][:-1].strip()
|
||||||
|
|
||||||
|
def invoke(self, arg, from_tty):
|
||||||
|
gdb.execute("set print pretty")
|
||||||
|
gdb.execute('set pagination off')
|
||||||
|
gdb.execute('set print repeats 0')
|
||||||
|
gdb.execute('set print elements unlimited')
|
||||||
|
ret_ptype = gdb.execute('ptype {}'.format(arg), to_string=True)
|
||||||
|
tname = self.extract_typename(ret_ptype)
|
||||||
|
print('{} {} = {{'.format(tname, arg))
|
||||||
|
r = gdb.execute('p {}'.format(arg), to_string=True)
|
||||||
|
r = r.split('\n')
|
||||||
|
for rr in r[1:]:
|
||||||
|
if '=' not in rr:
|
||||||
|
print(rr)
|
||||||
|
continue
|
||||||
|
hs = self.get_count_heading(rr)
|
||||||
|
rr_s = rr.strip().split('=', 1)
|
||||||
|
rr_rval = rr_s[1].strip()
|
||||||
|
print(' ' * hs + '.' + rr_s[0] + '= ' + rr_rval)
|
||||||
|
|
||||||
|
class ListDumpCmd(gdb.Command):
|
||||||
|
"""Prints a linked list"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ListDumpCmd, self).__init__(
|
||||||
|
"list_dump", gdb.COMMAND_USER
|
||||||
|
)
|
||||||
|
|
||||||
|
def _print_list(self, val):
|
||||||
|
"""Walk through the linked list.
|
||||||
|
|
||||||
|
We will simply follow the 'next' pointers until we encounter the HEAD again
|
||||||
|
"""
|
||||||
|
idx = 0
|
||||||
|
head = val
|
||||||
|
kthread_ptr = val
|
||||||
|
result = ""
|
||||||
|
while kthread_ptr != 0 and (idx == 0 or kthread_ptr != head):
|
||||||
|
result += gdb.execute('p *({}){}'.format(str(kthread_ptr.type),kthread_ptr), to_string=True)
|
||||||
|
kthread_ptr = kthread_ptr["next"]
|
||||||
|
idx += 1
|
||||||
|
result = ("Found a Linked List with %d items:" % idx) + "\n"+ result
|
||||||
|
return result
|
||||||
|
|
||||||
|
def complete(self, text, word):
|
||||||
|
# We expect the argument passed to be a symbol so fallback to the
|
||||||
|
# internal tab-completion handler for symbols
|
||||||
|
return gdb.COMPLETE_SYMBOL
|
||||||
|
|
||||||
|
def invoke(self, args, from_tty):
|
||||||
|
# We can pass args here and use Python CLI utilities like argparse
|
||||||
|
# to do argument parsing
|
||||||
|
print("Args Passed: %s" % args)
|
||||||
|
if args:
|
||||||
|
ptr_val = gdb.parse_and_eval(args)
|
||||||
|
else:
|
||||||
|
ptr_val = gdb.parse_and_eval("currentThread")
|
||||||
|
try:
|
||||||
|
ptr_val["next"]
|
||||||
|
except:
|
||||||
|
print("Expected pointer argument with a next field")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(self._print_list(ptr_val))
|
||||||
|
|
||||||
register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True)
|
register_pretty_printer(None, CustomPrettyPrinterLocator(), replace=True)
|
||||||
KthreadListDumpCmd()
|
KthreadListDumpCmd()
|
||||||
PhyMemDescListDumpCmd()
|
PhyMemDescListDumpCmd()
|
||||||
|
PrintStructC99Cmd()
|
||||||
|
ListDumpCmd()
|
||||||
|
@ -109,6 +109,7 @@ static void testAlloc(void)
|
|||||||
void *alloc5 = testAllocNSet(1024);
|
void *alloc5 = testAllocNSet(1024);
|
||||||
void *alloc6 = testAllocNSet(1024);
|
void *alloc6 = testAllocNSet(1024);
|
||||||
void *alloc7 = testAllocNSet(4096);
|
void *alloc7 = testAllocNSet(4096);
|
||||||
|
void *alloc8 = testAllocNSet(8192);
|
||||||
free(alloc1);
|
free(alloc1);
|
||||||
free(alloc2);
|
free(alloc2);
|
||||||
free(alloc3);
|
free(alloc3);
|
||||||
@ -116,6 +117,7 @@ static void testAlloc(void)
|
|||||||
free(alloc5);
|
free(alloc5);
|
||||||
free(alloc6);
|
free(alloc6);
|
||||||
free(alloc7);
|
free(alloc7);
|
||||||
|
free(alloc8);
|
||||||
void *alloc11 = testAllocNSet(1024);
|
void *alloc11 = testAllocNSet(1024);
|
||||||
void *alloc12 = testAllocNSet(1024);
|
void *alloc12 = testAllocNSet(1024);
|
||||||
void *alloc13 = testAllocNSet(1024);
|
void *alloc13 = testAllocNSet(1024);
|
||||||
|
Loading…
Reference in New Issue
Block a user