堆空间的内存分配管理系统及嵌入式芯片的制作方法

文档序号:12612211阅读:268来源:国知局
堆空间的内存分配管理系统及嵌入式芯片的制作方法与工艺

本发明涉及内存堆领域,尤其涉及堆空间的内存分配管理系统及嵌入式芯片。



背景技术:

目前,嵌入式在数字信号处理系统中已经广泛应用,特别是多核DSP芯片,如何实现对多核DSP内存堆高效管理、可靠应用已成为多核DSP实时嵌入式系统开发的一个技术点。目前在嵌入式系统应用的内存堆,大多以C语言标准库自带malloc/free函数,实现内存申请或者释放。然而会出现很多问题,例如效率不能满足实时嵌入式操作系统中对内存堆高性能的要求,例如,在堆上,释放内存时,将内存释放到整个内存池中,当再次是申请时还是通过malloc,这样碎片化比较严重,且此过程比较耗时效率较低等不足之处,对于使用者也难于维护,例如,在系统运行过程中会不停的有内存的申请释放,无法实时监控堆的使用情况。



技术实现要素:

第一方面,本发明提供了一种堆空间的内存分配管理系统,该系统包括:

堆空间创建单元,用于创建堆空间;

内存池创建单元,用于根据应用配置的至少一个典型长度和各典型长度的数据块数量在所述堆空间内创建内存池,所述内存池中为带有对应数据块数量的所述至少一个典型长度内存空间的节点和各所述典型长度的链表集,所述内存池中各节点的节点头压入所述典型长度对应的链表集;

动静态属性单元,用于根据应用配置的静态或动态属性确定所述节点的静态或动态属性,所述内存池的链表集包括正在使用动态节点链表、正在使用静态节点链表和已经释放动态节点链表。

优选的,所述堆空间创建单元,具体用于:若应用配置的堆空间信息包括私有堆属性标志,则在核内私有存储区域内创建堆空间;若应用配置的堆空间信息包括共享堆属性标志,则在核内共享存储区域内创建堆空间。

优选的,还包括:

请求内存单元,用于获得应用向所述堆空间申请内存的请求;

判断单元,用于确定所述申请内存小于等于所述堆空间的最大典型长度,则判断所述堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中是否有节点头;

已释放内存占用单元,用于若堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中有节点头,则将已经释放动态节点链表中节点头所在节点的内存地址返回给应用,将所述节点头从已经释放动态节点链表压入到正在使用动态节点链表;

开辟节点单元,用于若堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中没有节点头,则在堆空间内未使用的内存空间建立带有申请内存长度的内存空间的新节点,将新节点的内存地址返回给应用,将新节点的节点头压入申请内存长度的链表集。

优选的,所述节点由顺序排列的节点头、返回给应用的内存空间和预设长度的节点尾三部分组成,返回给应用的内存空间的长度与所述典型长度相同。

优选的,还包括第一共享判断单元,与所述请求内存单元、开辟节点单元以及已释放内存占用单元连接,用于在所述请求内存单元获得应用所述堆空间申请内存的请求之后,判断所述堆空间是否在共享区域,若是,则需要加自旋锁,若否,则关中断直至内存申请成功。

优选的,还包括:

请求释放单元,用于获取应用对所述堆空间内存的释放请求;

节点释放单元,用于判断内存释放请求中的释放内存地址对应节点是动态节点还是静态节点,若是动态节点,则将节点从所述正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中;若是静态节点,确定内存释放请求中的释放内存地址对应节点是静态节点,则返回错误信息给应用。

优选的,还包括第二共享判断单元,与所述请求释放单元以及节点释放单元连接,用于所述请求释放单元获取应用释放所述堆空间内存的请求之后,判断所述堆空间是否在共享区域,若是,则加自旋锁,若否,则关中断直至内存释放成功。

第二方面,本发明还提供了一种嵌入式芯片,包括上述第二方面所述的一 种堆空间的内存分配管理系统。

与现有技术相比,本发明提供的堆空间的内存分配管理系统及嵌入式芯片,具有以下有益效果:本发明通过应用来配置所述节点的静态或动态属性,实现了对静态、动态节点的分开管理,其次在每个典型长度申请、释放的节点由正在使用动态节点链表,正在使用静态节点链表和已经释放动态节点链表维护,其优势是提高申请、释放内存的效率,减小节点入队或者出队时耗时,能够在一定程度上提高堆管理的效率,一般静态节点都用于操作系统的任务,信号量等,与动态节点分开,降低被其他越界内存修改的概率,在一定程度增加系统的可靠性。每个堆空间根据需求可创建多个典型长度,解决了堆空间管理上碎片化的问题,同时可以很快定位出个别典型长度的内存出了问题,节点构成,根据典型长度开辟一片内存,以节点头开始紧跟返回给用户的空间,以节点尾结束,为每个节点设计了边界,如果用户填写的数据越界踩其他节点,节点尾的标志有助于定位问题。

