summaryrefslogtreecommitdiff
path: root/kernel/kmalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kmalloc.c')
-rw-r--r--kernel/kmalloc.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c
index 061d68e..38db6fc 100644
--- a/kernel/kmalloc.c
+++ b/kernel/kmalloc.c
@@ -3,7 +3,7 @@
#include "spinlock.h"
#include "log.h"
-#define BLOCKS KMALLOC_MEM_SIZE/KMALLOC_BLOCK_SIZE
+#define BLOCKS (KMALLOC_MEM_SIZE/KMALLOC_BLOCK_SIZE)
// this is in .bss so we can assume it was zeroed!
static uint8_t data[KMALLOC_MEM_SIZE] __attribute__((aligned (4096))); // bytes
@@ -11,16 +11,12 @@ static uint8_t map[BLOCKS];
//
static uint32_t data_addr;
-static uint32_t next;
-static uint32_t first;
-static uint8_t init=0;
-
static uint32_t next_free(uint32_t start)
{
for(int i=start;i<BLOCKS;i++)
{
if(!map[i])return i;
- return next_free(i+map[i]);
+ i+=map[i]-1;
}
return BLOCKS; // out of mem
}
@@ -44,7 +40,7 @@ static uint32_t free_cont(uint32_t blocks)
{
pos=next_free(pos);
// klog("next_free:%d",pos);
- if(pos==BLOCKS)return BLOCKS; // out of mem
+ if(pos+blocks>=BLOCKS)return BLOCKS; // out of mem
uint32_t end=next_used(pos,blocks);
// klog("next_used:%d",end);
if(end-pos>=blocks)return pos;
@@ -83,28 +79,27 @@ static void mark_free(uint32_t start,uint32_t blocks)
// will be initialized on first call to kballoc() //
static void kmallocinit()
{
- next=&(data[0]);
- data_addr=next;
- first=next;
- if(next%4096)kpanic("kmalloc data not aligned properly.");
+ data_addr=data;
+ if(data_addr%4096)kpanic("kmalloc data not aligned properly.");
- klog("In-Kernel Block Memory Allocation Initialized at: 0x%08X (free: %d x 4096KB BLOCKS)",next,BLOCKS);
- init=1;
+ klog("In-Kernel Block Memory Allocation Initialized at: 0x%08X (free: %d x 4096KB BLOCKS)",data_addr,BLOCKS);
}
// kernel block memory allocation //
uint32_t kballoc(uint32_t size)
{
+ static bool init=false;
if(size>255)kpanic("max supported size 255 blocks");
spinlock_spin(SPINLOCK_ALLOC);
- if(!init)kmallocinit();
+ if(!init){kmallocinit(); init=true;}
uint32_t blk=free_cont(size);
if(blk==BLOCKS)kpanic("out of mem");
mark_used(blk,size);
spinlock_release(SPINLOCK_ALLOC);
+ klog("allocated %d blocks at 0x%08X",size,data_addr+blk*4096);
return data_addr+blk*4096;
}
@@ -112,7 +107,7 @@ void kbfree(uint32_t pos)
{
uint32_t blk=(pos-data_addr)/4096;
spinlock_spin(SPINLOCK_ALLOC);
- klog("freeing %d blocks ad 0x%08X",map[blk],pos);
+ klog("freeing %d blocks at 0x%08X",map[blk],pos);
mark_free(blk,map[blk]);
spinlock_release(SPINLOCK_ALLOC);
}
@@ -121,14 +116,28 @@ void kmalloc_sysfs(ringbuffer *r,void (*f)(ringbuffer *r,char *fmt, ...))
{
uint32_t free=0;
uint32_t used=0;
+
+ char cmap[BLOCKS];
+ cmap[200]=0;
+
for(int i=0;i<BLOCKS;i++)
{
- if(map[i]) used++;
- else free++;
+ if(map[i])
+ {
+ cmap[i]='X';
+ used++;
+ }
+ else
+ {
+ cmap[i]='_';
+ free++;
+ }
}
f(r,"kernel blocks allocation/deallocation");
f(r,"total 4096kb blocks: %d (%d bytes)",BLOCKS,BLOCKS*4096);
f(r,"used 4096kb blocks: %d (%d bytes)",used,used*4096);
f(r,"free 4096kb blocks: %d (%d bytes)",free,free*4096);
+// f(r,"%s",cmap); // TODO: watch out for buffer overflow in f
+
}