os/kernel/kmalloc.c

109 lines
2.3 KiB
C
Raw Normal View History

2020-07-25 16:54:37 -05:00
/**
* \file
*/
2020-07-22 19:35:23 -05:00
#include "cpu/arch_consts.h"
2019-03-23 07:30:00 -05:00
#include <math.h>
2020-07-22 19:35:23 -05:00
#include <stdlib.h>
#include <string.h>
2019-03-23 07:30:00 -05:00
2020-07-25 16:54:37 -05:00
#define KMALLOC_BMAP_SZ (((KMALLOC_SZ*1024)/4)/8) //!< The size of the kmalloc bitmap
2019-03-23 07:30:00 -05:00
2020-07-25 16:54:37 -05:00
static char bitmap[KMALLOC_BMAP_SZ]; //!< Bitmap of used areas of the heap
static void* data=(void*)KMALLOC_START; //!< Start of the kmalloc heap
2019-03-23 07:30:00 -05:00
2020-07-25 16:54:37 -05:00
/**
* Get a bit in the heap bitmap
* \param index The bit to get
* \return the bit
*/
2020-07-23 11:50:23 -05:00
static char get_bmap_bit(size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-03-23 07:30:00 -05:00
char entry=bitmap[byte];
return (entry&(1<<bit))>0;
}
2020-07-25 16:54:37 -05:00
/**
* Set a bit in the heap bitmap
* \param index The bit to set
*/
2020-07-23 11:50:23 -05:00
static void set_bmap_bit(size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-03-23 07:30:00 -05:00
bitmap[byte]=bitmap[byte]|(1<<bit);
}
2020-07-25 16:54:37 -05:00
/**
* Clear a bit in the heap bitmap
* \param index The bit to clear
*/
2020-07-23 11:50:23 -05:00
static void clear_bmap_bit(size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-03-23 07:30:00 -05:00
bitmap[byte]=bitmap[byte]&(~(1<<bit));
}
2020-07-23 11:50:23 -05:00
void* kmalloc(size_t size) {
size_t num_4b_grps=(size_t)ceilf((float)size/4);
2019-03-23 07:30:00 -05:00
num_4b_grps+=2;
2020-07-23 11:50:23 -05:00
size_t bmap_index;
size_t remaining_blks;
for(size_t i=0;i<KMALLOC_BMAP_SZ;i++) {
2019-07-01 15:30:00 -05:00
char got_0=0;
remaining_blks=num_4b_grps;
2020-07-23 11:50:23 -05:00
size_t old_j;
for (size_t j=i*8;;j++) {
2019-07-01 15:30:00 -05:00
char bit=get_bmap_bit(j);
if (got_0) {
if (bit) {
if (remaining_blks==0) {
bmap_index=old_j;
2019-03-23 07:30:00 -05:00
break;
} else {
2019-07-01 15:30:00 -05:00
i+=j/8;
i--;
break;
2019-03-23 07:30:00 -05:00
}
} else {
2019-07-01 15:30:00 -05:00
remaining_blks--;
2019-03-23 07:30:00 -05:00
}
2019-07-01 15:30:00 -05:00
} else {
if (!bit) {
got_0=1;
old_j=j;
remaining_blks--;
2019-03-23 07:30:00 -05:00
}
}
2019-07-01 15:30:00 -05:00
if (remaining_blks==0) {
bmap_index=old_j;
break;
}
2019-03-23 07:30:00 -05:00
}
if (remaining_blks==0) {
break;
}
}
if (remaining_blks!=0) {
return NULL;
}
2020-07-23 11:50:23 -05:00
for (size_t i=0;i<num_4b_grps;i++) {
2019-03-23 07:30:00 -05:00
set_bmap_bit(bmap_index+i);
}
2020-07-23 11:50:23 -05:00
size_t data_offset=(bmap_index*8)+8;
size_t* info=(void*)(((char*)data)+data_offset-8);
2019-03-23 07:30:00 -05:00
info[0]=num_4b_grps;
info[1]=bmap_index;
return (void*)(((char*)data)+data_offset);
2019-03-23 07:30:00 -05:00
}
void kfree(void* mem) {
2020-07-23 11:50:23 -05:00
size_t* info=(size_t*)((size_t)mem-8);
size_t num_4b_grps=info[0];
size_t bmap_index=info[1];
for (size_t i=0;i<num_4b_grps;i++) {
2019-03-23 07:30:00 -05:00
clear_bmap_bit(bmap_index+i);
}
}