附图说明

图1是本发明提供的一种堆空间的内存分配管理方法第一个实施例的的方法流程图。

图2是本发明提供的一种堆空间的内存分配管理方法第二个实施例的方法流程图的方法流程图一。

图3是本发明提供的一种堆空间的内存分配管理方法第二个实施例的方法流程图的方法流程图二。

图4是本发明提供的一种堆空间的内存分配管理系统第一个实施例的结构框图。

图5是本发明提供的一种堆空间的内存分配管理系统第二个实施例的结构框图一。

图6是本发明提供的一种堆空间的内存分配管理系统第二个实施例的结构框图二。

图7是本发明提供的一种堆空间的内存分配管理系统第二个实施例的结构框图三。

图8是本发明提供的实施例中实例1的方法流程图。

图9是本发明提供的实施例中实例2的方法流程图。

图10是本发明提供的实施例中实例3的方法流程图。

图11是本发明提供的实施例中实例4的方法流程图。

具体实施方式

为使本发明解决的技术问题、采用的技术方案和达到的技术效果更加清楚,下面将结合附图对本发明实施例的技术方案作进一步的详细描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。

图1示出根据本发明提供的一种堆空间的内存分配管理方法第一个实施例的方法流程图。本实施例的一种堆空间的内存分配管理方法主要由一种堆空间的内存分配方系统来执行,该系统可以设置在嵌入式芯片中,如DSP芯片,当然也可以设置在其他包含CPU的芯片中。该方法包括以下步骤:

S11:创建堆空间。

具体的,在内存中定义一块未被占用的内存空间作为堆空间。

例如:在内存中定义一块未被占用的内存空间作为堆空间A。

当在多核芯片中创建堆空间时,应用配置的堆空间信息包括私有堆属性标志,则在核内私有存储区域内创建堆空间;应用配置的堆空间信息包括共享堆属性标志,则在核内共享存储区域内创建堆空间。内存域根据CACHE属性又分为具有CACHE属性域和不具有CACHE属性域,一般情况下,具有CACHE属性域则可以为核内私有存储区域,不具有CACHE属性域为核内共享存储区域,使本发明的内存堆管理配置灵活,满足由使用者指定堆的位置需求。

S12:根据应用配置的至少一个典型长度和各典型长度的数据块数量在堆空间内创建内存池,内存池中为带有对应数据块数量的至少一个典型长度内存空间的节点和各典型长度的链表集,内存池中各节点的节点头压入典型长度对应的链表集。

其中,应用配置的典型长度可以为一种,也可以为多种。

如上例,应用配置了第一典型长度108B和第二典型长度236B根据应用配置的第一典型长度为108B,第一典型长度的数据块数量为m个,在之前创 建好的堆空间A中建立m个带有108B内存空间的节点,应用又配置了第二典型长度为236B,第二典型长度的数据块数量为n个,则在之前创建好的堆空间A中建立m个带有108B内存空间的节点,该带有108B内存空间的节点的节点头压入在内存池B1的链表集b1,该带有108B内存空间的节点的节点头压入内存池B1的链表集b2,这些带有108B内存空间的节点和带有236B内存空间的节点、链表集b1和链表集b2构成一个内存池B1。

如图8示出的实例1:以多核DSP芯片的应用中堆空间的创建为例,按照如下步骤实现:

(101),根据应用设置的私有或共享属性,到通过划分内存在核私有空间定义一个全局数组变量作为堆空间,数组大小即为要创建堆空间的大小;

(102),根据本方案提供的堆属性结构体,定义一个结构体变量,即为要记录创建堆的相关属性参数;

(103),设定堆典型长度块的数量,及每个典型长度的大小;

(104),定义堆的名字;

(105),以步骤(101)、(102)、(103)、(104)及私有或者共享堆属性标志作为创建函数入参,调用堆创建函数;

(106),判断堆属性和堆起始地址两个入参的合法性,如果合法执行步骤(107),否则直接返回错误;

(107),按照堆属性结构体的长度,对该堆属性结构体变量清0;

(108),记录创建堆的属性:堆的起始地址,即堆的头、堆的长度,堆的当前地址,堆的私有或者共享属性标志,堆典型长度,堆的名字记录到步骤(102)的属性结构体变量中;

(109),如果堆为私有堆,把步骤(108)作为节点压入私有堆链表,否则把步骤(108)作为节点压入共享堆链表;

(110),创建完成,把步骤(102)作为函数返回值,返回给应用作为句柄;

(111),定义一个全局变量记录步骤(110)的返回值。

S13:根据应用配置的静态或动态属性确定节点的静态或动态属性,内存池的链表集包括正在使用动态节点链表、正在使用静态节点链表和已经释放动态节点链表。S13与S12的顺序不作限定。

