一種嵌入式系統的內存分配方案
4.2 TMS中的內存分配
TMS是WindRiver公司為可管理式交換機推出的開(kāi)發(fā)包。它用用IDB來(lái)管理各種協(xié)議的數據,比如STP和GVRP等。為了支持IDB,它建立了自己的緩沖池管理方案,程序在 bufPoolLib.c中。該程序包含用于緩沖池管理的函數,這些函數允許從1個(gè)池中分配固定數目和大小的緩沖區。通過(guò)預先分配一定數目固定大小的緩沖區,避免了反復的小的內存塊分配/釋放相關(guān)聯(lián)的內存碎片和浪費。既然它從1個(gè)單一的塊中分配緩沖池,也比對每一個(gè)緩沖區執行1 次分配有更高的空間效率。模塊對每個(gè)緩沖區加上1個(gè)標記(MAGIC),釋放時(shí)會(huì )檢查標記。模塊給用戶(hù)提供分配和釋放操作定義回調函數的能力。這樣可以做到自動(dòng)的對象創(chuàng )建和解構,同時(shí)允許由多個(gè)緩沖池分配的成員組成的對象做為1個(gè)單一的實(shí)體刪除。這類(lèi)似于C++中自動(dòng)的對象構建和解構,不過(guò)是用C語(yǔ)言并且沒(méi)有堆棧分配的負擔。模塊既允許從堆棧中分配緩沖池(通過(guò)calloc),也可以在用戶(hù)分配的空間中創(chuàng )建它們。模塊用1個(gè)單向鏈表來(lái)維護未分配的緩沖區,但不跟蹤已分配的緩沖區。模塊并不是任務(wù)安全的,用戶(hù)需要用信號時(shí)來(lái)保護緩沖池。
(1)緩沖池結構 typedef struct { ulong_t magic; /*用于一致性檢測的特殊標記*/ Boolean localAlloc; /*內存是否在創(chuàng )建緩沖區時(shí)分配*/ SL_LIST freeList; /*空閑鏈表*/ Void store; /*緩沖區指向的內存指針*/ STATUS(*createFn)(void*,ulong_t argl); /*創(chuàng )建緩沖區時(shí)的回調函數指針*/ STATUS(*destroyFn)(void*,ulong_targl);/*釋放緩沖區時(shí)的回調函數指針*/ Ulong_t argVal;/*回調函數的參數*/ } buf_pool_t; 結構中的參數包括檢查標記MAGIC、是否本地分配、空閑鏈表、內存指針、創(chuàng )建緩沖池的回調函數指針、釋放時(shí)的回調函數指針、回調函數參數。
(2)相關(guān)函數
◆BufPoolInitializeStorage:分配和初始化存儲區。參數包括存儲區地址(如為NULL,則本地分配)、緩沖區大小、緩沖區個(gè)數。
①根據緩沖區大小和個(gè)數獲得所需的內存大小。
②如果指針為NULL,則調用calloc分配內存。設置本地分配標志。
③初始化內存為0。
④初始化指針。分配的內存塊最前面為緩沖池結構buf_pool_t。實(shí)際的存儲區緊隨其后。Buf_pool_t包含參數檢查標記、是否本地分配、存儲區地址、分配時(shí)回調函數、釋放時(shí)回調函數、回調函數變量。此時(shí)只設置存儲區指針。
◆BufPoolCreate:創(chuàng )建緩沖池。參數為內存制止。緩沖區尺寸和個(gè)數,創(chuàng )建時(shí)回調函數、釋放時(shí)回調函數、回調函數參數。
①尺寸對齊。
②調用bufPoolInitializeStorage初始化內存區和buf_pool_t結構。
③用傳入參數填充buf_pool_t結構。 ④將緩沖區添加到空閑鏈表中,最后的緩沖區在最前面。
◆BufPoolDestroy:刪除緩沖池。參數為buf_pool_t指針。
①檢查緩沖池結構中的MAGIC字段是否被個(gè)性。
②如果是本地分配的則翻放內存區。
◆BufPoolAlloc:從緩沖池中分配一個(gè)緩沖區,參數為緩沖池結構指針。如果存在空閑緩沖區,則從空閑鏈表中除并提供給調用者,執行創(chuàng )建時(shí)回調函數。如果回調函數返回錯誤,則將緩沖區返還給空閑鏈表。
①檢查緩沖池結構中的MAGIC標記是否完好。
②從空閑鏈表中取出頭一個(gè)節點(diǎn)。
③如果節點(diǎn)不為空,清空節點(diǎn),以其地址為參數調用回調函數。
④如果回調函數返回錯誤,則將節點(diǎn)還給空閑鏈表。 ⑤返回得到空閑緩沖區地址。
◆BufPoolFree:將緩沖區返回給緩沖池。如果定義了回調函數,將在歸還緩沖之間調用回調函數。參數為緩沖池結構和緩沖區指針。
①緩沖池MAGIC標記是否完好。
②如果定義回調函數、調用之。如果返回錯誤,則設置錯誤號。
③將緩沖區添加到空閑鏈表中頭部。
注意該函數有2點(diǎn):
①回調函數返回錯誤,照樣歸還緩沖區。
②沒(méi)有檢查緩沖區是否二次釋放,這一點(diǎn)與Intel的驅動(dòng)程序不同。 另外,TMS的緩沖池沒(méi)有BLOCK要領(lǐng),不需要判斷哪個(gè)CELL屬于哪個(gè)BLOCK,簡(jiǎn)化 了操作。
5 小結
許多嵌入式應用在RTOS提供的malloc/free的基礎上編寫(xiě)自己的內存管理方案。編寫(xiě)這樣的內存管理方案,目的無(wú)非有兩個(gè):一是減少對 malloc/free的依賴(lài),從而避免由之帶來(lái)的內存碎片、時(shí)間不確定等總是;另一個(gè)是增強程序的查錯能力,送還內存使用錯誤。對于在嵌入式系統中廣泛存在的數據庫類(lèi)型的內存需求,即分配多個(gè)固定尺寸的內存單元的要求,“一閃分配,多次使用”的方案無(wú)疑是一種很好的解決之道。文中介紹的2個(gè)例子很好地體現了它的優(yōu)越性。
評論