为MyOS实现了一个内存分配函数,并修正了GUI分配窗口的一个Bug

来源:互联网 发布:时间轴数据新闻作品 编辑:程序博客网 时间:2024/05/29 00:31
#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);
    }
}
原创粉丝点击