其中,正在使用动态节点链表中记录有使用/释放状态为使用状态的动态节点的节点头,正在使用静态节点链表中记录有使用/释放状态为使用状态的静态节点的节点头,已经释放动态节点链表中记录有使用/释放状态为释放状态的动态节点的节点头。

一般节点由顺序排列的节点头、返回给应用的内存空间两部分组成,返回给应用的内存空间的长度与对应的典型长度相同,节点头是该节点的核心,维护整个节点的属性和在内存链表上挂接释放,节点头中包括了该节点的使用/释放状态,节点头后面跟的为返回给应用的内存空间的内存地址,即为节点内存地址。如上例中,带有108B内存空间的节点和带有236B内存空间的节点的节点头长度均为20B,节点头长度均为4B。

优选的,节点由顺序排列的节点头、返回给应用的内存空间和预设长度的节点尾三部分组成,返回给应用的内存空间的长度与对应的典型长度相同,返回给应用的内存空间的首地址为节点的节点内存地址,预设长度的节点尾为每个节点设计了边界,如果用户填写的数据越界踩其他节点,节点尾的标志有助于定位问题。

静态节点为在系统运行中不需要释放内存的节点,一般用于操作系统的任务,信号量等,与动态节点分开,降低被其他越界内存修改的概率,在一定程度增加系统的可靠性,同时,每个节点都具有动态或者静态的属性之一,动静态分开,减小节点入队或者出队时耗时,能够在一定程度上提高堆管理的效率。

图2和图3示出根据本发明提供的一种堆空间的内存分配管理方法第二个实施例的方法流程图。本实施例的一种堆空间的内存分配管理系统主要由本实施例的一种堆空间的内存分配管理方法主要由一种堆空间的内存分配系统来执行,该系统可以设置在嵌入式芯片中,如DSP芯片。本实施例相比于一种堆空间的内存分配管理方法第一个实施例的区别在于:还包括申请内存步骤和释放内存步骤,该方法包括以下步骤:

S21:创建堆空间。该步骤的执行过程与S11相同,在此不再赘述。

S22:根据应用配置的至少一个典型长度和各典型长度的数据块数量在堆空间内创建内存池,内存池中为带有对应数据块数量的至少一个典型长度内存空间的节点和各典型长度的链表集,内存池中各节点的节点头压入典型长度对应的链表集。该步骤的执行过程与S12相同,在此不再赘述。

S23:根据应用配置的静态或动态属性确定节点的静态或动态属性,内存池的链表集包括正在使用动态节点链表,正在使用静态节点链表和已经释放动态节点链表。该步骤的执行过程与S13相同,在此不再赘述。

S24:获得应用向堆空间申请内存的请求。

例如,调用申请内存函数,函数中包括参数有:堆空间的句柄、申请内存长度、申请内存的动态或静态属性以及该申请内存的定义名称。

S25:确定申请内存小于等于堆空间的最大典型长度,则判断堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中是否有节点头。

其中,匹配的典型长度为堆空间中大于等于申请内存长度的最小典型长度。

例如:内存池B1已经有第一典型长度108B和第二典型长度236B,若申请内存长度是108B,则将判断堆空间中与申请内存长度108B匹配的第一典型长度108B的已经释放动态节点链表中是否有节点头,若申请内存长度为128B,确定其小于最大典型长度236B,因此,将判断堆空间中与申请内存长度128B匹配的第一典型长度136B的已经释放动态节点链表中是否有节点头。

S25之后,包括S26:若是,则将已经释放动态节点链表中节点头所在节点的内存地址返回给应用,将节点头从已经释放动态节点链表压入到正在使用动态节点链表。

具体的,且若S25中判断堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中有节点头,则将已经释放动态节点链表中节点头的节点内存地址返回给应用,节点头的节点内存则成为应用的申请内存,同时判断该节点为动态节点还是静态节点,若为动态节点,则将该节点头压入该内存池的正在使用动态节点链表;若为静态节点,则将该节点头压入该内存池的正在使用静态节点链表。

如上例,若申请内存长度是108B,则将判断堆空间中与申请内存长度108B匹配的第一典型长度108B的已经释放动态节点链表中是否有节点头,而空间中有典型长度108B对应的已经释放的动态节点链表中有节点头t1,则认为该节点头对应节点的内存空间处于已释放状态,则将节点头t1的节点内存地址返回给应用,节点内存地址即为节点中返回给应用的内存空间的首地址,若节点头t1长度为20B,则将节点头t1首地址偏移20B作为节点内存地址返 回给应用,该节点头t1的节点内存则成为应用的申请内存。

S25之后,包括S27:若否,则在堆空间内未使用的内存空间建立带有申请内存长度的内存空间的新节点,将新节点的内存地址返回给应用,将新节点的节点头压入申请内存长度的链表集。

