os/libc/stdlib.c

175 lines
4.3 KiB
C
Raw Normal View History

2020-07-26 15:38:29 -05:00
/**
* \file
*/
#include <math.h>
2019-03-17 12:22:00 -05:00
#include <memory.h>
2020-07-22 19:35:23 -05:00
#include <stdlib.h>
#include <string.h>
2019-03-17 12:22:00 -05:00
2020-07-26 15:38:29 -05:00
#define MAX_BLOCKS 512 //!< Maximum number of blocks that can be used
2019-03-11 09:32:55 -05:00
2020-07-26 15:38:29 -05:00
/**
* Represents a contiguos block in the heap
*/
2019-02-09 12:52:45 -06:00
typedef struct {
2020-07-26 15:38:29 -05:00
char* bitmap; //!< Bitmap of avilable four byte groups
size_t bitmap_byt_size; //!< Size of the bitmap in bytes
size_t bitmap_bit_size; //!< Size of the bitmap in bits
size_t avail_data_size; //!< Size of the data block
void* data_block; //!< Data block
2019-02-09 12:52:45 -06:00
} heap_block;
2020-07-26 15:38:29 -05:00
static heap_block entries[MAX_BLOCKS]; //!< List of blocks in the heap
static size_t num_used_entries=0; //!< Number of blocks in the heap
2019-03-11 09:32:55 -05:00
2020-07-26 15:38:29 -05:00
/**
* Get a bit in a bitmap
* \param bmap The bitmap
* \param index The index in the bitmap
* \return the bit
*/
2020-07-23 11:50:23 -05:00
static char get_bmap_bit(char* bmap,size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-02-09 12:52:45 -06:00
char entry=bmap[byte];
return (entry&(1<<bit))>0;
}
2019-03-11 09:32:55 -05:00
2020-07-26 15:38:29 -05:00
/**
* Set a bit in a bitmap
* \param bmap The bitmap
* \param index The index in the bitmap
*/
2020-07-23 11:50:23 -05:00
static void set_bmap_bit(char* bmap,size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-02-09 12:52:45 -06:00
bmap[byte]=bmap[byte]|(1<<bit);
}
2019-03-11 09:32:55 -05:00
2020-07-26 15:38:29 -05:00
/**
* Clear a bit in a bitmap
* \param bmap The bitmap
* \param index The index in the bitmap
*/
2020-07-23 11:50:23 -05:00
static void clear_bmap_bit(char* bmap,size_t index) {
size_t byte=index/8;
size_t bit=index%8;
2019-02-09 12:52:45 -06:00
bmap[byte]=bmap[byte]&(~(1<<bit));
}
2019-03-11 09:32:55 -05:00
2020-07-26 15:38:29 -05:00
/**
* Add a block to the heap
* \param mem_blks The number of pages that this block will use
*/
2020-07-23 11:50:23 -05:00
static void reserve_block(size_t mem_blks) {
size_t bmap_byts=((mem_blks*BLK_SZ)/4)/8;
entries[num_used_entries].bitmap=alloc_memory((size_t)ceilf((double)bmap_byts/BLK_SZ));
2019-02-09 12:52:45 -06:00
entries[num_used_entries].bitmap_byt_size=bmap_byts;
entries[num_used_entries].bitmap_bit_size=bmap_byts*8;
2019-03-11 09:32:55 -05:00
char* bmap=entries[num_used_entries].bitmap;
2020-07-23 11:50:23 -05:00
size_t bmap_byt_sz=entries[num_used_entries].bitmap_byt_size;
for(size_t i=0;i<bmap_byt_sz;i++) {
2019-02-09 12:52:45 -06:00
bmap[i]=0;
}
entries[num_used_entries].avail_data_size=mem_blks*BLK_SZ;
entries[num_used_entries].data_block=alloc_memory(mem_blks);
num_used_entries++;
}
2019-04-22 13:18:05 -05:00
void* malloc(size_t size) {
2020-07-23 11:50:23 -05:00
size_t num_4b_grps=(size_t)ceilf((float)size/4);
2019-02-09 12:52:45 -06:00
num_4b_grps+=3;
int blk_indx=-1;
2020-07-23 11:50:23 -05:00
size_t bmap_index;
2019-02-09 12:52:45 -06:00
heap_block entry;
2020-07-23 11:50:23 -05:00
for (size_t i=0;i<num_used_entries;i++) {
size_t remaining_blks;
2019-02-09 12:52:45 -06:00
entry=entries[i];
if (entry.avail_data_size>=size) {
2019-03-11 09:32:55 -05:00
char* bmap=entry.bitmap;
2020-07-23 11:50:23 -05:00
size_t bmap_byt_sz=entry.bitmap_byt_size;
for(size_t i=0;i<bmap_byt_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(bmap,j);
if (got_0) {
if (bit) {
if (remaining_blks==0) {
bmap_index=old_j;
2019-02-09 12:52:45 -06:00
break;
} else {
2019-07-01 15:30:00 -05:00
i+=j/8;
i--;
break;
2019-02-09 12:52:45 -06:00
}
} else {
2019-07-01 15:30:00 -05:00
remaining_blks--;
2019-02-09 12:52:45 -06:00
}
2019-07-01 15:30:00 -05:00
} else {
if (!bit) {
got_0=1;
old_j=j;
remaining_blks--;
2019-02-09 12:52:45 -06:00
}
}
2019-07-01 15:30:00 -05:00
if (remaining_blks==0) {
bmap_index=old_j;
break;
}
2019-02-09 12:52:45 -06:00
}
if (remaining_blks==0) {
break;
}
}
}
if (remaining_blks==0) {
blk_indx=i;
break;
}
}
if (blk_indx==-1) {
2020-07-23 11:50:23 -05:00
// reserve_block((size_t)ceilf((double)size/BLK_SZ));
2020-07-09 11:28:57 -05:00
reserve_block(1024);
2019-02-09 12:52:45 -06:00
return malloc(size);
}
2020-07-23 11:50:23 -05:00
for (size_t i=0;i<num_4b_grps;i++) {
2019-02-09 12:52:45 -06:00
set_bmap_bit(entry.bitmap,bmap_index+i);
}
2020-07-23 11:50:23 -05:00
size_t data_offset=(bmap_index*8)+12;
size_t* info=(void*)(((char*)entry.data_block)+data_offset-12);
2019-02-09 12:52:45 -06:00
info[0]=num_4b_grps;
info[1]=bmap_index;
info[2]=blk_indx;
entry.avail_data_size-=size+12;
return (void*)(((char*)entry.data_block)+data_offset);
2019-02-09 12:52:45 -06:00
}
void* realloc(void *mem, size_t new_sz) {
void* ptr=malloc(new_sz);
if (mem==NULL) {
return ptr;
}
2020-07-23 11:50:23 -05:00
size_t num_4b_grps=*((size_t*)((char*)mem-12));
2019-02-09 12:52:45 -06:00
memcpy(ptr,mem,num_4b_grps*4);
free(mem);
mem=ptr;
return ptr;
}
void free(void* mem) {
2020-07-23 11:50:23 -05:00
size_t* info=(size_t*)((char*)mem-12);
size_t num_4b_grps=info[0];
size_t bmap_index=info[1];
size_t blk_indx=info[2];
2019-02-09 12:52:45 -06:00
heap_block entry=entries[blk_indx];
2020-07-23 11:50:23 -05:00
for (size_t i=0;i<num_4b_grps;i++) {
2019-02-09 12:52:45 -06:00
clear_bmap_bit(entry.bitmap,bmap_index+i);
}
entry.avail_data_size+=(num_4b_grps*4)+12;
}