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

本文介绍了一个简单的kmalloc内存管理实现方法,包括初始化、分配和释放内存的过程。该方法使用了页面控制块和内存控制块来跟踪内存使用情况。
#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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值