如上例,若申请内存长度为128B,确定其小于最大典型长度236B,因此,将判断堆空间中与申请内存长度128B匹配的第一典型长度236B的已经释放动态节点链表中是否有节点头,而空间中有典型长度236B对应的已经释放的动态节点链表中没有节点头,则认为该典型长度236B的节点的内存空间均处于正在使用状态,则根据申请内存长度在堆空间内未使用的内存空间创建新节点t3,其为带有128B的内存空间的新节点t3,将新节点t3的节点内存地址返回给应用,将新节点的节点头t3压入典型长度为申请内存长度128B的链表集中。

其中,将新节点的节点头压入以申请内存长度为典型长度的链表集:判断申请内存是动态属性还是静态属性,若为动态属性,则将新节点的节点头压入对应内存池的正在使用动态节点链表末尾,若为静态属性,则新节点的节点头压入对应内存池的正在使用静态列表末尾。

作为一种较佳的实施方式,在S24之后,还包括S241:判断所述堆空间是否在共享区域,若是,则加自旋锁;若否,则关中断直至内存申请成功。其中,申请成功是指在步骤S26中将节点头从已经释放动态节点链表压入到正在使用动态节点链表或S27中将新节点的节点头压入申请内存长度的链表集。通过加自旋锁则确保在同一时刻仅能一个核操作该堆空间,每个核会有多个优先级不同的任务,在每次申请内存时关掉中断,申请成功后打开中断,在这个非常断点时间内,任务不会切换,确保内存的申请时为原子操作。

如附图9示出的实例2:以多核DSP系统中应用中在堆空间上申请内存为例,调用申请内存函数,通过如下步骤实现:

(201),第一个入参为实例1步骤(111),第二个入参为申请内存长度,第三个入参为申请动态或者静态内存,地址对齐的长度,第五个入参申为要申请内存块定义一个名字;

(202),函数入参判断,如果入参合法执行步骤(202),否则返回错误;

(203),根据堆句柄中携带的堆空间私有、共享模式,判断是否申请自旋 锁,如果是共享堆,执行步骤(204),否则执行步骤(205);

(204),申请自旋锁;

(205),记录本申请内存节点的名字,即步骤(201)的第五个入参;

(206),根据步骤(201)中第三个入参,如果是动态内存模式,执行步骤(207),否则执行步骤(208);

(207),调用动态堆内存管理函数,实现内存的申请,该函数返回值即为要返回给应用的申请地址,执行步骤(209);

(208),调用静态堆内存管理函数,实现内存的申请,该函数返回值即为要返回给应用的申请地址,执行步骤(209);

(209),根据堆句柄中携带的堆私有、共享模式,判断是否释放自旋锁,如果是共享堆,执行步骤(210),否则执行步骤(211);

(210),释放步骤(204)获得的自旋锁;

(211),将步骤(208)或者步骤(209)中的获得的地址作为步骤(201)函数返回值,即是申请到的内存的地址。

如附图10示出的实例3:详细说明实例2中的步骤(207)的实现,实现步骤如下:(301)在动态内存申请函数填入堆的句柄,申请长度,地址对齐长度,申请节点名字,调用函数开始;

(302),根据申请长度,确认该长度落在哪个典型长度值中,获得该典型值长度的索引;

(303),关中断,确保原子操作;

(304),根据获得的典型长度索引,判断该典型长度值的已释放链表是否为空,如果该链表为空,执行步骤(305),否则执行步骤(308);

(305),根据申请长度,从当前堆未使用的数据空间开辟一段,其长度包括节点头、典型值长度和节点尾三部分;

(306),将步骤(305)获得的内存块的接点头填入相关字段:节点名字、节点长度、节点在用标志、动态节点标志,同时在节点尾部填入标志,说明这是节点的尾;

(307),把该节点压入该典型值长度的在用链表后,执行步骤(310);

(308),从已释放链表中弹出一个该典型值的节点;

(309),修改该节点的属性,置在用标志,新的名字,然后执行步骤(307);

(310),开中断;

(311),返回节点头后面跟的内存地址,即返回给应用的地址。

如图3所示,作为一种较佳的实施方式,在S23之后,还包括S28,S28与S24至S27并不限定先后关系。

S28:获取应用对堆空间内存的释放请求。

一般释放请求中包括释放内存所在堆空间的句柄、释放内存地址,其中释放内存地址为堆空间中某个节点内的返回应用的内存空间。

S29:判断内存释放请求中的释放内存地址对应节点是动态节点还是静态节点,若是动态节点,则将节点从正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中;若是静态节点,确定内存释放请求中的释放内存地址对应节点是静态节点,则返回错误信息给应用。

具体的,判断内存释放请求中的释放内存地址对应节点是动态节点还是静态节点,若是动态节点,则将节点从其所在的内存池的正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中;若是静态节点,则返回错误信息给应用。

