Tiniux 3.0 / Memory.c / OSMemMalloc 和 OSMemCalloc
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/83998064if(gpOSMemEnd==OS_NULL){OSMemInit();if(gpOSMemEnd==OS_NULL){return pResult;}}
// 不需要分配则返回OS_NULLif (size == 0) {return pResult;}
// 对齐要分配的内存块 size = OSMEM_ALIGN_SIZE(size);
// 分配的内存块至少要大于OSMIN_SIZE_ALIGNEDif(size < OSMIN_SIZE_ALIGNED) {// every data block must be at least OSMIN_SIZE_ALIGNED long size = OSMIN_SIZE_ALIGNED;}
// 分配的内存块大小超过堆最大值,则返回OS_NULLif (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_ALIGNEDif ((!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_ALIGNEDptOSMemTemp2 = (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!)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
