mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
page allocator for alloc()
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
#ifndef _PAGEALLOC_H_INCLUDE
|
||||
#define _PAGEALLOC_H_INCLUDE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void* pageallocator_alloc(size_t size);
|
||||
bool pageallocator_free(void* addr);
|
||||
void* pageallocator_realloc(void* addr, size_t size, bool* nonexistant);
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifndef _SLAB_H_INCLUDE
|
||||
#define _SLAB_H_INCLUDE
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void* slab_alloc(size_t);
|
||||
void slab_free(void*);
|
||||
|
||||
size_t slab_getentrysize(void*);
|
||||
void slab_init();
|
||||
|
||||
#endif
|
||||
|
||||
+27
-7
@@ -1,13 +1,18 @@
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/slab.h>
|
||||
#include <string.h>
|
||||
#include <kernel/pagealloc.h>
|
||||
|
||||
void* alloc(size_t size){
|
||||
return slab_alloc(size);
|
||||
if(size > 256) // slab implementation max size
|
||||
return pageallocator_alloc(size);
|
||||
else
|
||||
return slab_alloc(size);
|
||||
}
|
||||
|
||||
void free(void* addr){
|
||||
slab_free(addr);
|
||||
if(pageallocator_free(addr))
|
||||
slab_free(addr);
|
||||
}
|
||||
|
||||
void alloc_init(){
|
||||
@@ -15,14 +20,29 @@ void alloc_init(){
|
||||
}
|
||||
|
||||
void* realloc(void* addr, size_t size){
|
||||
void* tmp = alloc(size);
|
||||
if(!tmp)
|
||||
|
||||
bool nonexistant;
|
||||
|
||||
void* newaddr = pageallocator_realloc(addr, size, &nonexistant);
|
||||
|
||||
if(newaddr)
|
||||
return newaddr;
|
||||
|
||||
if(nonexistant == 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
size_t slabsize = slab_getentrysize(addr);
|
||||
|
||||
newaddr = alloc(size);
|
||||
|
||||
if(!newaddr)
|
||||
return NULL;
|
||||
|
||||
memcpy(tmp, addr, size);
|
||||
memcpy(newaddr, addr, slabsize);
|
||||
|
||||
free(addr);
|
||||
slab_free(addr);
|
||||
|
||||
return tmp;
|
||||
return newaddr;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
#include <kernel/pagealloc.h>
|
||||
#include <kernel/slab.h>
|
||||
#include <arch/mmu.h>
|
||||
#include <arch/spinlock.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct _page_allocation{
|
||||
struct _page_allocation* next;
|
||||
void* start;
|
||||
size_t size;
|
||||
} page_allocation;
|
||||
|
||||
static int lock;
|
||||
static page_allocation* list;
|
||||
|
||||
void* pageallocator_alloc(size_t size){
|
||||
|
||||
page_allocation* alloc = slab_alloc(sizeof(page_allocation));
|
||||
|
||||
if(!alloc)
|
||||
return NULL;
|
||||
|
||||
size_t pagec = size / PAGE_SIZE + (size % PAGE_SIZE ? 1 : 0);
|
||||
|
||||
// use vmm?
|
||||
|
||||
alloc->start = pmm_hhdmalloc(pagec);
|
||||
|
||||
if(!alloc->start){
|
||||
slab_free(alloc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alloc->size = size;
|
||||
|
||||
spinlock_acquire(&lock);
|
||||
|
||||
if(list)
|
||||
alloc->next = list;
|
||||
|
||||
list = alloc;
|
||||
|
||||
spinlock_release(&lock);
|
||||
|
||||
return alloc->start;
|
||||
|
||||
}
|
||||
|
||||
bool pageallocator_free(void* addr){
|
||||
spinlock_acquire(&lock);
|
||||
|
||||
page_allocation* it = list;
|
||||
page_allocation* prev = NULL;
|
||||
|
||||
while(it){
|
||||
void* end = it->start + it->size;
|
||||
if(it->start <= addr && end > addr)
|
||||
break;
|
||||
prev = it;
|
||||
it = it->next;
|
||||
}
|
||||
|
||||
if(!it){
|
||||
spinlock_release(&lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!prev)
|
||||
list = it->next;
|
||||
else
|
||||
prev->next = it->next;
|
||||
|
||||
spinlock_release(&lock);
|
||||
|
||||
|
||||
size_t pagec = it->size / PAGE_SIZE + (it->size % PAGE_SIZE ? 1 : 0);
|
||||
|
||||
// use vmm?
|
||||
pmm_hhdmfree(it->start, pagec);
|
||||
slab_free(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* pageallocator_realloc(void* addr, size_t size, bool* nonexistant){
|
||||
|
||||
spinlock_acquire(&lock);
|
||||
|
||||
page_allocation* it = list;
|
||||
page_allocation* prev = NULL;
|
||||
|
||||
while(it){
|
||||
void* end = it->start + it->size;
|
||||
if(it->start <= addr && end > addr)
|
||||
break;
|
||||
prev = it;
|
||||
it = it->next;
|
||||
}
|
||||
|
||||
if(!it){
|
||||
*nonexistant = 1;
|
||||
spinlock_release(&lock);
|
||||
return NULL;
|
||||
}
|
||||
size_t oldpagec = it->size / PAGE_SIZE + (it->size % PAGE_SIZE ? 1 : 0);
|
||||
size_t newpagec = size / PAGE_SIZE + (size % PAGE_SIZE ? 1 : 0);
|
||||
|
||||
if(oldpagec == newpagec){
|
||||
spinlock_release(&lock);
|
||||
return it->start;
|
||||
}
|
||||
|
||||
if(!prev)
|
||||
list = it->next;
|
||||
else
|
||||
prev->next = it->next;
|
||||
|
||||
spinlock_release(&lock);
|
||||
|
||||
void* new = pageallocator_alloc(size);
|
||||
|
||||
if(!new){
|
||||
*nonexistant = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(new, it->start, it->size);
|
||||
|
||||
// use vmm?
|
||||
pmm_hhdmfree(it->start, oldpagec);
|
||||
slab_free(it);
|
||||
|
||||
return new;
|
||||
|
||||
}
|
||||
@@ -50,6 +50,11 @@ static inline slabdesc* getslabdesc(size_t size){
|
||||
|
||||
}
|
||||
|
||||
size_t slab_getentrysize(void* addr){
|
||||
slab_t *slab = (size_t)addr & ~(0xFFF);
|
||||
return slab->entrysize;
|
||||
}
|
||||
|
||||
static void free(void* addr){
|
||||
|
||||
// align down to page size
|
||||
|
||||
Reference in New Issue
Block a user