通过对指定内存的释放,方便管理。释放内存地址可以为S22中创建的节点的节点内存地址,也可以为S27中新节点的节点内存地址。静态节点都用于操作系统的任务,信号量等,与动态节点分开,降低被其他越界内存修改的概率,在一定程度增加系统的可靠性。

优选的,在S28之后,还包括S281:判断所述堆空间是否在共享区域,若是,则加自旋锁,若否,则关中断直至内存申请成功。其中,申请成功是指在步骤S28中则将节点从正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中或则返回错误信息给应用。通过加自旋锁则确保在同一时刻仅能一个核操作该堆空间,每个核会有多个优先级不同的任务,在每次释放内存时关掉中断,释放完成后打开中断,在这个非常断点时间内,任务不会切换,确保内存的释放时为原子操作。

如图11示出的实例4:以在多核DSP系统中应用,在堆上释放内存为例,内存释放如下步骤实现:

(401),调用释放内存函数,入参:释放内存的堆句柄,释放内存地址,调用函数开始;

(402),根据句柄入参,地址入参,获得释放地址的节点;

(403),根据节点携带信息判断是动态节点还是静态节点,如果动态节点执行步骤(404),否则返回应用错误;

(404),判断该节点是否为已释放节点,如果该节点在用节点执行步骤(405),否则返回正确;

(405),该堆是共享堆还是私有堆?如果是共享堆,执行步骤(406),如果是私有堆,执行步骤(407);

(406),获取自旋锁,然后执行步骤(408);

(407),关中断,然后执行步骤(408);

(408),把该节点从在用链表中移除;

(409),修改该节点的属性,从在用状态修改为释放状态;

(410),将该节点压入已释放链表;

(411),该堆是共享堆还是私有堆?如果是共享堆,执行步骤(412),如果是私有堆执行步骤(413);

(412),退出自循环锁,然后执行步骤(414);

(413),开中断,然后执行步骤(414);

(414),返回。

图4示出根据本发明提供的一种堆空间的内存分配管理系统第一个实施例的结构框图。本实施例的一种堆空间的内存分配管理系统该系统可以设置在嵌入式芯片中,如DSP芯片,当然也可以设置在其他包含CPU的芯片中。一种堆空间的内存分配管理系统包括堆空间创建单元31、内存池创建单元32和动静态属性单元33。

堆空间创建单元31,用于创建堆空间。

具体的,在内存中定义一块未被占用的内存空间作为堆空间。

例如:在内存中定义一块未被占用的内存空间作为堆空间A。

当在多核芯片中创建堆空间时,应用配置的堆空间信息包括私有堆属性标志,则在核内私有存储区域内创建堆空间;应用配置的堆空间信息包括共享堆属性标志,则在核内共享存储区域内创建堆空间。内存域根据CACHE属性又分为具有CACHE属性域和不具有CACHE属性域,一般情况下,具有CACHE属性域则为核内私有存储区域,不具有CACHE属性域为核内共享存储区域, 使本发明的内存堆管理配置灵活,满足由使用者指定堆的位置需求。

内存池创建单元32,用于根据应用配置的至少一个典型长度和各典型长度的数据块数量在堆空间内创建内存池,内存池中为带有对应数据块数量的至少一个典型长度内存空间的节点和各典型长度的链表集,内存池中各节点的节点头压入典型长度对应的链表集。

其中,应用配置的典型长度可以为一种,也可以为多种。

如上例,应用配置了第一典型长度108B和第二典型长度236B根据应用配置的第一典型长度为108B,第一典型长度的数据块数量为m个,在之前创建好的堆空间A中建立m个带有108B内存空间的节点,应用又配置了第二典型长度为236B,第二典型长度的数据块数量为n个,则在之前创建好的堆空间A中建立m个带有108B内存空间的节点,该带有108B内存空间的节点的节点头压入在内存池B1的链表集b1,该带有108B内存空间的节点的节点头压入内存池B1的链表集b2,这些带有108B内存空间的节点和带有236B内存空间的节点、链表集b1和链表集b2构成一个内存池B1。

如附图8示出的实例1:以多核DSP芯片的应用中堆空间的创建为例,按照如下步骤实现:

(101),根据应用设置的私有或共享属性,到通过划分内存在核私有空间定义一个全局数组变量作为堆空间,数组大小即为要创建堆空间的大小;

(102),根据本方案提供的堆属性结构体,定义一个结构体变量,即为要记录创建堆的相关属性参数;

(103),设定堆典型长度块的数量,及每个典型长度的大小;

(104),定义堆的名字;

(105),以步骤(101)、(102)、(103)、(104)及私有或者共享堆属性标志作为创建函数入参,调用堆创建函数;

(106),判断堆属性和堆起始地址两个入参的合法性,如果合法执行步骤(107),否则直接返回错误;

