一種嵌入式系統(tǒng)的內(nèi)存分配方案
目)、緩沖池指針、空閑鏈表、用于統(tǒng)計和調(diào)試的參數(shù)等。對緩沖池的操作包括創(chuàng)建緩沖池、釋放緩沖池、從緩沖池中分配1個內(nèi)存單元、釋放內(nèi)存單元回緩沖池等。下面舉2個例子說明一下該方案的具體使用情況。 4.1 Intel交換機驅(qū)動程序中內(nèi)存分配 在以Intel的交換芯片為基礎(chǔ)的交換機方案中,因為采用的是軟件地址學(xué)習(xí)的方式,需要在內(nèi)存中維護(hù)許多數(shù)據(jù),如MAC地址表的軟拷貝、VLAN表、靜態(tài)單播地址表、組播地址表等。這些表都是由一些樹組成,每個樹由一些固定尺寸的節(jié)點組成。一般每個節(jié)點幾十個字節(jié),每棵樹的節(jié)點數(shù)是可增長的,少則幾十,最多可到16K個節(jié)點。因此,很適合于采用該方案,具體的實現(xiàn)如下: (1)緩沖池結(jié)構(gòu) BlockMemMgrtypedefstruct{MemSizedata_cell_size;/*數(shù)據(jù)單元的尺寸*/MemSizeblock_size;/*塊尺寸*/ /*下面的變量為預(yù)定義的每個管理器最多包含的塊數(shù),如64MAX_BLOCKS_OF_MEM_SIZE*/Unsignedshortblocks_being_used;/*已使用的塊數(shù)*/ Voidmem_ptr[PAX_BLOCKS_OF_MEM_SIZE];/*塊數(shù)組*/ SLListfree_data_cells_list;/*空閑鏈表*/ }BlockMemMgr; 結(jié)構(gòu)中的參數(shù)包括:單元尺寸、塊尺寸、已用塊數(shù)、所有塊的地址、空閑鏈表(單向鏈表)。 (2)緩沖池的管理函數(shù) ◆block_mem_create:創(chuàng)建塊內(nèi)存管理器,參數(shù)包括內(nèi)存指針(如為NULL,表示自己分配)、塊尺寸、單元尺寸、返回管理器指針。過程如下: ①檢驗參數(shù)合法性。 ②單元尺寸4字節(jié)對齊,計算每個塊中的單元數(shù)。對內(nèi)存指針進(jìn)行4字節(jié)對齊或者分配內(nèi)存指針。 ③初始化結(jié)構(gòu)BlockMemMgr,包括單元尺寸和塊尺寸。設(shè)置第1個內(nèi)存塊的指針。如果內(nèi)存是外來的,設(shè)置塊已用標(biāo)志(已用為0),表示不能增加塊;否則,已用塊數(shù)設(shè)為1。 ④創(chuàng)建空閑鏈表,將塊內(nèi)所有單元添加到鏈表中,最后一個單元處于鏈表的最前面。 ⑤返回BlockMemMgr。 ◆block_mem_destroy:解構(gòu)一個塊內(nèi)存管理器,釋放它所分配的所有內(nèi)存,調(diào)用者負(fù)責(zé)外部內(nèi)存的釋放。參數(shù)為BlockMemMgr。返回成功失敗標(biāo)志。 ①參數(shù)合法性檢測。 ②刪除單向鏈表(設(shè)鏈表指針為NULL)。 ③如果塊是動態(tài)分配的,釋放它們。 ④釋放結(jié)構(gòu)BlockMemMgr。 ◆block_malloc:從塊內(nèi)存管理器中分配1個單元⑤釋放結(jié)構(gòu)BlockMemMgr ◆block_malloc:從塊內(nèi)存管理器中分配1個單元。參數(shù)為BlockMemMgr,返回數(shù)據(jù)單元指針。 ①參數(shù)合法性檢測。 ②判斷空閑鏈表是否為空(是否為NULL)。如果為空,判斷是否可以動態(tài)分配塊,如果不能,返回失敗;如果可以動態(tài)分配塊,則分配1個塊,執(zhí)行與block_mem_create一樣的操作。 ③從空閑鏈表中分配第1個單元,返回其指針。注意這里有一個小技巧,即數(shù)據(jù)單元在空閑時其中存放空閑鏈表的節(jié)點信息,而分配后則存放數(shù)據(jù)內(nèi)容。 ◆block_free:釋放1個數(shù)據(jù)單元,返回塊內(nèi)存管理器。小心不要對1個單元釋放2次。參數(shù)為BlockMemMgr和單元指針。 ①參數(shù)合法性檢測。 ②地址比較,判斷數(shù)據(jù)單元屬于哪個塊。 ③判斷數(shù)據(jù)單元的內(nèi)容是否為空閑鏈表節(jié)點信息(也就是塊內(nèi)某單元的地址),從而確定是否為2次釋放。 ④將該數(shù)據(jù)單元插入到空閑鏈表的前面。 ⑤引用該單元的指針設(shè)為NULL。 內(nèi)存管理代碼遵守如下約定: ①管理的內(nèi)存是實際可寫的內(nèi)存; ②分配內(nèi)存是4字節(jié)或32位對齊; ③block_malloc、bloc k_free在中斷級調(diào)用是部分安全的,除非BLOCK中已經(jīng)沒有空閑CELL,需要重新調(diào)用malloc分配新的BLOCK(而malloc和free就不是安全的,因為其中使用了信號量和搜索算法,容易引起中斷服務(wù)程序阻塞)。當(dāng)然,block_mem_create和block_mem_destroy必須在進(jìn)程級調(diào)用。 4.2 TMS中的內(nèi)存分配 TMS是WindRiver公司為可管理式交換機推出的開發(fā)包。它用用IDB來管理各種協(xié)議的數(shù)據(jù),比如STP和GVRP等。為了支持IDB,它建立了自己的緩沖池管理方案,程序在bufPoolLib.c中。該程序包含用于緩沖池管理的函數(shù),這些函數(shù)允許從1個池中分配固定數(shù)目和大小的緩沖區(qū)。通過預(yù)先分配一定數(shù)目固定大小的緩沖區(qū),避免了反復(fù)的小的內(nèi)存塊分配/釋放相關(guān)聯(lián)的內(nèi)存碎片和浪費。既然它從1個單一的塊中分配緩沖池,也比對每一個緩沖區(qū)執(zhí)行1次分配有更高的空間效率。模塊對每個緩沖區(qū)加上1個標(biāo)記(MAGIC),釋放時會檢查標(biāo)記。模塊給用戶提供分配和釋放操作定義回調(diào)函數(shù)的能力。這樣可以做到自動的對象創(chuàng)建和解構(gòu),同時允許由多個緩沖池分配的成員組成的對象做為1個單一的實體刪除。這類似于C++中自動的對象構(gòu)建和解構(gòu),不過是用C語言并且沒有堆棧分配的負(fù)擔(dān)。模塊既允許從堆棧中分配緩沖池(通過calloc),也可以在用戶分配的空間中創(chuàng)建它們。模塊用1個單向鏈表來維護(hù)未分配的緩沖區(qū),但不跟蹤已分配的緩沖區(qū)。模塊并不是任務(wù)安全的,用戶需要用信號時來保護(hù)緩沖池。 (1)緩沖池結(jié)構(gòu) typedefstruct{ulong_tmagic;/*用于一致性檢測的特殊標(biāo)記*/ BooleanlocalAlloc;/*內(nèi)存是否在創(chuàng)建緩沖區(qū)時分配*/ SL_LISTfreeList;/*空閑鏈表*/ Voidstore;/*緩沖區(qū)指向的內(nèi)存指針*/ STATUS(*createFn)(void*,ulong_targl);/*創(chuàng)建緩沖區(qū)時的回調(diào)函數(shù)指針*/STATUS(*destroyFn)(void*,ulong_targl);/*釋放緩沖區(qū)時的回調(diào)函數(shù)指針*/Ulong_targVal;/*回調(diào)函數(shù)的參數(shù)*/ }buf_pool_t; 結(jié)構(gòu)中的參數(shù)包括檢查標(biāo)記MAGIC、是否本地分配、空閑鏈表、內(nèi)存指針、創(chuàng)建緩沖池的回調(diào)函數(shù)指針、釋放時的回調(diào)函數(shù)指針、回調(diào)函數(shù)參數(shù)。 (2)相關(guān)函數(shù) ◆BufPoolInitializeStorage:分配和初始化存儲區(qū)。參數(shù)包括存儲區(qū)地址(如為NULL,則本地分配)、緩沖區(qū)大小、緩沖區(qū)個數(shù)。 ①根據(jù)緩沖區(qū)大小和個數(shù)獲得所需的內(nèi)存大小。 ②如果指針為NULL,則調(diào)用calloc分配內(nèi)存。設(shè)置本地分配標(biāo)志。 ③初始化內(nèi)存為0。 ④初始化指針。分配的內(nèi)存塊最前面為緩沖池結(jié)構(gòu)buf_pool_t。實際的存儲區(qū)緊隨其后。Buf_pool_t包含參數(shù)檢查標(biāo)記、是否本地分配、存儲區(qū)地址、分配時回調(diào)函數(shù)、釋放時回調(diào)函數(shù)、回調(diào)函數(shù)變量。此時只設(shè)置存儲區(qū)指針。 ◆BufPoolCreate:創(chuàng)建緩沖池。參數(shù)為內(nèi)存制止。緩沖區(qū)尺寸和個數(shù),創(chuàng)建時回調(diào)函數(shù)、釋放時回調(diào)函數(shù)、回調(diào)函數(shù)參數(shù)。①尺寸對齊。②調(diào)用bufPoolInitializeStorage初始化內(nèi)存區(qū)和buf_pool_t結(jié)構(gòu)。③用傳入?yún)?shù)填充buf_pool_t結(jié)構(gòu)。④將緩沖區(qū)添加到空閑鏈表中,最后的緩沖區(qū)在最前面。 ◆BufPoolDestroy:刪除緩沖池。參數(shù)為buf_pool_t指針。①檢查緩沖池結(jié)構(gòu)中的MAGIC字段是否被個性。②如果是本地分配的則翻放內(nèi)存區(qū)。 ◆BufPoolAlloc:從緩沖池中分配一個緩沖區(qū),參數(shù)為緩沖池結(jié)構(gòu)指針。如果存在空閑緩沖區(qū),則從空閑鏈表中除并提供給調(diào)用者,執(zhí)行創(chuàng)建時回調(diào)函數(shù)。如果回調(diào)函數(shù)返回錯誤,則將緩沖區(qū)返還給空閑鏈表。①檢查緩沖池結(jié)構(gòu)中的MAGIC標(biāo)記是否完好。②從空閑鏈表中取出頭一個節(jié)點。③如果節(jié)點不為空,清空節(jié)點,以其地址為參數(shù)調(diào)用回調(diào)函數(shù)。④如果回調(diào)函數(shù)返回錯誤,則將節(jié)點還給空閑鏈表。⑤返回得到空閑緩沖區(qū)地址。 ◆BufPoolFree:將緩沖 |