在线时间 490 小时 最后登录 2024-2-3 注册时间 2013-2-28 听众数 117 收听数 46 能力 268 分 体力 39235 点 威望 1340 点 阅读权限 255 积分 31237 相册 2 日志 0 记录 0 帖子 1388 主题 937 精华 0 分享 0 好友 111
升级 0%
TA的每日心情 衰 2020-10-25 11:55
签到天数: 264 天
[LV.8]以坛为家I
自我介绍 内蒙古大学计算机学院
群组 : 2013年数学建模国赛备
想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言
1 D. T L& w8 w) D( J: a2 K 7 [- \+ ^! X8 J
& Z Z D+ K" x; Z/ l
4 W) f# ] Z* L1 r *\file
V$ g6 H) g, g# g; L *\brief - p0 V/ [$ e; c
*\details ( i7 C3 q* ~; y
*' ?, S1 c' F( G$ t8 k* F& @
*\author Janson% [/ B; ~3 s. ]4 G8 N) b5 L2 }
*\version
$ w' N6 L4 L8 N* G *\date 04Jan12
5 q/ }, q j3 i, E. h# W$ M/ d+ H *( P# ?2 i3 C" }% f; j- I
*\warning
" f4 q& X( ]1 U0 z N8 f5 m *, J* s( v) J2 m$ {2 O/ r
*\history \arg 30Jan12, Janson, Create the file
+ j, x* e! B) O! d4 ?1 w * modify from VxWorks source
( [# ]& d; T% t) B$ v/ y * Legal Declaration: it is for studying VxWorks only.# B5 d: G- G5 h; b) x$ l4 U/ ?
*/3 I3 n# T; s# I: r" d) u' o
#include "includes.h"
$ H- V: u; C2 l& R
/ F8 ^' _! F' Q6 A /* The memParLib.h file is hear:$ W1 S9 j( V% a/ b
https://code.google.com/p/vxwork ... rivate/memPartLib.h
& z6 T" |+ g8 s6 B+ l- G# K */! u' `; L8 \) [" w* S8 B0 h
. }- Z; [2 z# \8 v
/* optional check for bad blocks */2 A" Q/ h9 b* s6 i
+ B) {6 d a% h- {, ~% `" ~ #define MEM_BLOCK_CHECK 0x10: \8 l7 V" K* x6 ]) q* o
2 P& Y8 h$ w8 f* b( x, h$ ~
/* response to errors when allocating memory */
9 E0 W& S1 h2 i0 q+ c* O3 |! F + A$ s1 A7 }& e" _! I0 \) `- k
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20% H' F9 a, i9 k2 t
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40/ @, @0 J% s$ `! i+ ~
) A$ e. ?" l( h9 L l
/* response to errors when freeing memory */
9 V0 J: n7 Y% V; C 5 X9 y' R/ }# u) V" V( j0 p
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
- b& R, D: L( ^, [. ] #define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x1005 F0 U$ h6 s0 T6 ^" d: @; T
( J% F& x) M9 l$ t0 A- G7 q #define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
$ o8 h1 I6 l& A# k# n3 q/ W #define PREV_HDR(pHdr) ((pHdr)->prevHdr)
) q4 d) \! S" v
6 f* }4 U& B7 t% r) j #define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
* V) K* l) t: l) [, e* M #define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \( ^9 c! W9 }5 A7 ]# u
sizeof(BLOCK_HDR)))4 F3 B3 m0 A; I. S) N% ~/ g# }
$ ?" s! Q$ K+ `9 X7 u6 Q #define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
9 H0 `) c7 o8 d0 A; o #define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \" p- u) k) J" V
OFFSET (FREE_BLOCK, node)))
t- x& C! P3 L c! t( `- d
" y# L( O+ j }5 x+ n static BOOL memPartLibInstalled = FALSE;% d6 @% G5 E0 ~- O
- @0 l2 `& ]( M* e
static OBJ_CLASS memPartClass;
`( ~5 @7 N8 Z1 X# l) {) ]0 e6 b CLASS_ID memPartClassId = &memPartClass;5 U( M0 ?( p0 e3 Q
n1 D3 C K& P% L
static PARTITION memSysPartition;" @( K- [0 H I
PART_ID memSysPartId = &memSysPartition;
% q; C y) e& w' R U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
4 C7 x' @$ D+ }6 Z( y$ F
' j) _. L6 j% f static SEMAPHORE semMemSysPartition;7 X! `) l% u" i' R0 R" j0 q# l
- Y, f! C @! T9 f+ a static void memPartSemInit(PART_ID partId);, D0 p) f. u9 h; l. |% _
) G8 ?6 S) l# f! C9 x. }" L FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;2 P( X- L2 f& B3 X
, f( i- c* W* D& e0 K
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;+ y% m7 |: A0 Z
1 F0 i4 F# z/ i; s! t& S1 G/ W static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);( m& f& L$ U1 a* s: m
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
! X& y) y7 l, [& ?6 ]; P7 S0 E , FAST BLOCK_HDR* pHdr
' e$ ]4 V7 u3 N9 T , FAST unsigned nWords2 H1 f2 |( R; X: F+ |# J+ }. q
, unsigned minWords( n8 p4 b3 I$ k
, unsigned align);
$ W% L6 D) D9 `" ~/ Y3 w4 i/ c& y
0 R. Z4 \3 O- ~" S4 Q& c4 q static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
' ]2 E' g a; k. R : X9 M! ~ O- \! B( d
STATUS memPartLibInit(char* pPool, unsigned poolSize)
1 O/ ^5 u0 x$ J7 p1 M4 q {
- z" x! r1 Z C H% ` if((!memPartLibInstalled) && ! c! R5 }5 g) }2 h* h- u# R
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)5 B V `0 b* O M
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))1 y/ q' e5 w) F' u; g7 z6 ?8 k2 y
{
* b H. [' C* s6 p5 t memPartInit(&memSysPartition, pPool, poolSize);
% }% a1 |3 X- |1 e% _, E$ M memPartLibInstalled = TRUE;
1 f: ?: S5 \2 \, a/ A: A }
8 q' j3 I8 i [+ Z8 v * r4 t/ M3 p' U6 h- V9 X; J
return ((memPartLibInstalled)? OK : ERROR);
( c$ \ ]) R, Y }9 K2 o! P# y# {) q2 b+ B
/ f8 b: ^& p4 X7 q$ b, B
PART_ID memPartCreate(char* pPool, unsigned poolSize)
/ }- E+ D( h7 H' F5 O: Z* U0 ~ {, G2 o7 _/ ~9 [% }/ r! c# M
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
" n. m. _: u* N' q6 j
( R8 p/ O. c9 u: t# y if(NULL != pPart)" Z1 P/ X$ S0 c( V" A6 h3 l
{" s7 J2 |' |9 ~, \8 l. e; e- |
memPartInit(pPart, pPool, poolSize);
. A( L; t" P% q0 \+ c8 O6 d }
1 [- \, c9 S) O3 g) Y; ^
. m7 M0 s% L5 q$ a# X& v5 y return pPart;& n x4 q- I# T1 u
}& H( [: i+ ^6 R9 ?4 o W5 }! F- u
+ m1 ?0 O+ E; C; F; q void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)- _% B( z# T ^/ x- F `
{
- r* |5 V# e* }* V- e memset((void*)partId, 0, sizeof(*partId));
8 M6 v$ Z3 M! b# d2 n * o- _7 L3 F) x8 R: p
partId->options = memPartDefaultOption;
2 h/ m1 V q; i. I partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */ p1 C) J# E0 b- b: a6 B" k
4 r o0 i& e/ a" B" Q% ^( r (* memPartSemInitRtn) (partId);
2 y% a( m0 u7 z/ I; Q- K5 ]% S; A
6 o% c; k; r# t+ t4 {7 h( W' P& i dllInit(&partId->freeList);1 m+ z0 q# h5 e: W( h% V
' i+ z% p5 d- A' n. F& D3 m objCoreInit(&partId->objCore, memPartClassId);
5 R% `; \ A- z+ l, x
, \7 d6 ]. C; \7 P. j( | memPartAddToPool(partId, pPool, poolSize);
, R& A: B1 b8 ] }4 W% R+ @. L* c! M5 W
' J5 Z% K- o& h; w
STATUS memPartDestroy(PART_ID partId)7 c! E _% }1 {& T4 Z
{
+ J ?" C% x2 m) s8 Q return (ERROR);
. t' E) n" r+ [; U6 V/ x }0 W7 z! f5 `4 c7 {
* M8 @2 V) m; K7 B9 L void memAddToPool(FAST char *pPool, FAST unsigned poolSize)6 P) b0 X4 ~$ [' S4 m* s2 r3 b, X
{
1 w$ i' T6 q0 C; A (void)memPartAddToPool(&memSysPartition, pPool, poolSize);9 l3 i. w2 q; ~( ~: Q+ r0 Z
}
! j: }* y* I: _' d
: I2 ~' [$ i" Q' I8 u5 o2 E
$ E- h" v' h w+ c! T4 J. ~9 ~ static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
7 X8 K8 {& Z; r" z1 \+ ~2 `7 `: u {
, ^( D4 ]5 I3 b0 I' k# o BLOCK_HDR* pHdrStart;" W7 y1 L, J1 x f! D
BLOCK_HDR* pHdrMid;! E6 a2 C2 Z/ H/ d; z0 s
BLOCK_HDR* pHdrEnd;; ?8 S2 x5 f- D/ u
char* tmp;
( B$ w5 f" }5 f' {9 }# t int reducePool;
# e7 ]8 x5 ?! [2 ^9 c. I0 G ; e, ]% h" Q9 E6 V( i$ K" p) a
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
0 |2 O- \& v ~% h4 z {0 D+ A1 w5 u, k1 ?1 v
return (ERROR);
, N: g% U: I+ `% @4 N% r2 i* P9 R; W }& B5 D ~% b- b# S) Q
% L0 @7 P% h4 d1 m. e1 m+ `
tmp = (char*) MEM_ROUND_UP(pPool);
: M7 y8 \4 T W reducePool = tmp - pPool;+ Z& l. T T2 l9 J+ d2 Y
a+ X5 d; k4 e$ A) }; d% J
/* adjust the lenght */: \# j0 X0 V( }- B* S6 n
if(poolSize >= reducePool)- A# P, ]- a) G6 V" R
{
' A# v' i, k$ r0 b# S4 f3 B poolSize -= reducePool;1 }. f# a1 s6 b. g4 J+ q8 R3 z
}
/ ]$ {$ p6 H5 s8 s* k else
' l, m; J3 o8 s6 d2 t3 l {
2 a9 W" m$ a( W8 a poolSize = 0;; o# f$ `: ?2 m0 ~
} y2 g6 K% e8 o/ w0 Y' p
pPool = tmp;. @1 q' O5 \$ s$ b
! P3 {) A% x; n: {* [ poolSize = MEM_ROUND_DOWN(poolSize);
- O+ f7 \1 b/ h
4 u% T- K/ n4 ~) [ /* at least one valid free block and three header blocks */- R; ` o/ x4 `
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)3 h0 \3 j8 d% [0 R9 P
{* @, e7 Q h( L& e
return (ERROR);9 x7 p- r7 M0 J1 z* n, O8 s" e
}+ i8 B. t7 j G+ _3 g' _1 }
7 C+ l/ K9 a* k, l n1 }. |: x
/* initialize three blocks */
. z8 I9 H% i( n" ]0 i1 m3 k pHdrStart = (BLOCK_HDR*)pPool;
- _- l9 i/ x1 W' V1 J: | pHdrStart->prevHdr = NULL;3 ^, Q+ |5 [/ b% c: U7 l e
pHdrStart->free = FALSE; /* never in use */
) U s# o' j0 N5 j+ Z pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;( H. _+ F4 r( O; [
" S) @2 A% v7 N p; ]5 M
pHdrMid = NEXT_HDR(pHdrStart);
( L# H6 u2 ~: D# H( V) d pHdrMid->prevHdr = pHdrStart;* Y4 J, ]+ O6 q) X
pHdrMid->free = TRUE; /* the main block */
; H" R/ K _2 r/ K3 ?& k pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;. X- \% m, j' l6 p4 p
5 f$ B X7 N+ c r( e) T pHdrEnd = NEXT_HDR(pHdrMid);1 n3 ^; p" o4 L7 W. g, a3 {/ L4 _
pHdrEnd->prevHdr = pHdrMid;
+ C. k3 A1 E! m! P pHdrEnd->free = FALSE;1 ~6 k1 o3 x3 e8 m+ T& a0 W
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
7 [4 h2 I; A* f3 r ! `. J- ?1 N( h2 y' O8 o0 J: a. X
/* TODO take sem hear */- s; D$ `" Z1 T @" x" B; `
semTake(partId->semPartId, WAIT_FOREVER);; g/ w& h1 V8 t. ~* x
6 b$ z4 t0 Y3 r( l' z9 F4 G* }, n* _
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));" T/ X/ i& \& _! X& K7 }2 N
partId->totalWords += (poolSize >> 1);7 R! O3 }5 v* B; e) n
0 w6 p/ y, _, R& ` /* TODO give sem hear */1 ]& q# Q' U" \# k
semGive(partId->semPartId);, h- J8 Z9 ~1 l X
6 A- m, B x7 q. M) J9 s! H. W
$ c0 a7 j9 n0 u0 y! K+ m4 M
return (OK);# {, U9 Q: l3 d# Q& l; Y
}
. W, X$ |: W+ i: L. [
; f8 ]8 }4 o4 p1 x# q% d& V void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)4 C( ?* \5 Q: p7 U( ~' ^# p5 O
{3 V* c# J! S5 N( H
FAST unsigned nWords;
$ J, \" P4 ~+ I _ FAST unsigned nWordsExtra;
- ]2 z* C; g1 d FAST DL_NODE* pNode;
4 H& n0 Z) ?/ r FAST BLOCK_HDR* pHdr;
3 u3 D% n: ^% C0 b1 J' m BLOCK_HDR* pNewHdr;7 ~( J' v- R' F& n0 }) S( |
BLOCK_HDR* origpHdr;# d7 w1 H% n: @; [: P
4 ^: r7 D; h' [3 a2 |, [4 q, H9 w if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
9 K2 P7 L0 M: m: p0 n( Q( X. Q) Y {: B& s, W8 F/ V- H) z" s$ d
return (NULL);
, y# k' a$ V9 c) Z4 [5 z; }% Z }3 o3 k+ c% i) u) G0 l/ P, D7 q
5 P) F# D9 T, Z4 z nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
1 ^- @2 V% ]6 X* u , F7 C9 d3 |; m6 B
if((nWords<<1) < nBytes)
I6 g! g. x4 v+ n4 z" { {- ~% g8 R# |7 r# J/ W
/* TODO suspend the task */7 m% f% Z: U% i& D! q- a
return (NULL);: z+ L) o. r3 t! L
}/ k5 s- O4 K# I
2 r8 I7 l; ^9 g. t& a7 u if(nWords < partId->minBlockWords)0 c) ^2 e0 @% f! Z$ H' |4 B8 H) U. x
{
5 A4 l7 E' C- V nWords = partId->minBlockWords;
6 d4 b( ?# f5 Z$ C( B. Y0 x }
& D$ r( z4 E! D+ b) ]
3 v0 s' j+ E" o /* TODO task the semaphore hear */
$ M' [2 ~' w% c9 w# l semTake(partId->semPartId, WAIT_FOREVER);9 J; Y5 O9 f+ l! Z
pNode = DLL_FIRST(&partId->freeList);
' S& Q! `3 n4 ~ nWordsExtra = nWords + align/2; /* why? */
; t+ l) o2 G5 U5 J4 x) I ) X$ Q& f; L' i7 U! T) ^) v
for(;;)
& @0 `& A' [0 o {
$ X M b) ~) c' n while(NULL != pNode), a. ~2 ]" |/ f; s/ ]3 y
{
; k& S% N# l3 ~ n8 [* f) J if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||+ S( O" A+ S4 R8 m& y+ F
((NODE_TO_HDR(pNode)->nWords == nWords) && # B2 K7 X) ? a
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))/ {$ C8 i* Z: U) s* N
{
7 M- _& n) f* e5 @, E: t! R' l0 I- X break;
9 u& ]8 r9 K$ w. h* w }
! s) E- u. r5 _" k8 D 6 X9 E/ R) ~# ?
pNode = DLL_NEXT(pNode);
5 H6 {2 C f- { }
`2 o& u- C* ~# |; P. l3 p- O 7 J I$ w3 }% T& d, }2 j: I
if(NULL == pNode)/ e4 S: T# Q5 q2 t2 W ~! L# Y
{
1 b. L8 q! x* T1 q /*TODO give the semaphore */
- h9 ~7 |5 [2 D5 l( l semGive(partId->semPartId);' ~7 P, G9 T& p, A
return NULL;6 C! O! M, c' ]$ l# `& ~
}3 I: N3 P4 Q. y1 `" h3 V
- m. d2 K4 U4 J8 p1 n& I1 w& y
pHdr = NODE_TO_HDR(pNode);( e# i# u3 `$ W
origpHdr = pHdr;& u0 y6 v4 f, H4 h- C
: x4 X6 v* a7 y% V pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
, r5 z; j- ?! R: \2 _( T if(NULL != pNewHdr)
1 v3 B& x5 [- V1 j1 n( {4 \/ e1 N {
# n& e& J* @3 s pHdr = pNewHdr;
4 x s, N) m" q" G+ \5 ^% l# b, b2 Q break;
$ I5 D) Y2 {; y" [, v. G x } y0 V; P* y. S( h% F* d
. }' ~: l6 X" t9 p* f, Q3 o+ _ pNode = DLL_NEXT(pNode);
. R8 u5 |' w$ F" [' i+ f6 I }% Z7 ?) L0 N. X9 T/ v& g
% `; h5 [+ Q* l0 E* s
pHdr->free = FALSE;
& t" `0 _. T3 Q8 @8 O partId->allBlocksAlloc++;& Q( c! X9 K# a# P) s
partId->allWordsAlloc += pHdr->nWords;: l5 W3 z5 D, B1 i! u8 Q
partId->curBlocksAlloc++;0 O# q) E, L9 t0 E& d3 w d
partId->curWordsAlloc += pHdr->nWords;0 i/ l2 H3 J5 }9 z/ M0 a
0 O, F d: `/ J /*TODO give the semaphore hear */
. _3 g. N9 _6 p semGive(partId->semPartId);
) `/ z5 N+ @. y- u6 l. ~ return (HDR_TO_BLOCK(pHdr));
) A/ ?0 h0 c& _# r; S
2 {# x6 q; k1 x$ \! C9 E$ M/ E( y+ P }
& {. }* R. L3 f5 o' n 5 R" B: t* H# s- C1 L
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
% Z" }/ o& m" t) b+ K {
[- T/ w0 a2 V! C. z return memPartAllignedAlloc(partId, bytes, memDefaultAlign);4 d( |, N- @8 y L
}
3 Q) D. w+ z5 _" b9 g " j; h& }0 q. |" m, E3 p& D
STATUS memPartFree(PART_ID partId, char* pBlock)
5 ^* f; M) a" _. _" F1 E {
# a% ?& h% p' k9 |7 Z3 c9 d) O# l: V FAST BLOCK_HDR *pHdr;; a9 F& x- C0 d
FAST unsigned nWords;
/ N% E, I. {! w FAST BLOCK_HDR *pNextHdr;" G/ z# g* m7 t8 D
* i8 s3 Y( F9 V2 W6 S9 `% J( l" p
if(!IS_CLASS(partId, memPartClassId))
6 L n" O% m% K: X5 _ {3 R" A" x+ z/ K
return (ERROR);
9 `* y1 c& j3 p& j }5 X8 D" {# j1 v
c& U+ Q7 p. P4 E7 I if(NULL == pBlock)& {2 c$ e ]+ u7 H- j
{
% c+ L3 G' L# Y; P; G return (OK);
/ a& G7 p. r- k( \/ R& M }
, W1 D1 v, S+ B: _ 7 M- U$ w8 L9 w# v" B+ e3 ]% Y
pHdr = BLOCK_TO_HDR(pBlock);
. D5 R2 }& R3 Y& ~- `7 c0 R8 }& R |. x
+ d. d3 y. g- ?! T& Y( |. t* A1 A semTake(partId->semPartId, WAIT_FOREVER);
+ j4 u& } l: {( e; `
; \% {& s/ _5 Z" T) \ if((partId->options & MEM_BLOCK_CHECK)5 `5 M8 b& v* i7 ~+ ?( ~
&& !memPartBlockIsValid(partId, pHdr, FALSE))
1 b: @$ {. U. r {! ]( B0 }5 `9 n! g: S. y$ F
semGive(partId->semPartId);$ k, x& R9 u+ a. \9 ~
return (ERROR);; F+ R# }7 G8 e8 m# e f
}
% `1 J) t' n a' T5 w 6 o; u3 U# D/ e$ U0 S0 K0 q
nWords = pHdr->nWords;
# M2 U, S# _; X1 C" f9 D if(PREV_HDR(pHdr)->free)
1 b' z; E% p7 S0 K* E {/* the prev hdr is free and than coalesce with it */4 i4 A, [* d( ^$ [; l' y7 z
pHdr->free = FALSE;
) y& U2 I0 d) G2 W* L2 A3 W! }! _ pHdr = PREV_HDR(pHdr);) F& l- R% r9 p, h
pHdr->nWords += nWords;
0 b" c, L5 [$ ^' X } e. {& _* n4 u2 Q8 W( A2 L7 H
else) F* C' q9 f. H z
{0 A' c( V3 d) w" @0 h
pHdr->free = TRUE;1 D" O) |' e9 U0 ~- c
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
$ g5 q. L5 n- p* N) z' j }
* x7 x% H! `+ U+ i + p! p0 w, {4 {
/* check to coalesce with the next */
+ x, i/ {1 X- K6 K$ y& t pNextHdr = NEXT_HDR(pHdr);1 @: d5 F* B6 c, o5 B
if(pNextHdr->free)
& K) D! v* i: {; Z {, G. I$ }8 x4 R) x
pHdr->nWords += pNextHdr->nWords;
# F3 p0 I3 j( a4 Q9 i dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));7 Z- P9 V9 A& z' n9 K
}
* I! T- L, w* M# o$ S1 G( [8 O% q 3 [# D1 T/ Z4 f9 v5 E# k+ ^) Z3 H q
/* cannot use pNextHdr->prevHdr=pHdr hear */
: [% Z( |$ m# _4 d l* B. ` NEXT_HDR(pHdr)->prevHdr = pHdr;5 [6 H$ ^5 z$ e' p7 z
T7 i( ?' w% r0 G, x3 U
partId->curBlocksAlloc--;5 _7 \. E8 Q9 a$ u3 u( I
partId->curWordsAlloc -= nWords;6 l! E5 W Z1 M0 q" |6 d8 c% u
8 M* m' } p9 d /* TODO give sem hear */
4 k2 I' P: E) R4 w3 K. C' f1 E semGive(partId->semPartId);5 Z Y+ J3 k; I; @* ` y
+ w4 u5 d; o5 V) n return (OK);
( U8 U, \) e1 H! K }
: ]( S( o. t- ^% s! J* C$ u5 f* o - ^* M8 @0 \$ O! a+ `
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
7 n9 r6 X4 _5 U/ p- n0 A {
5 C$ [0 p+ U% a9 c+ u8 z BOOL valid;, Y1 ?3 L4 l1 G' ]0 M' ]" x
# R9 a; d% S) r a6 O
TASK_LOCK();4 C" s) ^6 f- U q
semGive(partId->semPartId);
7 ]0 Q: |9 k* Q& p' s5 ^
- L/ w/ I1 t# }& D valid = MEM_ALIGNED(pHdr)
& x$ X" m+ v/ m) d+ H# Y && MEM_ALIGNED(pHdr->nWords*2)
/ |) G3 O8 w9 M F9 I9 `7 d && (pHdr->nWords < partId->totalWords) ' r3 C& D& j( B
&& (pHdr->free == isFree)
; G% `$ W1 X8 g- V) l && (pHdr == PREV_HDR(NEXT_HDR(pHdr))): X4 r4 a" k! c
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
- C$ k, T; q3 l4 d0 H7 W
5 F6 F3 O' p9 F2 z N, L1 T semTake(partId->semPartId, WAIT_FOREVER);0 O% _& H0 i# |& ^5 h
TASK_UNLOCK();3 y2 z9 L0 w! x- s$ ~
2 g) S, C6 x; B) v; u
return valid;
# i* h! I- `- \% T* L- @ T }* |3 z: q0 j5 t# i. @
& Y4 B9 e, y3 j* q3 p
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
1 J/ f7 V9 v3 B9 P/ g/ o , FAST BLOCK_HDR* pHdr
. I, [9 n/ M; C6 O! P1 ] , FAST unsigned nWords: ^$ m" D1 _6 c$ A
, unsigned minWords
* R' X! l: d. D U# } , unsigned align)+ a. f" [8 W6 Z; x3 Q' i
{
: ? `/ k. M8 f% P' k8 Z FAST BLOCK_HDR *pNewHdr;/ L( @& a+ H `- Z f7 h
FAST BLOCK_HDR *pNextHdr;
+ j1 K" Q8 d9 Q, s/ P FAST char *endOfBlock;
0 P) v' t. V, S( y' D FAST char *pNewBlock;3 s( h/ F( t5 P
int blockSize;
+ ^4 a8 K3 V1 v" y- l , x1 q, \# r8 e1 ?6 Y
endOfBlock = (char*)pHdr + (pHdr->nWords*2);8 S: ~8 A* F2 @0 a; t" Z1 L3 v
3 B9 B1 \* \8 ]0 R
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));2 K! k# k9 l3 s& g) r) a1 M( l. V
$ u4 U7 w+ O. [ h3 A$ q
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));/ B \1 l0 B$ p0 ~1 y
3 {" `% ~3 @" u: L7 \ pNewHdr = BLOCK_TO_HDR(pNewBlock);
2 f- i; L/ }# g( _
' t5 m% n( i: t, q$ I8 \ blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
$ N3 r5 h o5 ~0 S + K/ G4 P+ @1 V0 S- J8 L6 A
if(blockSize < minWords)
3 k, v1 d4 P7 A/ F# c. \ {: S! i9 ` B; X- T( a
if(pNewHdr == pHdr)) s5 Q/ \0 b+ m8 ^9 o8 n2 N$ V: [
{; d+ c" {% G4 g4 `) [& o% S
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
: I+ Z( s/ r; |! X5 W( F }# i5 H0 P. i$ s2 I
else
' I/ Q/ M6 k- ?2 ?- v7 f {
% o, z. H" }6 ^, H2 p return NULL;" o V' o3 S$ o5 R. L' X
}/ U! T& r) B* q8 H2 _
}
6 i q, K- ]" A% F# a else& U, I8 H, v! d7 ?4 @2 B
{ /* recaculate pHdr */. h$ B; p0 }4 ~, R8 N2 ]
pNewHdr->prevHdr = pHdr;
+ g5 l1 M) k7 d# }& E# r( t6 E i pHdr->nWords = blockSize;
6 p- R) U. x5 V/ F) \/ I }
4 I" w1 F1 }$ Z- }5 n 1 Q- Q- b: V" {4 A5 |2 S: H' C
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)): y7 Z! v8 t9 r
{
; m- P5 u# p" V' i+ ?. v pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
0 Q& m z* ?$ z! z" } pNewHdr->free = TRUE;
( J( Z, {/ @# f) H6 B5 F8 Z * w7 A. k( C( Z7 G! P% u& q
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;8 g$ L3 C* t' j" F: T5 M9 C3 @+ W& j7 I
}
4 v: d- U# U; J/ E6 \, _5 b, E else) ^, Y/ j% o5 J0 i6 f U
{/* space left is enough to be a fragment on the free list then */
7 W- L# f L+ p0 h9 |) G pNewHdr->nWords = nWords;" u, h& o, g5 I) N/ A
pNewHdr->free = TRUE;% J0 w9 T! E7 h2 S7 v% ?. `% w) c4 ~
8 `% T7 @. {1 }( L6 z$ y! ?: d6 L& Y pNextHdr = NEXT_HDR(pNewHdr);1 e4 D2 |4 V8 }2 ` E" |
/* words 包括BlockHdr */4 y3 W- k: S# ]
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;7 H# E. f% P) |- [6 V, Z
pNextHdr->prevHdr = pNewHdr;% `2 K* x( d1 m
pNextHdr->free = TRUE;0 ]9 H5 G% l; R% H4 ^- E
! f9 q1 j" F2 q7 E
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
8 V+ z0 ` V) @. m: b 2 k/ H6 J! @3 w0 W* U- w$ d8 x8 G5 @3 B
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;+ K: G0 Y1 G6 |/ x% s% H E
}
$ x& l& @% Y) z% J. D1 i! d; @
" j4 Q( y. v$ W l* i( L, U& i4 O return (pNewHdr);8 [) f: f4 d1 [; k V
}
# E E- [0 K } : K2 y% D( b' A2 y' b) `
static void memPartSemInit(PART_ID partId)+ R! V% d4 H9 ?+ ^. a
{; J/ c, y6 s; ?& G
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);9 E$ @( C" }2 a. d- z: y
# j5 F6 X& H5 x3 ?2 l" s: I partId->semPartId = &semMemSysPartition;
' X0 w& |1 R4 C7 Y }4 p2 `& k& d& o+ r4 G# ^4 x% w
( I. K6 w) B% ~1 _8 c4 V) u void* malloc(unsigned bytes)7 `. D; d8 R' L/ E3 r
{
$ W2 k! i. a& A5 t: E3 p return memPartAlloc(memSysPartId, bytes);
2 r) `$ b/ n4 h8 x; S }, l7 e' `# [1 S4 \$ c, x+ Y
# G3 P( t& c2 w7 Z& B, U% O' }; l void free(void* p)- Q2 h% r5 t8 @! _
{9 p4 d8 ?7 f$ v8 z- V0 {7 d( ^
memPartFree(memSysPartId, (char*)p);; n4 G: [8 W- a/ M# l
}
X. d+ C' u4 y9 S
zan