(107),按照堆属性结构体的长度,对该堆属性结构体变量清0;

(108),记录创建堆的属性:堆的起始地址,即堆的头、堆的长度,堆的当前地址,堆的私有或者共享属性标志,堆典型长度,堆的名字记录到步骤(102)的属性结构体变量中;

(109),如果堆为私有堆,把步骤(108)作为节点压入私有堆链表,否则把步骤(108)作为节点压入共享堆链表;

(110),创建完成,把步骤(102)作为函数返回值,返回给应用作为句柄;

(111),定义一个全局变量记录步骤(110)的返回值。

动静态属性单元33,用于根据应用配置的静态或动态属性确定节点的静态或动态属性,内存池的链表集包括正在使用动态节点链表、正在使用静态节点链表和已经释放动态节点链表。

其中,正在使用动态节点链表中记录有使用/释放状态为使用状态的动态节点的节点头,正在使用静态节点链表中记录有使用/释放状态为使用状态的静态节点的节点头,已经释放动态节点链表中记录有使用/释放状态为释放状态的动态节点的节点头。

一般节点由顺序排列的节点头、返回给应用的内存空间两部分组成,返回给应用的内存空间的长度与对应的典型长度相同,节点头是该节点的核心,维护整个节点的属性和在内存链表上挂接释放,节点头中包括了该节点的使用/释放状态,节点头后面跟的为返回给应用的内存空间的内存地址,即为节点内存地址。如上例中,带有108B内存空间的节点和带有236B内存空间的节点的节点头长度均为20B,节点头长度均为4B。

优选的,节点由顺序排列的节点头、返回给应用的内存空间和预设长度的节点尾三部分组成,返回给应用的内存空间的长度与对应的典型长度相同,返回给应用的内存空间的首地址为节点的节点内存地址,预设长度的节点尾为每个节点设计了边界,如果用户填写的数据越界踩其他节点,节点尾的标志有助于定位问题。

静态节点为在系统运行中不需要释放内存的节点,一般用于操作系统的任务,信号量等,与动态节点分开,降低被其他越界内存修改的概率,在一定程度增加系统的可靠性,同时,每个节点都具有动态或者静态的属性之一,动静态分开,减小节点入队或者出队时耗时,能够在一定程度上提高堆管理的效率。

图5示出根据本发明提供的一种堆空间的内存分配管理系统第二个实施例的结构框图。本实施例的一种堆空间的内存分配管理系统可以设置在DSP嵌入式芯片中,如DSP芯片当然也可以设置在其他包含CPU的芯片中。本实施 例相比于一种堆空间的内存分配管理系统第一个实施例的区别在于:本实施例中包括了用于申请内存和释放内存的单元。

本实施例中,本系统包括堆空间创建单元41、内存池创建单元42、动静态属性单元43、请求内存单元44、判断单元45、已释放内存占用单元46、开辟节点单元47以及第一共享判断单元441。

堆空间创建单元41,用于创建堆空间。该单元的执行过程与堆空间创建单元31相同,在此不再赘述。

内存池创建单元42,用于根据应用配置的至少一个典型长度和各典型长度的数据块数量在堆空间内创建内存池,内存池中为带有对应数据块数量的至少一个典型长度内存空间的节点和各典型长度的链表集,内存池中各节点的节点头压入典型长度对应的链表集。该单元的执行过程与内存池创建单元32相同,在此不再赘述。

动静态属性单元43,用于根据应用配置的静态或动态属性确定节点的静态或动态属性,内存池的链表集包括正在使用动态节点链表,正在使用静态节点链表和已经释放动态节点链表。该单元的执行过程与动静态属性单元33相同,在此不再赘述。

请求内存单元44,用于获得应用向堆空间申请内存的请求。

例如,调用申请内存函数,函数中包括参数有:堆空间的句柄、申请内存长度、申请内存的动态或静态属性以及该申请内存的定义名称。

判断单元45,用于确定申请内存小于等于堆空间的最大典型长度,则判断堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中是否有节点头。

其中,匹配的典型长度为堆空间中大于等于申请内存长度的最小典型长度。

例如:内存池B1已经有第一典型长度108B和第二典型长度236B,若申请内存长度是108B,则将判断堆空间中与申请内存长度108B匹配的第一典型长度108B的已经释放动态节点链表中是否有节点头,若申请内存长度为128B,确定其小于最大典型长度236B,因此,将判断堆空间中与申请内存长度128B匹配的第一典型长度136B的已经释放动态节点链表中是否有节点头。

已释放内存占用单元46,用于若判断单元45得出堆空间中与申请内存长 度匹配的典型长度的已经释放动态节点链表中有节点头,则将已经释放动态节点链表中节点头所在节点的内存地址返回给应用,将节点头从已经释放动态节点链表压入到正在使用动态节点链表。

