page allocator for alloc()

This commit is contained in:
Matheus
2022-08-19 22:11:06 -03:00
parent af3e62d37c
commit f04d4b5a31
5 changed files with 181 additions and 8 deletions
+11
View File
@@ -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
+2 -1
View File
@@ -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
View File
@@ -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;
}
+136
View File
@@ -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;
}
+5
View File
@@ -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