Tiniux 3.0 / Memory.c / OSMemMalloc 和 OSMemCalloc

---------------------------------------------
-- 时间:2018-11-13
-- 创建人:Ruo_Xiao
-- 邮箱:xclsoftware@163.com
-- 若大神不吝抛砖,小菜感激不尽!
---------------------------------------------

一、OSMemMalloc 

void* OSMemMalloc(uOSMemSize_t size)
{
//	变量初始化
	//返回最终的已分配的内存块的首地址(不包括tOSMem_t)
    uOS8_t * pResult = OS_NULL;
	//gpOSMemBegin(堆)的迭代器
    uOSMemSize_t ptr = 0U;
	//分配完内存块之后剩余的空闲块的在堆中的位置,也是迭代器
    uOSMemSize_t ptr2 = 0U;
    //开始时是较大空闲块的首地址,由于堆分配是从低地址向高地址分配,分配完成之后,
    //该地址变成了要分配的内存块的首地址,但是包含tOSMem_t,去掉tOSMem_t之后就是pResult。
	tOSMem_t *ptOSMemTemp = OS_NULL;
	//分配完内存块剩余的空闲块的首地址
	tOSMem_t *ptOSMemTemp2 = OS_NULL;
//	初始化堆,详见:https://blog.csdn.net/itworld123/article/details/83998064
    if(gpOSMemEnd==OS_NULL)
    {
        OSMemInit();
        if(gpOSMemEnd==OS_NULL)
        {
            return pResult;
        }
    }
//	不需要分配则返回OS_NULL
    if (size == 0) 
    {
        return pResult;
    }
//  对齐要分配的内存块 
    size = OSMEM_ALIGN_SIZE(size);
//	分配的内存块至少要大于OSMIN_SIZE_ALIGNED
    if(size < OSMIN_SIZE_ALIGNED) 
    {
        // every data block must be at least OSMIN_SIZE_ALIGNED long 
        size = OSMIN_SIZE_ALIGNED;
    }
//	分配的内存块大小超过堆最大值,则返回OS_NULL
    if (size > OSMEM_SIZE_ALIGNED) 
    {
        return pResult;
    }

    // protect the heap from concurrent access 
    OSIntLock();
    
    //	2018-11-10
    //	(uOSMemSize_t)((uOS8_t *)gpOSMemLFree - gpOSMemBegin)	确定闲置tOSMem_t首地址相对Begin的位置
    //	OSMEM_SIZE_ALIGNED - size	搜索的范围不能超过待分配内存块的最高地址处
    //	ptr = ((tOSMem_t *)(void *)&gpOSMemBegin[ptr])->NextMem	确定下一个tOSMem_t的位置    
    for (ptr = (uOSMemSize_t)((uOS8_t *)gpOSMemLFree - gpOSMemBegin); ptr < OSMEM_SIZE_ALIGNED - size;
        ptr = ((tOSMem_t *)(void *)&gpOSMemBegin[ptr])->NextMem) 
    {
        ptOSMemTemp = (tOSMem_t *)(void *)&gpOSMemBegin[ptr];

		//1、ptOSMemTemp->Used	该内存块不能被用
		//2、ptOSMemTemp->NextMem - (ptr + SIZEOF_OSMEM_ALIGNED)) >= size	
		//	计算该free指定的空闲块的大小,其中不包括tOSMem_t,故减掉 SIZEOF_OSMEM_ALIGNED
        if ((!ptOSMemTemp->Used) && (ptOSMemTemp->NextMem - (ptr + SIZEOF_OSMEM_ALIGNED)) >= size) 
        { 
        
			//	分配内存的过程就是插入节点(tOSMem_t)的过程。
			//	ptOSMemTemp 				当前节点的首地址(tOSMem_t)
			//	ptOSMemTemp->NextMem		下一个节点的首地址(tOSMem_t)
			//	ptOSMemTemp->NextMem - (ptr + SIZEOF_OSMEM_ALIGNED) 当前节点对应的内存块到下一个内存块对应的tOSMem_t首地址之间的大小
			//	(size + SIZEOF_OSMEM_ALIGNED + OSMIN_SIZE_ALIGNED)	申请内存完内存之后,在申请的内存后面插入新的tOSMem_t,
			//				tOSMem_t和下一个节点之间至少要有一个OSMIN_SIZE_ALIGNED大小的内存小块,否则两个tOSMem_t就连在
			//				了一起。
			//	如果满足上述要求,就插入一个节点,否则直接将该内存块设置为要申请的内存
            if (ptOSMemTemp->NextMem - (ptr + SIZEOF_OSMEM_ALIGNED) >= (size + SIZEOF_OSMEM_ALIGNED + OSMIN_SIZE_ALIGNED)) 
            {                
                ptr2 = ptr + SIZEOF_OSMEM_ALIGNED + size;
                // 创建 ptOSMemTemp2 信息块,该信息块对应的内存块大小至少为 OSMIN_SIZE_ALIGNED
                ptOSMemTemp2 = (tOSMem_t *)(void *)&gpOSMemBegin[ptr2];
                ptOSMemTemp2->Used = 0;
                ptOSMemTemp2->NextMem = ptOSMemTemp->NextMem;
                ptOSMemTemp2->PrevMem = ptr;

                ptOSMemTemp->NextMem = ptr2;
                ptOSMemTemp->Used = 1;

                if (ptOSMemTemp2->NextMem != OSMEM_SIZE_ALIGNED) 
                {
                    ((tOSMem_t *)(void *)&gpOSMemBegin[ptOSMemTemp2->NextMem])->PrevMem = ptr2;
                }
            } 
            else 
            {
                ptOSMemTemp->Used = 1;
            }

			//循环第一次,此时ptOSMemTemp=gpOSMemLFree。
            if (ptOSMemTemp == gpOSMemLFree) 
            {
				//若gpOSMemLFree完成了内存分配,即:Used为1,则更新Free指针。
                while (gpOSMemLFree->Used && gpOSMemLFree != gpOSMemEnd) 
                {
                    gpOSMemLFree = (tOSMem_t *)(void *)&gpOSMemBegin[gpOSMemLFree->NextMem];
                }
            }
			//	返回tOSMem_t对应的的内存块的地址
            pResult = (uOS8_t *)ptOSMemTemp + SIZEOF_OSMEM_ALIGNED;
            break;
        }
    }

    OSIntUnlock();

    return pResult;
}

二、OSMemCalloc 

//Calloc和 Malloc的关系是,前者调用后者并且若申请内存块成功则初始化buffer。
//详见:https://blog.csdn.net/itworld123/article/details/79187109
void* OSMemCalloc(uOSMemSize_t count, uOSMemSize_t size)
{
    void *pMem = OS_NULL;

    // allocate 'count' objects of size 'size' 
    pMem = OSMemMalloc(count * size);
    if (pMem) 
    {
        // zero the memory 
        memset(pMem, 0, count * size);
    }
    return pMem;
}

注:建议将代码复制下来,用 VS Code 或者 Notepad++ 审阅效果更加。

 

 

(SAW:Game Over!)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值