具体的,且若判断单元45中判断堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中有节点头,则将已经释放动态节点链表中节点头的节点内存地址返回给应用,节点头的节点内存则成为应用的申请内存,同时判断该节点为动态节点还是静态节点,若为动态节点,则将该节点头压入该内存池的正在使用动态节点链表;若为静态节点,则将该节点头压入该内存池的正在使用静态节点链表。

如上例,若申请内存长度是108B,则将判断堆空间中与申请内存长度108B匹配的第一典型长度108B的已经释放动态节点链表中是否有节点头,而空间中有典型长度108B对应的已经释放的动态节点链表中有节点头t1,则认为该节点头对应节点的内存空间处于已释放状态,则将节点头t1的节点内存地址返回给应用,节点内存地址即为节点中返回给应用的内存空间的首地址,若节点头t1长度为20B,则将节点头t1首地址偏移20B作为节点内存地址返回给应用,该节点头t1的节点内存则成为应用的申请内存。

开辟节点单元47,用于若判断单元45得出堆空间中与申请内存长度匹配的典型长度的已经释放动态节点链表中没有节点头,则在堆空间内未使用的内存空间建立带有申请内存长度的内存空间的新节点,将新节点的内存地址返回给应用,将新节点的节点头压入申请内存长度的链表集。

如上例,若申请内存长度为128B,确定其小于最大典型长度236B,因此,将判断堆空间中与申请内存长度128B匹配的第一典型长度236B的已经释放动态节点链表中是否有节点头,而空间中有典型长度236B对应的已经释放的动态节点链表中没有节点头,则认为该典型长度236B的节点的内存空间均处于正在使用状态,则根据申请内存长度在堆空间内未使用的内存空间创建新节点t3,其为带有128B的内存空间的新节点t3,将新节点t3的节点内存地址返回给应用,将新节点的节点头t3压入典型长度为申请内存长度128B的链表集中。

其中,将新节点的节点头压入以申请内存长度为典型长度的链表集:判断申请内存是动态属性还是静态属性,若为动态属性,则将新节点的节点头压入 对应内存池的正在使用动态节点链表末尾;若为静态属性,则新节点的节点头压入对应内存池的正在使用静态列表末尾。

如图5和图7所示,作为一种较佳的实施方式,还包括第一共享判断单元441,与请求内存单元44、开辟节点单元47以及已释放内存占用单元46连接:用于判断所述堆空间是否在共享区域,若是,则加自旋锁;若否,则关中断直至内存申请成功。

其中,申请成功是指在已释放内存占用单元46中将节点头从已经释放动态节点链表压入到正在使用动态节点链表或开辟节点单元47中将新节点的节点头压入申请内存长度的链表集。通过加自旋锁则确保在同一时刻仅能一个核操作该堆空间,每个核会有多个优先级不同的任务,在每次申请内存时关掉中断,申请完成后打开中断,在这个非常断点时间内,任务不会切换,确保内存的申请时为原子操作。

如附图9示出的实例2:以在多核DSP系统中应用中在堆空间上申请内存为例,调用申请内存函数,通过如下步骤实现:

(201),第一个入参为实例1步骤(111),第二个入参为申请内存长度,第三个入参为申请动态或者静态内存,地址对齐的长度,第五个入参申为要申请内存块定义一个名字;

(202),函数入参判断,如果入参合法执行步骤(202),否则返回错误;

(203),根据堆句柄中携带的堆空间私有、共享模式,判断是否申请自旋锁,如果是共享堆,执行步骤(204),否则执行步骤(205);

(204),申请自旋锁;

(205),记录本申请内存节点的名字,即步骤(201)的第五个入参;

(206),根据步骤(201)中第三个入参,如果是动态内存模式,执行步骤(207),否则执行步骤(208);

(207),调用动态堆内存管理函数,实现内存的申请,该函数返回值即为要返回给应用的申请地址,执行步骤(209);

(208),调用静态堆内存管理函数,实现内存的申请,该函数返回值即为要返回给应用的申请地址,执行步骤(209);

(209),根据堆句柄中携带的堆私有、共享模式,判断是否释放自旋锁,如果是共享堆,执行步骤(210),否则执行步骤(211);

(210),释放步骤(204)获得的自旋锁;

(211),将步骤(208)或者步骤(209)中的获得的地址作为步骤(201)函数返回值,即是申请到的内存的地址。

如附图10示出的实例3:详细说明实例2中的步骤(207)的实现,实现步骤如下:(301)在动态内存申请函数填入堆的句柄,申请长度,地址对齐长度,申请节点名字,调用函数开始;

(302),根据申请长度,确认该长度落在哪个典型长度值中,获得该典型值长度的索引;

(303),关中断,确保原子操作,原子操作为等一个核申请完毕退出自旋锁后,其他核获得申请权限;

