mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +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
|
#ifndef _SLAB_H_INCLUDE
|
||||||
#define _SLAB_H_INCLUDE
|
#define _SLAB_H_INCLUDE
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
void* slab_alloc(size_t);
|
void* slab_alloc(size_t);
|
||||||
void slab_free(void*);
|
void slab_free(void*);
|
||||||
|
size_t slab_getentrysize(void*);
|
||||||
void slab_init();
|
void slab_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+27
-7
@@ -1,13 +1,18 @@
|
|||||||
#include <kernel/alloc.h>
|
#include <kernel/alloc.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <kernel/pagealloc.h>
|
||||||
|
|
||||||
void* alloc(size_t size){
|
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){
|
void free(void* addr){
|
||||||
slab_free(addr);
|
if(pageallocator_free(addr))
|
||||||
|
slab_free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void alloc_init(){
|
void alloc_init(){
|
||||||
@@ -15,14 +20,29 @@ void alloc_init(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* realloc(void* addr, size_t size){
|
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;
|
return NULL;
|
||||||
|
|
||||||
memcpy(tmp, addr, size);
|
|
||||||
|
|
||||||
free(addr);
|
size_t slabsize = slab_getentrysize(addr);
|
||||||
|
|
||||||
return tmp;
|
newaddr = alloc(size);
|
||||||
|
|
||||||
|
if(!newaddr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(newaddr, addr, slabsize);
|
||||||
|
|
||||||
|
slab_free(addr);
|
||||||
|
|
||||||
|
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){
|
static void free(void* addr){
|
||||||
|
|
||||||
// align down to page size
|
// align down to page size
|
||||||
|
|||||||
Reference in New Issue
Block a user