Tiniux 3.0 / Memory.c / OSMemInit
---------------------------------------------
-- 时间:2018-11-04
-- 创建人:Ruo_Xiao
-- 邮箱:xclsoftware@163.com
---------------------------------------------
一、前言
1、本博文是我自己的理解,在没有把握的地方我会特别注明。本人菜鸟一枚,真诚地期待大神地指教!
2、Tiniux 3.0下载地址。
3、建议使用Source Inlight看源码,效率更高!
4、为了避免篇幅过长,博文源码中使用的一些数据类型就不多解释了,本文只针对终点区域做详解。
5、根据Memory.h头文件可知,函数一共5个,如下:
uOSBase_t OSMemInit(void);
void *OSMemMalloc(uOSMemSize_t size);
void *OSMemCalloc(uOSMemSize_t count, uOSMemSize_t size);void *OSMemTrim(void *pMem, uOSMemSize_t size);
void OSMemFree(void *pMem);
二、OSMemInit
1、源码
/*****************************************************************************
Function : OSMemInit
Description : Zero the heap and initialize start, end and lowest-free pointer.
Input : None
Output : None
Return : None
*****************************************************************************/
uOSBase_t OSMemInit(void)
{tOSMem_t *ptOSMemTemp = OS_NULL;// align the heap gpOSMemBegin = (uOS8_t *)OSMEM_ALIGN_ADDR(OSRAM_HEAP_POINTER);/* Initialize the stack tiniux used. */memset(gpOSMemBegin, 0U, OSMEM_SIZE_ALIGNED);// initialize the start of the heap ptOSMemTemp = (tOSMem_t *)(void *)gpOSMemBegin;ptOSMemTemp->NextMem = OSMEM_SIZE_ALIGNED;ptOSMemTemp->PrevMem = 0;ptOSMemTemp->Used = 0;// initialize the end of the heap gpOSMemEnd = (tOSMem_t *)(void *)&gpOSMemBegin[OSMEM_SIZE_ALIGNED];gpOSMemEnd->Used = 1;gpOSMemEnd->NextMem = OSMEM_SIZE_ALIGNED;gpOSMemEnd->PrevMem = OSMEM_SIZE_ALIGNED;// initialize the lowest-free pointer to the start of the heap gpOSMemLFree = (tOSMem_t *)(void *)gpOSMemBegin;return 0U;
}
2、该函数的目的:
(1)将申请的堆初始化为0;
(2)设置指向堆开始位置的tOSMem_t结构体;
(3)设置指向堆结束位置和指向最低位置的已经释放内存的首地址的tOSMem_t结构体。
3、系统内存分布
gpOSMemEnd - gpOSMemBegin = OSMEM_SIZE_ALIGNED
4、tOSMem_t
typedef struct _tOSMem
{uOSMemSize_t NextMem; uOSMemSize_t PrevMem; uOS8_t Used;
}tOSMem_t;
(1)作用:用于记录堆中已分配的和未分配的内存块在系统内存中的位置(首地址)。
(2)NextMem:堆中,下一个tOSMem_t的首地址。
(3)PrevMem:堆中,上一个tOSMem_t的首地址。
(4)Used:指明其后面的内存块是否被分配,0则为分配,非0则已分配。
(5)注意:tOSMem_t中的元素指明的地址是堆中的地址,gpOSMemBegin、gpOSMemEnd 和 gpOSMemLFree首地址都是系统内存中的地址。
5、在系统内存中申请堆
gpOSMemBegin = (uOS8_t *)OSMEM_ALIGN_ADDR(OSRAM_HEAP_POINTER);
(1)OSMEM_ALIGN_ADDR,地址对齐操作。
(2)OSRAM_HEAP_POINTER,堆数组的首地址。
#define OSMEM_SIZE_ALIGNED OSMEM_ALIGN_SIZE(512)
uOS8_t OSRamHeap[OSMEM_SIZE_ALIGNED + (2U*SIZEOF_OSMEM_ALIGNED) + OSMEM_ALIGNMENT];
#define OSRAM_HEAP_POINTER OSRamHeap
A、上述代码的作用是申请512个字节的堆,但是为了在堆中包含两个tOSMem_t(gpOSMemEnd 和 gpOSMemLFree)同时为了数据对齐,则加上了(2U*SIZEOF_OSMEM_ALIGNED) + OSMEM_ALIGNMENT。
B、特别声明:该数组类型为unsigned char,故1个字节即为1个元素,两个tOSMem_t首地址之间的差值就是二者在gpOSMemBegin数组中位置之间的差值。
6、对于刚刚分配好的堆,实际上就2个内存块,一个是ptOSMemTemp信息块和其对应的内存块,另一个是gpOSMemEnd信息块,如下图所示:
1、由于就两个内存块,故:ptOSMemTemp -> NextMem = OSMEM_SIZE_ALIGNED。
由于ptOSMemTemp之前没有节点,故:ptOSMemTemp -> PrevMem = 0,
同时由于该内存块没有分配,故:ptOSMemTemp -> Used = 0。
2、由于gpOSMemEnd的作用是作为堆的尾端,故: gpOSMemEnd -> Used = 1。
同时为了不让其参加运算,孤立它,故:
gpOSMemEnd -> NextMem = OSMEM_SIZE_ALIGNED;
gpOSMemEnd -> PrevMem = OSMEM_SIZE_ALIGNED;
三、拓展
解决了delete []ptr,在delete不知道该ptr数组大小的时候就准确地释放了内存的问题。原因就是在每一个已分配的内存块的前面都添加了相应的信息块,用于存放该存储块首尾在系统内存中的位置,如Tiniux中的tOSMem_t。
(SAW:Game Over!)
Tiniux 3.0 / Memory.c / OSMemInit相关推荐
- Tiniux 3.0 / Memory.c / OSMemMalloc 和 OSMemCalloc
--------------------------------------------- -- 时间:2018-11-13 -- 创建人:Ruo_Xiao -- 邮箱:xclsoftware@163 ...
- Tiniux 3.0 / Memory.c / OSMemFree
--------------------------------------------- -- 时间:2018-11-14 -- 创建人:Ruo_Xiao -- 邮箱:xclsoftware@163 ...
- SK hynix announces 96GB DDR5 CXL 2.0 memory expansion solution【搬运外媒VedioCardz报道(手工翻译)】
SK hynix announces 96GB DDR5 CXL 2.0 memory expansion solution (SK海力士发布最新CXL2.0标准的DDR5 96GB内存扩展方案) S ...
- android studio dump java heap_Android Studio 3.0 Memory Profiler使用
Memory Profiler是Android Profiler中的一个组件,Android Profiler是Android Studio3.0用来替换之前Android Monitor的观察工具, ...
- Android 10.0系统启动之init进程-[Android取经之路]
摘要:init进程是linux系统中用户空间的第一个进程,进程号为1.当bootloader启动后,启动kernel,kernel启动完后,在用户空间启动init进程,再通过init进程,来读取ini ...
- redis info memory
参考:http://redis.readthedocs.org/en/latest/server/info.html INFO [section] 以一种易于解释(parse)且易于阅读的格式,返回关 ...
- redis-4.0.10集群安装(3台机器,6个node),以及在Spring项目中的集成,redis操作工具类
1 Redis安装 redis高可用的三种常见的集群方式:redis sentinel .redis cluster(多主机+分布式).redis sharding.接下来主要介绍redis sent ...
- Persistent Memory编程简介
Persistent Memory编程简介 编程 libpmem 持久化函数 libpmemobj 跟对象 root object 例程 事务支持 type safety 线程安全 管理工具 ipmc ...
- GCC9.2/Python3.8/Libvirt6.0/QEMU4.2 编译/配置/安装
文章目录 安装CentOS系统 安装GCC 4.8 安装wget/bzip2 编译安装GCC 9.2 卸载GCC4.8版本 编译安装Python3 获取configure时的设定参数 安装Libvir ...
最新文章
- IIS监控--自动重启脚本工具
- 和smi_nvidia-smi 报错:无法与 nvidia driver 通信
- angular js一factory,service,provider创建服务
- AI基础:正则表达式
- Apache——启动错误:[Cannot load modules/mod_actions.so into server]解决方案
- python 报错traceback-python-traceback捕获并打印异常
- [ZJOI2012]灾难(建图)
- 【RobotStudio学习笔记】(七)工件坐标
- Linux/Ubuntu下解压命令
- 知网caj文件怎么转换成Word文档?
- 【原创】关于改变电脑默认安装地址后桌面快捷键显示“指定路径不存在”错误的解决方法之一
- 概率练习 (16.04.30)
- poco源码简单分析
- linkMap深度解析
- python实现泊松分布_常见的分布及如何使用python实现
- MY-I.MX6-DEMO Android4.4.2环境搭建
- Codeforces C. Ehab and Path-etic MEXs (树 / 构造 / MEX)
- java super父类方法_java super关键字,super调用父类构造方法详解
- 你不得不知的北京十大驾校
- linux只W25Q256驱动,使用m25p80,支持w25q系列nor flash
热门文章
- 我觉得要技术者上升到整体去考虑会好点
- 大学生html5设计大赛方案,2018年大学生三维设计大赛策划书范文
- java 注解 id_java注解
- 前端趋势榜:上周最有意思、又实用的 10 大 Web 项目 - 210924
- k8s部署ingress:使用heptio-contour部署ingress controller(通过sealos安装,非nginx-ingress类型)
- docker --link容器互联
- elasticsearch ik分词插件配置自定义分词词典
- python文件中环境声明_Python环境构建
- python进度条 pyqt_python如何通过pyqt5实现进度条
- volatile的学习总结