#include "KMalloc.h"
#include "PageAlloc.h"
static int has_initialized = 0;
struct page_control_block
{
int useCount;
unsigned long freeSize;
struct page_control_block *prev;
struct page_control_block *next;
};
struct mem_control_block
{
unsigned long size;
struct mem_control_block *prev;
};
static struct page_control_block *pageList = 0;
static struct mem_control_block **freeList = 0;
/**
* kmalloc初始化
**/
void init_kmalloc()
{
if(has_initialized)
{
return;
}
int i;
freeList = (struct mem_control_block **)GetFreePage();
for(i = 0; i < 1024; i++)
{
freeList[i] = (struct mem_control_block *)0;
}
has_initialized = 1;
}
/**
* 分配内存
**/
void *kmalloc(unsigned long size)
{
// 初始化kmalloc
if(has_initialized == 0)
{
init_kmalloc();
}
// 如果请求的空间超过了一页,则返回0
if(size > 4096 - sizeof(struct page_control_block) - sizeof(struct mem_control_block))
{
return 0;
}
// 计算实际需要的空间大小,并4字节对齐
size = size + sizeof(struct mem_control_block);
size = (size + 3) & (~3);
// 首先看是否有被释放的块
if(freeList[size >> 2]) { //如果有先前被释放的块
struct mem_control_block* memControl = (struct mem_control_block*)freeList[size >> 2];
freeList[size >> 2] = memControl->prev;
memControl->size = size;
memControl->prev = 0;
//
struct page_control_block* pageControl = (struct page_control_block*)((unsigned long)memControl & (~4095));
pageControl->useCount++;
//
return (void*)((unsigned long)memControl + sizeof(struct mem_control_block));
} else { //如果没有先前被释放的块
struct page_control_block* pageControl = (struct page_control_block*)pageList;
while(pageControl)
{
if(pageControl->freeSize >= size)
{
break;
}
pageControl = pageControl->next;
}
//
if(!pageControl) { // 如果没有从pageList中找到合适的页
unsigned long pageAddr = GetFreePage();
pageControl = (struct page_control_block*)pageAddr;
pageControl->useCount = 0;
pageControl->freeSize = 4096 - sizeof(struct page_control_block);
pageControl->prev = 0;
pageControl->next = pageList;
if(pageList) {
pageList->prev = pageControl;
}
pageList = pageControl;
}
//
struct mem_control_block* memControl = (struct mem_control_block*)((unsigned long)pageControl + (4096 - pageControl->freeSize));
memControl->size = size;
memControl->prev = 0;
//
pageControl->useCount++;
pageControl->freeSize = pageControl->freeSize - size;
return (void*)((unsigned long)memControl + sizeof(struct mem_control_block));
}
}
/**
* 释放内存
**/
void kfree(void *start)
{
struct page_control_block* pageControl = (struct page_control_block*)((unsigned long)start & (~4095));
pageControl->useCount--;
if(pageControl->useCount)
{
struct mem_control_block* memControl = (struct mem_control_block*)((unsigned long)start - sizeof(struct mem_control_block));
memControl->prev = freeList[memControl->size >> 2];
freeList[memControl->size >> 2] = memControl;
} else {
if(pageControl->prev)
{
pageControl->prev->next = pageControl->next;
}
if(pageControl->next)
{
pageControl->next->prev = pageControl->prev;
}
if(pageControl == pageList)
{
pageList = pageControl->next;
}
int i;
unsigned long start = (unsigned long)pageControl;
unsigned long end = (unsigned long)pageControl + 4096;
for(i = 0; i < 1024; i++)
{
unsigned long tmp = (unsigned long)freeList[i];
if(tmp > start && tmp < end)
{
freeList[i] = (struct mem_control_block *)0;
}
}
FreePage((unsigned long)pageControl);
}
}
#include "PageAlloc.h"
static int has_initialized = 0;
struct page_control_block
{
int useCount;
unsigned long freeSize;
struct page_control_block *prev;
struct page_control_block *next;
};
struct mem_control_block
{
unsigned long size;
struct mem_control_block *prev;
};
static struct page_control_block *pageList = 0;
static struct mem_control_block **freeList = 0;
/**
* kmalloc初始化
**/
void init_kmalloc()
{
if(has_initialized)
{
return;
}
int i;
freeList = (struct mem_control_block **)GetFreePage();
for(i = 0; i < 1024; i++)
{
freeList[i] = (struct mem_control_block *)0;
}
has_initialized = 1;
}
/**
* 分配内存
**/
void *kmalloc(unsigned long size)
{
// 初始化kmalloc
if(has_initialized == 0)
{
init_kmalloc();
}
// 如果请求的空间超过了一页,则返回0
if(size > 4096 - sizeof(struct page_control_block) - sizeof(struct mem_control_block))
{
return 0;
}
// 计算实际需要的空间大小,并4字节对齐
size = size + sizeof(struct mem_control_block);
size = (size + 3) & (~3);
// 首先看是否有被释放的块
if(freeList[size >> 2]) { //如果有先前被释放的块
struct mem_control_block* memControl = (struct mem_control_block*)freeList[size >> 2];
freeList[size >> 2] = memControl->prev;
memControl->size = size;
memControl->prev = 0;
//
struct page_control_block* pageControl = (struct page_control_block*)((unsigned long)memControl & (~4095));
pageControl->useCount++;
//
return (void*)((unsigned long)memControl + sizeof(struct mem_control_block));
} else { //如果没有先前被释放的块
struct page_control_block* pageControl = (struct page_control_block*)pageList;
while(pageControl)
{
if(pageControl->freeSize >= size)
{
break;
}
pageControl = pageControl->next;
}
//
if(!pageControl) { // 如果没有从pageList中找到合适的页
unsigned long pageAddr = GetFreePage();
pageControl = (struct page_control_block*)pageAddr;
pageControl->useCount = 0;
pageControl->freeSize = 4096 - sizeof(struct page_control_block);
pageControl->prev = 0;
pageControl->next = pageList;
if(pageList) {
pageList->prev = pageControl;
}
pageList = pageControl;
}
//
struct mem_control_block* memControl = (struct mem_control_block*)((unsigned long)pageControl + (4096 - pageControl->freeSize));
memControl->size = size;
memControl->prev = 0;
//
pageControl->useCount++;
pageControl->freeSize = pageControl->freeSize - size;
return (void*)((unsigned long)memControl + sizeof(struct mem_control_block));
}
}
/**
* 释放内存
**/
void kfree(void *start)
{
struct page_control_block* pageControl = (struct page_control_block*)((unsigned long)start & (~4095));
pageControl->useCount--;
if(pageControl->useCount)
{
struct mem_control_block* memControl = (struct mem_control_block*)((unsigned long)start - sizeof(struct mem_control_block));
memControl->prev = freeList[memControl->size >> 2];
freeList[memControl->size >> 2] = memControl;
} else {
if(pageControl->prev)
{
pageControl->prev->next = pageControl->next;
}
if(pageControl->next)
{
pageControl->next->prev = pageControl->prev;
}
if(pageControl == pageList)
{
pageList = pageControl->next;
}
int i;
unsigned long start = (unsigned long)pageControl;
unsigned long end = (unsigned long)pageControl + 4096;
for(i = 0; i < 1024; i++)
{
unsigned long tmp = (unsigned long)freeList[i];
if(tmp > start && tmp < end)
{
freeList[i] = (struct mem_control_block *)0;
}
}
FreePage((unsigned long)pageControl);
}
}