8 Q0 H( }7 ^3 ^8 E7 y#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))0 u n5 i: ^9 B( e a9 E
#define PREV_HDR(pHdr) ((pHdr)->prevHdr)8 T8 E, Y5 u3 T6 u, Q
6 _5 |7 z& r8 m6 E
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))) _1 u* y- N9 B7 T* {
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \ ) B' o2 z1 I: M* K7 H sizeof(BLOCK_HDR)))0 m6 p- D) k& E- S+ ~4 g) o
& }6 Q" @; a! f; E#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node) ) b {8 C' x- q5 u#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \ : H0 o4 d% ?% F3 z OFFSET (FREE_BLOCK, node)))3 ~5 a/ a, k8 i+ i
6 a7 ?6 q- I) S* L2 c$ Y& L+ [' hstatic BOOL memPartLibInstalled = FALSE; 3 Y8 e7 Q* T4 h* I3 p 5 B, I B9 h& G$ Istatic OBJ_CLASS memPartClass;# L/ @$ s* K' d2 i5 u7 A
CLASS_ID memPartClassId = &memPartClass; t! { ]1 U" J# m9 {% B% Z9 _1 F9 k/ q5 w- C, v
static PARTITION memSysPartition;9 ?% f; v- Z; V" ?* X
PART_ID memSysPartId = &memSysPartition; $ m% G3 L0 u) U% hU32 memDefaultAlign = _ALLOC_ALIGN_SIZE; ! ?4 v3 o) j, Y x. P 1 m3 L1 @! D$ q h- ]; S2 i/ \static SEMAPHORE semMemSysPartition;- K5 I7 f; \0 x& B8 ]0 j
( n3 n& }/ I* z
static void memPartSemInit(PART_ID partId);* v- P$ G M% O& I1 m( B
/ D. U! F# k' T
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;7 G" j, J# w; F, U: Y& z; [: E
$ s) ~( u, j0 }6 `) ]. H3 y5 H: K
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;. Z' u1 i6 b4 C/ k/ o
8 w( }8 R$ H, w3 X9 {" e) R" Z
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);7 [8 c/ H) i! X
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId- L4 d$ l4 j7 y8 }
, FAST BLOCK_HDR* pHdr , \* P$ e. y" S* t/ ]9 L , FAST unsigned nWords 1 q+ }8 b7 F$ A3 _1 u# | , unsigned minWords : a I( v9 o9 F/ ]* S4 g; n0 g , unsigned align); 7 Q/ B' L) J* g; [: ~4 h/ s. r7 N8 A+ p# l2 g
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize); 0 q1 J+ S7 m ?$ J+ s6 K; S 8 F8 S3 v: S, F7 D+ h# w, F; aSTATUS memPartLibInit(char* pPool, unsigned poolSize)' i2 F% I# k% W! i( D; F: u
{ 1 B& l9 r) ^* Q) p$ L if((!memPartLibInstalled) && 0 T4 k' l* s9 d1 L' G5 v0 A6 I
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)- L, g: q9 d: x3 A) a0 M
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy))) # ]0 z$ L' _" h1 ^/ y {& s* b4 ?: J8 V8 W
memPartInit(&memSysPartition, pPool, poolSize);! _6 g6 h! O. }
memPartLibInstalled = TRUE;, U& k0 ]- t9 {" p3 |" g/ u+ K. j
} ; V/ \4 `4 p' j! W a( j+ U- h5 s' Z! y5 [2 }7 |
return ((memPartLibInstalled)? OK : ERROR);# O# O+ ?2 e u0 A) N) i
}5 n. G" @1 [- O8 M* z, V8 A# _
+ U3 J) c2 s; J! gPART_ID memPartCreate(char* pPool, unsigned poolSize)7 Q' u& j5 f. V. S
{7 J. I6 y$ `$ ^8 S4 p' }
PART_ID pPart = (PART_ID)objAlloc(memPartClassId); : W0 b- c+ `0 ` : |, N! y! Q7 m; c+ [9 {' r if(NULL != pPart) / a |8 K" O: y% j; B* ? { ) \3 }' }, ?* A+ \" Z, @) w3 u' q! b, M memPartInit(pPart, pPool, poolSize);, W9 l- |- F6 b, F
} # L$ L# @' H% n ; g+ q" [+ y- J F1 B return pPart;7 _. M( x* {" E% ]* q) I
}9 S5 M4 i9 H( D& _: Z( w
: n( s9 j$ X1 g! f% ? rvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)( J L7 A6 |& L7 e5 m
{2 E: D0 c" t; @; B
memset((void*)partId, 0, sizeof(*partId));* g& c! @" E b
5 c& g+ K* Y$ A4 {* ` partId->options = memPartDefaultOption;) |, Z- o1 @ u2 n$ h" g' Z
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */ ; x6 h4 L2 r- t8 f* f % j3 ~5 n8 M$ X- b3 L (* memPartSemInitRtn) (partId); $ \/ x( s4 ^* l$ u4 r4 s 4 G- `) }3 H& E: ` dllInit(&partId->freeList);& t$ h% W! y `, P4 D O) U) a2 ^8 W
1 b8 X ^# j/ U% f
objCoreInit(&partId->objCore, memPartClassId); 2 I3 o$ U0 H3 |( o& F 5 e+ ^9 V7 q$ U1 p) a memPartAddToPool(partId, pPool, poolSize); , q( ?" H# w+ H9 n} # u; E, i5 i* |# k ' Q8 |4 K2 H: c0 o% d9 ?$ k% YSTATUS memPartDestroy(PART_ID partId)! {; X' `9 e9 o; v# }* s8 a, D {( Z
{6 c( ^ n" L- ]/ x4 d
return (ERROR);2 K: k+ o$ |% p7 b* O9 \) |
} ' y6 n! M6 H* {' t9 ` / l$ J/ O0 X$ ?. M2 n2 |7 F1 gvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)' W8 B; O( k3 y' q/ x ^
{9 f" q: i( Z" L A2 N1 h
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);$ N1 q, A. u' n3 X y K$ c' J) z- @
} . C! R/ a' f- j* J 7 k" e; b+ x0 }' z' g b6 j1 b, p8 bstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize). y8 {6 p! h" A- u. M) c
{ & c: v3 w% s) |% A2 W o BLOCK_HDR* pHdrStart; / E: { o0 P+ ^# |) h9 B4 Z BLOCK_HDR* pHdrMid; 2 R4 o' `4 d7 e. l" ~& P0 x5 o# B BLOCK_HDR* pHdrEnd; 3 {4 L7 a) h3 K6 U. {" G char* tmp;$ N }, T& b4 M( X$ O
int reducePool; u5 S7 k, H0 T: Q5 C2 J2 L6 P$ z! k5 Y5 ~2 X0 s2 c% N
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ ! J) _9 e1 b+ i }3 Z {& @" D" S# l# j5 V
return (ERROR); 8 v6 ] g& x! s0 ` } ! w& e+ z! [8 ]' G/ v * s9 ~4 {# x9 b5 k' H B$ G tmp = (char*) MEM_ROUND_UP(pPool); $ Z; p. ]+ i) k2 P5 N" }3 M% |- b reducePool = tmp - pPool; 5 j% Z5 p9 ?- d) F8 N2 s/ a" H0 V$ v' ]" q
/* adjust the lenght */) A0 A; Z9 y1 Z* J( @3 ?
if(poolSize >= reducePool)% ]% p% K7 R ^: }% c( T8 X6 ^
{2 Q- T% P- S k7 o2 A$ Q
poolSize -= reducePool; 5 o. j8 b, D' j3 b6 z }0 u& h: Y; G6 A& X( c- c
else 7 e" @& M# r: c' [3 c& u {. i5 J2 t' w; i/ y
poolSize = 0; - k: u% L+ B& y } 9 a0 P' a9 O6 j2 c6 v pPool = tmp; 6 n9 ?( C. Y: a ! I( i( S- X8 A N2 i7 r% X
poolSize = MEM_ROUND_DOWN(poolSize);. ^7 y0 h- @6 t; |
) ~+ m2 e* M# m7 o /* at least one valid free block and three header blocks */% k0 Q* ]- K ~* z% f! s
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) 1 S) q& A$ U) [8 U7 x {5 X) E0 Q) Y3 R6 W! u# Z
return (ERROR);5 S% h" R7 C# o0 \' w
}: H7 `0 Z7 ^+ x/ V# v( ~, N- p
r8 p- W( _. e& V1 r /* initialize three blocks */ ) [4 J5 {# l; U3 ^' i6 F# D7 y pHdrStart = (BLOCK_HDR*)pPool; % l. o3 D. ?% I' N. Z, Q! ~1 P9 t pHdrStart->prevHdr = NULL; # S4 ]- \; [' L4 c pHdrStart->free = FALSE; /* never in use */ # X& L1 d- S% M O; } pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; - N& ?2 m- X3 g6 K2 f* G. u# F! V0 I% V2 z9 U. v ?
pHdrMid = NEXT_HDR(pHdrStart); 5 v! s' e/ o E pHdrMid->prevHdr = pHdrStart;' j2 n# h9 g5 }# K' |& m
pHdrMid->free = TRUE; /* the main block */8 L( r' I( Z4 n% p6 U: u6 n
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;/ u4 p9 R! i+ ]7 p* C7 t1 I6 B
9 N% f$ p w4 @( V pHdrEnd = NEXT_HDR(pHdrMid);) z) g& h$ K7 f N U- F
pHdrEnd->prevHdr = pHdrMid;, H+ V) R- p4 X/ C
pHdrEnd->free = FALSE; ; s+ l5 z- ~9 J* j4 d) R- f) r, | pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;8 o" r& e2 r3 o# z
! p, {* a% n3 M: t4 p7 {+ N
/* TODO take sem hear */3 D/ f- Z% g% c4 b* m8 k( k% X
semTake(partId->semPartId, WAIT_FOREVER); , w* V$ ], a" S) i) e ( t, Y) p9 l% j% y2 ~
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# p' f$ T& E, p; m. O* ?( A
partId->totalWords += (poolSize >> 1);3 _/ w+ v1 ?/ J7 d$ `- A0 U; ^
, V! {# \ H2 u: s& s9 s /* TODO give sem hear */* F! L' T1 w& ?7 {& N2 Y
semGive(partId->semPartId); 3 C5 U( ]+ b; _& u+ X$ E1 p- B9 }# { d' h" q
1 {3 h3 v0 ^! e6 U" ` return (OK);: z+ Q# P' D' P! K+ a$ X
} 3 l8 ?/ Q% e5 b: `+ x: A8 a) A" c9 o2 `, b$ f% l
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)- t' y6 {& r8 T- u9 @
{ + V+ ?# U8 v# q/ S/ Y8 j% ? FAST unsigned nWords;' d" s3 {! b0 k! Y# J; o- N( X; ?. H
FAST unsigned nWordsExtra; * ?$ t2 ~5 o0 Y4 k7 c: d9 O4 m8 a FAST DL_NODE* pNode;+ E, K+ I. y4 m
FAST BLOCK_HDR* pHdr; 7 [7 p' M9 P. L+ G4 B1 A* R BLOCK_HDR* pNewHdr; l7 v4 X4 w9 D
BLOCK_HDR* origpHdr; 9 v' I$ S9 `( a, w6 J6 @/ r) d; L( ]) J, U u
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function *// k/ g f0 S9 X1 x
{ 9 j7 x5 }5 v6 W8 Q return (NULL);. q2 y& ~$ v5 |" ~1 c- L8 @
} _4 f* k, o( R, D % [/ K8 J: @) U _& `1 b# c nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;- V0 B6 D8 V# ~1 G [# `
2 X# t4 W& h! A# B
if((nWords<<1) < nBytes) 5 x5 ] P. [0 Q( L {. d* [1 C" f' ~ }6 E" T1 @
/* TODO suspend the task */8 {: j1 P0 ~* R7 R* G: u5 C
return (NULL);( d3 p- n. B0 {4 }, e0 V
}" J. g8 H% m ]) _+ [9 S2 E
5 a, B! I) {6 o+ g: I if(nWords < partId->minBlockWords) # ?% }9 b8 p$ s7 ?5 o8 W# p { ) l5 {$ r7 d v nWords = partId->minBlockWords; 8 U9 c# k4 F" m, {$ ~9 @ } : d# k! F* \# E3 q & I7 d+ H+ K+ T( n* d9 T /* TODO task the semaphore hear */ # S/ p6 A7 ~. Y7 C0 J+ f* H( w7 o- t. O semTake(partId->semPartId, WAIT_FOREVER);% O4 {9 y( {3 L' e/ V% E' e
pNode = DLL_FIRST(&partId->freeList);8 S4 t2 A" J$ `" y8 D* j% e" o
nWordsExtra = nWords + align/2; /* why? */( @+ g0 b) q3 j& Y$ ^# _; S
" D4 j9 |; q1 ?& `6 V
for(;;)$ z W& L, E2 f/ O8 \( ?
{ 5 Y0 n+ Z, T8 a7 l while(NULL != pNode) q8 y- e% I9 @6 O" W {% @) w# e5 g2 e2 P4 v
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||2 M, k$ f k/ j- n- s" t
((NODE_TO_HDR(pNode)->nWords == nWords) && 6 b) H: r$ _# h2 C7 N4 M! ]/ Q
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))( a& c, N- V: A6 a: u
{- b5 f9 A! v Q- E2 v8 J/ G8 e
break; & E( S1 @- j/ b# T! v5 ~/ K } 3 n. @4 E1 G# I& T4 v% K& D' c0 g2 J: F; ^
pNode = DLL_NEXT(pNode); , ~1 a* T3 j5 \" K+ k# u9 ?/ E }# |3 t c* o: r
0 k' D" `6 j( r if(NULL == pNode) ' A3 Z% z5 n( K) L {3 C0 Z& L% w' d2 @9 m6 M
/*TODO give the semaphore */ 3 A5 ^) D+ X2 {% ^1 G* a6 w! m semGive(partId->semPartId); 5 E) t; ` u0 z/ B* I/ h* C return NULL; E+ c; C6 `/ f( O/ [
}8 s7 X6 q# N- d& G% X& Q
0 |- e5 ^% O$ k: [% X5 _: q' G pHdr = NODE_TO_HDR(pNode); ( |! A5 J% E ?+ t origpHdr = pHdr;6 T' h: \. S' U% {/ Y& x8 ]
8 K1 H: s; I4 F1 | W
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);# W8 f: v& P A5 o" w0 o+ }) X
if(NULL != pNewHdr) ; [0 d l& ?6 ^0 ~$ G { 1 Z( D& h0 F% Q& |' u pHdr = pNewHdr; : W7 q) @6 X- s break; ; M! ?1 p! `* Z) T3 k) j }3 z$ b. b1 x# Z# G1 N
+ L# ^6 @, T- F8 b$ F
pNode = DLL_NEXT(pNode); - |1 ?* y+ D6 q) K e } ; S* m; Q, C) C% Z1 L& G4 C1 v$ t0 o( f ' e+ o4 p6 Y3 X4 K pHdr->free = FALSE;5 m& w. D j" e, Q
partId->allBlocksAlloc++;/ t* \' y6 O* y. b+ F9 y( H; v
partId->allWordsAlloc += pHdr->nWords; ' P6 X+ ~( ~9 F" Y. d0 P: b partId->curBlocksAlloc++;% o" |6 o' W8 c# S+ k) r
partId->curWordsAlloc += pHdr->nWords; ( t! I0 [4 Z$ w' w4 t % S: a# T! D! _0 Q" I( e& ]3 j$ r /*TODO give the semaphore hear */; V7 x3 k2 Z7 G$ f3 m
semGive(partId->semPartId); h% ~9 C3 L+ A9 g return (HDR_TO_BLOCK(pHdr));9 ?; S2 o; T, |, z+ p
6 A, J, Q; B- b% U} # x% u/ I: S. } , h3 G/ i9 J$ Rvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes). w! r% h* q& a# z7 ^ _% G
{8 ?% B5 U! Z1 @- c( y
return memPartAllignedAlloc(partId, bytes, memDefaultAlign); 7 i/ f' Y0 c/ ~4 S. D+ v" n1 ~}4 y/ O; f, A( C0 e+ A* w5 n& ?
: C9 ^* W% ^' }' J
STATUS memPartFree(PART_ID partId, char* pBlock) + U7 i% r2 m% U+ P* K0 v{# p7 {8 l6 v7 W% X, w3 Y) K
FAST BLOCK_HDR *pHdr; - J0 r$ o' t1 L/ P8 o* F, g FAST unsigned nWords;) x g/ Q" e0 A" i/ ~
FAST BLOCK_HDR *pNextHdr;1 _1 f4 [% J7 s3 s
8 O5 ? M) X* m7 @ |% ^
if(!IS_CLASS(partId, memPartClassId))9 G S7 j& e z$ u& J7 H+ J
{; a) M0 L; K6 E0 \. R$ h* D
return (ERROR); ' }$ G$ g" O! J( h3 j4 i }' c3 Q3 C/ i1 l+ t
# U P+ [+ H# L" D if(NULL == pBlock)! w" X0 Y/ {* f
{ 2 L/ U W I4 H0 x return (OK); 7 C' P8 z( D+ K0 }3 [" x/ n } 9 R( \! \5 O, x N4 B5 }7 b6 B" M' M" |" f ~
pHdr = BLOCK_TO_HDR(pBlock);- [) G1 H/ N" ] D v. ]' v$ R5 B
$ }7 P# d6 u$ l9 h
semTake(partId->semPartId, WAIT_FOREVER);' G# S$ C2 F v H( b' _0 a1 Q2 I O
. n! P8 h% H5 |. v- l5 [6 N if((partId->options & MEM_BLOCK_CHECK) 9 |' d; y9 X5 K- @# O. h& z && !memPartBlockIsValid(partId, pHdr, FALSE)) 2 f! `) S1 p* O { 3 o+ z. |. I5 t/ g& q. g. y semGive(partId->semPartId);) D Y; q% n' e! R4 {! l
return (ERROR); % H7 A8 o7 m' u7 {: W3 _$ s } . D- g' A' Q& p- }& x, ^1 E # K% N% {6 Q* D- K! |) o nWords = pHdr->nWords; + P. E& O5 {5 T6 H, u g7 g$ u if(PREV_HDR(pHdr)->free) 9 m X5 H h5 f {/* the prev hdr is free and than coalesce with it */ % H" L% M' g' V pHdr->free = FALSE; $ L/ E; e. ] ^. F pHdr = PREV_HDR(pHdr);$ U! C, r& \& e3 p5 X4 b0 [
pHdr->nWords += nWords;! v5 @1 H1 n7 T9 z$ V
}$ m0 z. O1 L2 [* a+ S3 A7 u, X/ d
else) _, Z- u& |" K5 T8 r9 Y( M
{8 x$ N1 r& ?, M: c" P
pHdr->free = TRUE; . ^5 H4 E2 M; i v' b" E dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));: {' n) E! |5 T
}; X% G: w `% l) y: @
% C, v r2 K- G y/ Y# o3 C /* check to coalesce with the next */ $ }% U! a4 D% V2 V& y$ |( B/ D+ s) p pNextHdr = NEXT_HDR(pHdr);3 a* f6 W3 \; q7 u( W
if(pNextHdr->free)* u5 I, Y% s/ }1 V
{, k" e5 V3 i" i h; L" V
pHdr->nWords += pNextHdr->nWords; & x, I Y- ^3 V8 L7 g1 G dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));5 u* j$ ^$ }" n' o
}) ~/ ?6 E" F V9 V+ _8 K: R$ }+ I
# O6 s, _1 Q/ ]- z+ f
/* cannot use pNextHdr->prevHdr=pHdr hear */1 E a- W/ S c. i
NEXT_HDR(pHdr)->prevHdr = pHdr;5 g: g- H! H2 i9 T* }3 z8 P, A
0 O3 ^7 S* ]6 T partId->curBlocksAlloc--; ' J0 q, l, Q$ v, j partId->curWordsAlloc -= nWords;2 S# ]/ w9 _9 ?$ o" ~
7 I8 ?0 F8 [- k& O4 q5 [' o
/* TODO give sem hear */ & L F) W, I" h semGive(partId->semPartId); " Y( Z9 Y; {& o, f. E # A y6 h3 Y% O1 s# ^& K2 _; H
return (OK); . c" Q) z5 ^" ^4 r* H3 I0 C$ m} * H; \9 h0 K# F8 i ' Y: {: @1 m/ c, ]* p' r9 x2 Fstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)' C {# ~: m4 R* x7 |, F" j6 T
{ % n3 i+ Y* h5 f$ _; G/ c [ BOOL valid; " t0 |! e+ ] _ O9 b# ~( V! g0 g: v8 [+ q
TASK_LOCK(); |8 l$ a) Z- S" F) T% ~( o semGive(partId->semPartId);0 g9 _! P1 R" l9 R. z
# S' `/ q3 T" g+ t( y3 v; E
valid = MEM_ALIGNED(pHdr)8 Z! ]+ @" m( H' E
&& MEM_ALIGNED(pHdr->nWords*2) & K5 v# I+ h3 Q: c && (pHdr->nWords < partId->totalWords) 4 o9 C! {; P/ t5 _% { && (pHdr->free == isFree)$ |1 O4 n* ?; _6 W" M
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr))) . i/ E7 D5 d# F4 @) p && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));; `% D& c; y6 S, o5 `
1 [' k5 q- D7 G" R, L/ Q semTake(partId->semPartId, WAIT_FOREVER); n& a- ]* x4 ^" R& F0 L( O TASK_UNLOCK();0 _8 J2 [" O& d; o8 I6 A, U4 u ^- n+ h
* t0 T" J* J; K% s1 q2 o return valid;; J. `! J0 Y8 P
}# {7 C ]" h# L" T
1 [2 I$ O8 G8 t }# D" Mstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 V4 p( L- E/ ?
, FAST BLOCK_HDR* pHdr ) I$ s" E' O9 H7 h$ z , FAST unsigned nWords' r$ A- A, i ]
, unsigned minWords" H6 O+ S( m$ C" @
, unsigned align) " h) U M* T7 l( q; b% s; B2 s4 `{; g" f4 Z ~5 h5 N2 [: g8 S, ^
FAST BLOCK_HDR *pNewHdr;! m; p3 L* Y8 s9 B
FAST BLOCK_HDR *pNextHdr; 3 U: ?' G, b/ L2 [' w J FAST char *endOfBlock; 4 q" c0 q5 \3 E5 d- U FAST char *pNewBlock; 9 I# @0 x4 d, ?& C# F3 g int blockSize; 7 v- r/ _7 V1 w8 y) h/ q2 d 3 B- i; i5 _& p% r5 A2 C endOfBlock = (char*)pHdr + (pHdr->nWords*2);+ u6 X a3 C# V$ N) k" C1 \
5 i" ?8 v/ I. h, ~
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));' s% ?% {* _' V! [ F; @0 u2 B
6 ]0 I) f8 G: o% h
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));1 Z' h# y, o. S+ B- C$ k
, O8 m& n0 O ?" o
pNewHdr = BLOCK_TO_HDR(pNewBlock); ( O" r, v0 z7 P9 _# v% K8 n" H$ R" c9 t/ \# @
blockSize = ((char*)pNewHdr - (char*)pHdr)/2; : Z) k+ s+ l: f8 _+ R/ l# X* t$ N# y0 A# X4 D1 k* N' j8 t5 a: Q p
if(blockSize < minWords) 4 D0 L# l! `! j/ e% O { 3 h' l, ?: Y0 y; u" b if(pNewHdr == pHdr)* A3 c' H5 _" a) J5 g' z
{% Y4 B) X# j7 w/ g" N
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); - Q4 p- } j$ L } / }/ P# K6 J. f5 [ else 0 f; Z$ I6 ]6 w5 l9 a* t k+ o5 E. X {& M8 A: h" t* `% C
return NULL;* g, {; K4 @8 f
}; k, z5 _; ?4 f' S, T0 T% q
} . C- h2 K4 M% c' P2 ] else7 J- W0 N9 ^; y* z5 v# h
{ /* recaculate pHdr */ 4 t% Q& k- @8 S6 x2 Z7 e5 L- | pNewHdr->prevHdr = pHdr;4 z, H4 d- Y7 Q& n" p: @
pHdr->nWords = blockSize; $ W) Z5 ~; a3 z1 K9 _ }4 B& l Y. m* f, n
: L4 R, N- e N, V8 ]1 b1 F$ `) x if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)) : ]: m+ N+ ?2 A ]4 u6 R' n { 9 K. v* {* @, k* Y* n pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;0 E# n# v V' f; p/ R! C2 Q5 @, |
pNewHdr->free = TRUE; 6 P# e/ P0 o: y 4 b- u, J. g; z W2 g- z. T, z$ G9 h NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;8 G- W1 l. n$ ]; Z5 w
}7 V0 _9 X* E2 T! w
else+ \8 x) w k& u/ K7 _7 X/ D$ {
{/* space left is enough to be a fragment on the free list then */, }" A' s9 p! ?( ` t8 Q& O
pNewHdr->nWords = nWords; 3 ~$ l( i% f/ G: M6 W$ @* U% d1 w pNewHdr->free = TRUE; & o6 M# T1 P2 g, G: k" ?$ E7 `& t: f/ [% L- j5 T5 o
pNextHdr = NEXT_HDR(pNewHdr);* X) b- u5 E1 C" K/ W
/* words 包括BlockHdr */. P1 }9 P' y& _
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2; 2 u7 \% I j" N5 x pNextHdr->prevHdr = pNewHdr;& \4 t& h3 Y7 C* r' L
pNextHdr->free = TRUE;! F: @1 j9 r9 u2 W& M
) [6 R/ v8 J1 U" l+ f" C
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));' v, @# w0 s$ J% t) @) A