#include "lowmem.h"
#include <slab.h>
#include <cache_struct.h>
#include <assert.h>
#include <i386.h>
#include <misc.h>
#include <stddef.h>
struct kmalloc_header_struct {
unsigned long size;
};
static struct cache_struct cache_table[LOG_PAGE_SIZE];
void kmalloc_init()
{
unsigned int k;
for (k = 2; k < LOG_PAGE_SIZE; k++)
kmem_cache_init(&cache_table[k], exp2(k));
}
void kmalloc_check_empty()
{
unsigned int k;
for (k = 2; k < LOG_PAGE_SIZE; k++)
kmem_cache_check_empty(&cache_table[k]);
}
void *kmalloc(unsigned long size)
{
unsigned int k;
void *p;
if (size == 0)
return NULL;
k = ulog2(size + sizeof (struct kmalloc_header_struct));
if (k < 2)
k = 2;
if (k < LOG_PAGE_SIZE) {
if (!(p = kmem_cache_alloc(&cache_table[k])))
return NULL;
((struct kmalloc_header_struct *)p)->size = size;
return p + sizeof (struct kmalloc_header_struct);
}
else
return alloc_page_frames(k - LOG_PAGE_SIZE);
}
void kfree(void *ptr, unsigned long size)
{
unsigned int k;
struct kmalloc_header_struct *hdr;
if (!ptr || size == 0)
return;
k = ulog2(size + sizeof (struct kmalloc_header_struct));
if (k < 2)
k = 2;
if (k < LOG_PAGE_SIZE) {
hdr = ptr - sizeof (struct kmalloc_header_struct);
assert(hdr->size == size);
hdr->size = 0;
return kmem_cache_free(&cache_table[k], ptr - sizeof (struct kmalloc_header_struct));
}
else
return free_page_frames(ptr, k - LOG_PAGE_SIZE);
}