(304),根据获得的典型长度索引,判断该典型长度值的已释放链表是否为空,如果该链表为空,执行步骤(305);否则执行步骤(308);

(305),根据申请长度,从当前堆未使用的数据空间开辟一段,其长度包括节点头、典型值长度和节点尾三部分;

(306),将步骤(305)获得的内存块的接点头填入相关字段:节点名字、节点长度、节点在用标志、动态节点标志,同时在节点尾部填入标志,说明这是节点的尾;

(307),把该节点压入该典型值长度的在用链表后,执行步骤(310);

(308),从已释放链表中弹出一个该典型值的节点;

(309),修改该节点的属性,置在用标志,新的名字,然后执行步骤(307);

(310),开中断;

(311),返回节点头后面跟的内存地址,即返回给应用的地址。

如图6和图7所示,作为一种较佳的实施方式,还包括请求释放单元48和连接请求释放单元48的节点释放单元49,内存池创建单元43的输出端连接请求释放单元48,或辟节点单元47的输出端连接请求释放单元48。

请求释放单元48,用于获取应用对堆空间内存的释放请求。

一般释放请求中包括释放内存所在堆空间的句柄、释放内存地址,其中释放内存地址为堆空间中某个节点内的返回应用的内存空间。

节点释放单元49,用于判断内存释放请求中的释放内存地址对应节点是动态节点还是静态节点,若是动态节点,则将节点从正在使用动态节点链表中移 除,并添加到已经释放的动态节点链表中;若是静态节点,确定内存释放请求中的释放内存地址对应节点是静态节点,则返回错误信息给应用。

具体的,判断内存释放请求中的释放内存地址对应节点是动态节点还是静态节点,若是动态节点,则将节点从其所在的内存池的正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中;若是静态节点,则返回错误信息给应用。

通过对指定内存的释放,方便管理。释放内存地址可以为内存池创建单元42中创建的节点的节点内存地址,也可以为辟节点单元47中新节点的节点内存地址。静态节点都用于操作系统的任务,信号量等,与动态节点分开,降低被其他越界内存修改的概率,在一定程度增加系统的可靠性。

优选的,如若图6和图7所示,还包括第二共享判断单元481,与请求释放单元48以及节点释放单元49连接,用于判断所述堆空间是否在共享区域,若是,则加自旋锁;若否,则需要关中断直至内存申请成功。其中,申请成功是指在节点释放单元49中则将节点从正在使用动态节点链表中移除,并添加到已经释放的动态节点链表中或返回错误信息给应用。通过加自旋锁则确保在同一时刻仅能一个核操作该堆空间,每个核会有多个优先级不同的任务,在每次释放内存时关掉中断,释放完成后打开中断,在这个非常断点时间内,任务不会切换,确保内存的释放时为原子操作。

如附图11示出的实例4:以在多核DSP系统中应用,在堆上释放内存为例,内存释放如下步骤实现:

(401),调用释放内存函数,入参:释放内存的堆句柄,释放内存地址,调用函数开始;

(402),根据句柄入参,地址入参,获得释放地址的节点;

(403),根据节点携带信息判断是动态节点还是静态节点,如果动态节点执行步骤(404),否则返回应用错误;

(404),判断该节点是否为已释放节点,如果该节点在用节点执行步骤(405),否则返回正确;

(405),该堆是共享堆还是私有堆?如果是共享堆,执行步骤(406),如果是私有堆,执行步骤(407);

(406),获取自旋锁,然后执行步骤(408);

(407),关中断,然后执行步骤(408);

(408),把该节点从在用链表中移除;

(409),修改该节点的属性,从在用状态修改为释放状态;

(410),将该节点压入已释放链表;

(411),该堆是共享堆还是私有堆?如果是共享堆,执行步骤(412),如果是私有堆,执行步骤(413);

(412),退出自循环锁,然后执行步骤(414);

(413),开中断,然后执行步骤(414);

(414),返回。

综上所述,本发明的堆空间的内存分配管理方法系统及嵌入式芯片,实现了对静态、动态节点的分开管理,其次在每个典型长度申请、释放的节点提高l申请、释放内存的效率,减小节点入队或者出队时耗时,能够在一定程度上提高堆管理的效率,降低系统任务被其他越界内存修改的概率,在一定程度增加系统的可靠性。每个堆空间根据需求可创建多个典型长度,解决了堆空间管理上碎片化的问题,同时可以很快定位出个别典型长度的内存出了问题。

上述实施例仅例示性说明本发明的原理及其功效,而非用于限制本发明。任何熟悉此技术的人士皆可在不违背本发明的精神及范畴下,对上述实施例进行修饰或改变。因此,举凡所属技术领域中具有通常知识者在未脱离本发明所揭示的精神与技术思想下所完成的一切等效修饰或改变,仍应由本发明的权利要求所涵盖。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1