OSMemCreate自我解析

OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
OS_MEM *pmem;
INT8U *pblk;
void **plink;
INT32U i;
if (nblks < 2) {       //内存的分区数必须大于2 
*err = OS_MEM_INVALID_BLKS;
return ((OS_MEM *)0);
}
if (blksize < sizeof(void *)) {    //每个内存块至少为一个指针的大小
*err = OS_MEM_INVALID_SIZE;
return ((OS_MEM *)0);
}
OS_ENTER_CRITICAL();
pmem = OSMemFreeList;  //空闲内存控制块中取获取一个内存控制块

if (OSMemFreeList != (OS_MEM *)0) {   //如果成功获取则原列表指向下一个内存控制块
OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
}
OS_EXIT_CRITICAL();
if (pmem == (OS_MEM *)0) {   //内存控制块不能为空,即有内存控制块可用
*err = OS_MEM_INVALID_PART;
return ((OS_MEM *)0);
}
plink = (void **)addr;   //addr是指向内存分区起始地址的一维指针,plink是一个二维指针,
                         //为保证赋值,将addr也强转成二维指针。操作后plink内存放的是addr的值
                         //和addr指向相同的地址
pblk = (INT8U *)addr + blksize;  //取得下一个内存分区块的起始地址(指针加整数:如INT8U类型占一 
                                 //条内存地址,而INT32U类型占4条内存地址,所以指针加整数的值 
                                 //为-------指针地址+(INT8U占内存地址数)×blksize 
for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk;    //*plink是一个void类型指针,为保证赋值,将pblk强转成void类型指针,
                          //操作后*plink指向下一个分区块的起始地址,即addr指向的地址的内存块
                          //内存放下一个内存分区块的起始地址
plink = (void **)pblk;   //此时将plink改为指向下一个内存分区块的起始地址,以便对下一个内存分区
                         //块内的值进行赋值操作
pblk = pblk + blksize;  //取得下一个内存分区块的起始地址
}
*plink = (void *)0;   //最后一个指向空值
OS_ENTER_CRITICAL();
pmem->OSMemAddr = addr;   //记录这个内存分区的起始地址
pmem->OSMemFreeList = addr;
pmem->OSMemNFree = nblks;   //记录这个内存分区的分区数
pmem->OSMemNBlks = nblks;
pmem->OSMemBlkSize = blksize;  //记录这个内存分区一个分区的字节大小
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (pmem); 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值