2 G" h" U7 R( Q/* optional check for bad blocks */% N- ]* L( g0 i- }4 n
; W) f( I. s- H$ l3 z' O: M
#define MEM_BLOCK_CHECK 0x10 2 T, a2 ^* s/ ^, ^+ [1 X , A- O1 r: |* c& t0 D0 [/* response to errors when allocating memory */( m7 `. Y& Y, ]) x# I: r' u" [" H8 F M9 ?
6 C4 F# T% s' `6 y
#define MEM_ALLOC_ERROR_LOG_FLAG 0x207 V1 f/ g/ d7 e% Q" q
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40 6 ^( z, u: a$ D9 U" y 0 [7 ^1 ?+ V Q8 `/* response to errors when freeing memory */ : K+ i/ U, y% c- |6 L) z* f+ t1 m9 {+ g. D4 k" P: b
#define MEM_BLOCK_ERROR_LOG_FLAG 0x802 C& ]0 @8 j. f+ B4 L
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x1008 L) r4 a! d% G" N' T
/ F% N0 y$ d# M6 h0 y( O. o
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))), n* @1 P( q4 m1 A( K( L/ u
#define PREV_HDR(pHdr) ((pHdr)->prevHdr): b( \+ h# x) s' B- U
6 n! m2 X+ w# ?: O9 F* N4 Y
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR))) 8 b0 y# B8 W2 S9 j7 S#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \$ V: |, A# M% s: _; m' o2 ]
sizeof(BLOCK_HDR))) ( d0 }+ }; c. {9 }& j! ^ J* |% c ( |; L, ~/ g; Q8 v1 ~#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)( D0 {9 \( F. w+ x( M9 U( x# Y
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \' H8 n% r4 v3 A5 f
OFFSET (FREE_BLOCK, node))): z, D3 ~$ x8 }7 K/ k
: [8 R: q; _0 f! r! \. z7 F% N
static BOOL memPartLibInstalled = FALSE;; a: M1 ^8 h! V* H7 ~$ w4 ] H8 X& o
8 g# C8 [& d' c6 h9 s
static OBJ_CLASS memPartClass; 4 z$ I8 _8 @# X$ H- T2 |CLASS_ID memPartClassId = &memPartClass;3 V, ~4 l) Y: o. Q% k$ ^1 L
2 u* v5 h" a1 Z
static PARTITION memSysPartition; + _" P/ T' Q3 ` Y3 \8 X# KPART_ID memSysPartId = &memSysPartition; . H; e7 M8 S" Z$ |4 ^! UU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;' k6 k2 H4 b* T7 C h; V
2 v/ ]6 u: \0 V2 A
static SEMAPHORE semMemSysPartition; " U5 y7 ]) a( I. p! X; s9 J0 t3 Q, r m% h0 ?6 H0 h, M7 c8 I9 c* f0 F2 P
static void memPartSemInit(PART_ID partId);7 _, @% [# h. Q8 _# I5 J( T
( N+ e2 R6 X# v- k6 R+ b4 LFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit; $ m& K) a% R* ? ; Z, \+ b: h4 f5 J; funsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK; - t7 l3 S/ H8 K! A2 B, U / E9 O$ W4 L: A+ P: vstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);# z! W, D2 N, a& _# I: _( V! d9 A
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId 1 Q4 l2 y8 [8 R/ U1 K/ U' D , FAST BLOCK_HDR* pHdr* D, J; `7 D4 Z: N" k5 f
, FAST unsigned nWords % M; p- r6 C4 Q, [, `' p! }; [1 g , unsigned minWords1 U5 A7 c; s l0 l
, unsigned align);% d5 J/ A1 A+ ~( M& {: X- d! R
2 o+ N: p S/ Y6 xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);0 T o# Z; ^3 C* {
3 q) r8 i9 J0 s7 s4 V9 U
STATUS memPartLibInit(char* pPool, unsigned poolSize)# k! C/ J: g! _% k
{1 w: K. Q% `& r; w
if((!memPartLibInstalled) && 6 |) e' X1 C( ~ (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)* D3 ]9 d% F1 H( G
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy))) 0 z9 e3 i# V/ ^* I { * H1 r. G( {& R5 {4 [7 T memPartInit(&memSysPartition, pPool, poolSize); ! b- Y- N" R) b l# T. v* l memPartLibInstalled = TRUE;1 w1 G0 T B5 W
}$ H* U/ k0 s: j Z# }" h0 I# z
) G' s3 X8 _# R Q" S
return ((memPartLibInstalled)? OK : ERROR); / ?6 _ {' @, q! i$ h) g9 y$ o} ; F( A* D {; E! I3 N4 t) v& I ' Z/ x; b" H9 i' i" bPART_ID memPartCreate(char* pPool, unsigned poolSize)6 ^8 ]) R. r# C% W- i) t
{ " S3 [' `& L' Q. i PART_ID pPart = (PART_ID)objAlloc(memPartClassId);* _5 [- X. G) t" O ]# {! @7 T
1 z, |, w6 _7 {* D
if(NULL != pPart)( b9 x' }( n6 \# t* }
{, x1 ^# `5 w% x y0 o& ^1 _3 C
memPartInit(pPart, pPool, poolSize);3 I, j3 p- Y! l" e. }$ V
} . G) M' a$ [6 D r: Q, ] ; t7 W \+ h n3 ?& s return pPart;# W" g5 D: i* u- ?. E
}1 e8 B& P T+ O9 F$ H
& `9 R' d, i; Tvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize) 8 C8 r4 f2 }; L4 M{! u: }( W, H, I$ C2 O
memset((void*)partId, 0, sizeof(*partId));8 @/ m; F% T6 L5 a- ^* p" T! h6 F
+ A3 R! L7 x- ]! d8 x/ S
partId->options = memPartDefaultOption; I* V$ w" v; a% N) L
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */# p) D' |/ W( u5 D7 c
/ H. h) t' G# X3 _' d (* memPartSemInitRtn) (partId);4 J6 F0 V) {; _2 _$ ]8 ~$ `) V
2 E' m5 {' V, k4 T% z8 @- G z dllInit(&partId->freeList);8 b- e+ f; t% `2 C2 W
3 \5 M- E5 {$ n4 T9 K
objCoreInit(&partId->objCore, memPartClassId);! Y/ O0 \ _# j1 N6 p g, Z
1 f: z) l, p- D0 M1 D
memPartAddToPool(partId, pPool, poolSize);' Z0 ?9 A3 s( ~
} 7 ^# ~& ^& f9 H) f" D 1 O r4 h2 I; i$ ]+ USTATUS memPartDestroy(PART_ID partId) 0 L- N" x. \3 x3 p5 \' a# |* k. g{ " m3 R' h; n9 v return (ERROR);# e3 d6 t2 m: ]
}4 d9 y0 Q0 @& F8 a
% C6 U: ]1 E: h7 A$ J# Wvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize) * W2 M6 [$ a) U{ + Y: {. R+ b7 \5 j2 u (void)memPartAddToPool(&memSysPartition, pPool, poolSize);/ J- v- C! Y5 t; r7 B1 A: `, v
} 3 d: m" `$ @2 x5 A6 N8 |+ V, e' ?4 e5 h" Y
" w4 Q5 {! [% n2 M) n4 y; t
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) * Y) ?4 }* @* e# H{ ( E2 x( ~ U# A BLOCK_HDR* pHdrStart;* P6 W" C$ B2 _
BLOCK_HDR* pHdrMid;0 a7 c1 Z% ^7 S2 q5 b
BLOCK_HDR* pHdrEnd;$ U4 Q* g' E% O* K& o
char* tmp;1 j, a5 P, g' J* C
int reducePool;, a# ?: ]9 K' j4 g5 k' q
; R* |6 s; w. @' v; \$ a
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ : a$ L. L" j+ H: s4 E% a4 G { ; ]; ?5 h9 u) v W3 m return (ERROR);7 R* E7 s! U' E6 a1 W9 y6 X
}9 `$ r% S7 a |* z1 g
% S0 c, ~0 H8 c6 S
tmp = (char*) MEM_ROUND_UP(pPool);# B+ X7 o5 Q h c+ ?$ ~3 r8 L
reducePool = tmp - pPool; u m- j8 @7 i
/ g9 O1 z. H9 ?6 X
/* adjust the lenght */ 3 `6 g$ W) f, h3 Y! d4 @$ T if(poolSize >= reducePool) / ~9 Q% k+ B9 c- s: Z! C { $ c4 ~5 p: M& z+ z poolSize -= reducePool;/ I- N/ [6 `% u4 D9 c
}: V/ k+ L2 g9 \$ x' _
else$ `1 O; y' h; S4 D; j: f' x9 T( k
{ 5 J% H% D/ n0 M% j poolSize = 0; ; _; U9 f" u n* G' o; g }8 A/ w E1 x. v
pPool = tmp;* \1 z3 e$ Z, ` U; X; M4 ^: p
0 G2 X! N n9 z' _! z/ N" w! i poolSize = MEM_ROUND_DOWN(poolSize); 4 N" m# B( n" ?9 e* V o ' y5 {' h! Y3 l% |8 w9 o /* at least one valid free block and three header blocks */ 5 d$ d& ?. D3 `2 G if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)8 {' l8 r6 ]( R) i4 e/ @* w
{& g& S+ S/ }* v, X
return (ERROR);) h/ x9 B) q- @ o1 J) f
}9 o, g7 k$ H& s3 H
! z7 ]2 B# G2 P% D1 v8 J /* initialize three blocks */) g2 u% X% n8 N6 ~
pHdrStart = (BLOCK_HDR*)pPool;8 c6 ?$ k/ ?% ~7 ?/ G
pHdrStart->prevHdr = NULL; ; r$ P1 X0 }) g9 y2 ]4 F; R pHdrStart->free = FALSE; /* never in use */, O3 W5 k- N7 T$ u
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;; T0 u9 J/ [/ v; a$ `1 P. |
/ C& ^4 D+ T6 h1 Q. p$ H/ R
pHdrMid = NEXT_HDR(pHdrStart); 7 g+ q; d- {5 c pHdrMid->prevHdr = pHdrStart; ( p; O- X' G9 F& E% @" r" m pHdrMid->free = TRUE; /* the main block */8 L9 s8 Z+ u6 d/ s! W
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;( f2 ~$ @: F, ^% {# \+ U8 f9 V
! |) S8 I6 B% k( m# k8 \3 f1 o! ^- v pHdrEnd = NEXT_HDR(pHdrMid);6 w6 R# F- w; Z
pHdrEnd->prevHdr = pHdrMid;2 U. p3 a7 A% Q" q: k
pHdrEnd->free = FALSE; / y2 m, |: e4 b, M3 l0 b* F" q pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;8 M; U4 w# g" M: t: r
5 {7 M4 I C! \/ v$ S /* TODO take sem hear */ 8 j: ]- {+ Q# z semTake(partId->semPartId, WAIT_FOREVER); ' N1 E9 k: \2 G) G! W ! S# M* N' l. _! l% |+ @+ X
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); 9 v- U3 B! e6 S2 q$ I partId->totalWords += (poolSize >> 1); 9 B: E; }% L. g8 N; I! }. d# ?0 D 3 }9 R) Z) }5 \ s+ g p0 g /* TODO give sem hear */, p9 H( q6 w1 y# W, }9 d
semGive(partId->semPartId);$ ~) f" z6 v. `. [# h( ]" z- f
) J( X8 l: z3 t" _
- s i( a) ^- F& {6 Y9 P, S return (OK); / Z2 Z! {8 `2 @6 g4 z Z}/ h7 }3 F2 r1 _" {) ]7 i
* M6 i: U0 l- ^5 d
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) # s- g& v6 l! f9 j4 z+ t{; ~+ Y* u! [' U5 H& |
FAST unsigned nWords; 8 m( A7 Q% X: R2 S FAST unsigned nWordsExtra;) }5 E1 N# {. R; J$ J4 ?
FAST DL_NODE* pNode;8 T: ^# ~9 p9 f9 c$ O$ x6 Z
FAST BLOCK_HDR* pHdr; 2 R( Y. j6 }5 ? BLOCK_HDR* pNewHdr; / D6 U k3 P% O. |9 H( D4 z BLOCK_HDR* origpHdr;2 c; r" P* V9 L. Q3 l- I9 F9 D
7 k' T- d$ z# [ A
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ 8 x, M8 ^, }# _+ Y5 X { - J9 s: b% w: ]1 ^3 O return (NULL); a- v% j3 u, o% W" M5 v! ?
} $ I K6 n5 c/ n: N7 y9 `, l( P1 c T. h " X& R& j; h- Z+ ~0 [ nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1; 9 G/ R' O6 z7 _# u3 f9 J; M, t" @9 ^. ~0 n
if((nWords<<1) < nBytes) - X5 a" n/ w9 |( O. s C { . K! j; L6 O ^5 H3 x /* TODO suspend the task */0 M& D3 l) y. U: t2 ?6 O
return (NULL);1 I8 x: ?3 I2 a
} + G! S1 ^: {% H! B/ ^' y0 p 1 a s9 T0 Q* N3 M if(nWords < partId->minBlockWords). |" N; N% L( l* [( Z0 _
{ ( h1 x# N" q3 A$ U$ D nWords = partId->minBlockWords;; b9 X' x5 @' R. D, ?, N7 N
} % s2 t4 Y) @8 h" i4 P- \. w, n2 b
/* TODO task the semaphore hear */ 5 I2 c, [; m' m semTake(partId->semPartId, WAIT_FOREVER);4 Z: O+ x7 W! @6 t O9 t: \3 q9 g
pNode = DLL_FIRST(&partId->freeList);, p, u3 K! G5 r- g
nWordsExtra = nWords + align/2; /* why? */ & h; E, D1 S! u9 I % @0 m! o2 j$ Q- A/ X for(;;)9 a0 X4 s) ^8 s; F6 `) h
{; J0 \. I4 ?6 l
while(NULL != pNode)' v }3 R/ b2 p2 o/ y9 h2 `
{% u" E5 I& K9 w3 b
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||1 O# l7 |. S" {
((NODE_TO_HDR(pNode)->nWords == nWords) && : y% w+ S Z1 B+ g `" y a
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) # R/ h! k3 f8 ^8 Y! k" |9 Z. `: V ] { ' d2 r6 { z- i- V break; , E: x2 }/ f/ d) k5 z ] } ( p1 X& `7 B6 X2 k) f3 ]9 h2 `: N$ [# ]" X l2 y, k7 I% S
pNode = DLL_NEXT(pNode); R2 t0 @3 U' p) s) i0 }5 a, T }. U0 \/ I u& r$ p4 w
- m. |6 L- H' c6 w0 U+ n& _ c( V
if(NULL == pNode)' v2 V8 l* q7 o1 {; O
{ * C1 h0 n7 I9 ~( W) J- M /*TODO give the semaphore */ + C; {$ E0 d2 _* F0 y semGive(partId->semPartId); 9 o$ G; ?% K: F5 l return NULL; , _; L6 o1 {( z7 y } 3 j) L+ i% e+ F 7 S. t3 e" ?9 X5 |/ j/ S pHdr = NODE_TO_HDR(pNode); 0 Z/ j" C+ C1 a origpHdr = pHdr; 9 ]! g; N+ n* J4 z + F; \& x& x7 m# C: t pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align); ! ?! ?# Y6 S2 g% Z if(NULL != pNewHdr) ; D5 _- P+ v9 b# K { , l h+ ~: D; l4 v& z* l pHdr = pNewHdr;, w; e$ W& [# |4 Y8 A
break;9 b: C) _) p# V4 X. H, x6 ]
} " {# g- v: P0 a% Z; ?7 t# e, N: v4 q% ?: b2 Q7 }
pNode = DLL_NEXT(pNode); 6 A0 q6 ^. X+ k {- \ } ; ^5 F8 r5 O& a1 @" L# ~7 t. ]6 T1 s0 V1 W! r
pHdr->free = FALSE; K5 V+ B! o) g8 t; P; c k partId->allBlocksAlloc++; S& |" Y& Y* _; E8 A partId->allWordsAlloc += pHdr->nWords; 3 s" ~- t; z- ?$ @. E5 }5 P5 j3 Y partId->curBlocksAlloc++; - o: K; C0 M5 t6 c! `4 k! Z partId->curWordsAlloc += pHdr->nWords; ! [. M! Y9 S0 g- o/ |2 J ) Q/ E& N5 l+ h5 e9 P /*TODO give the semaphore hear */: g- N( f9 `3 w2 F3 P0 A) s- M
semGive(partId->semPartId); " X6 c6 {7 z$ R$ S3 A( C* g return (HDR_TO_BLOCK(pHdr)); . M. M+ O4 g% n# Y6 [ 0 K/ y$ [0 q, S2 J7 l+ S+ A* K. b} 3 |1 i, [+ V# e7 J- I * F' ~1 a4 N$ }+ ~& V* }void* memPartAlloc(FAST PART_ID partId, unsigned bytes) 7 m; h& a" _3 ?{5 T( ` ?) ]) J9 W& t2 k9 l! y \
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);9 G* y9 }( K% c/ Y! {. A, I! S
}. {& u- a5 S2 m* v
. h# [/ B; E9 `3 ]STATUS memPartFree(PART_ID partId, char* pBlock)' p( F9 u% |! u7 ~. y
{; J, s, h& i0 B x9 a& {
FAST BLOCK_HDR *pHdr; # c# ^; w* S! Z1 c, n8 l FAST unsigned nWords;5 n/ o4 M t6 n% z
FAST BLOCK_HDR *pNextHdr;, U) |" Y! K. A; ^7 ?( S
& T* f$ L: C7 x7 r( V
if(!IS_CLASS(partId, memPartClassId)): X: z9 H% ?, o- s# Y' ?* ~- g
{ & e, o' A0 t1 C) q1 i return (ERROR);: W0 t' o! F5 ^
} 7 a$ Q: y* b' G0 o& }; E: N: W, z' j0 f, _" N, o- B# T
if(NULL == pBlock) l# V, k: Q$ z4 w/ S. z
{* z, L3 B3 a! Q/ e& ~# z5 ?' D
return (OK); / Y1 O4 w/ D0 N) } } . ?, z/ V. n6 |! W % a: g& h# @& p# v pHdr = BLOCK_TO_HDR(pBlock); , _5 q+ G1 d7 c6 b5 t6 U# s( D5 o 0 `" r3 Z5 B+ s, M5 {4 ]5 g" e! e2 t semTake(partId->semPartId, WAIT_FOREVER); 0 y8 F9 {5 K+ g" x; H: a: w " i ^3 T8 C) f- ~4 s) o1 Z if((partId->options & MEM_BLOCK_CHECK) 6 }9 A$ d c8 R7 m8 g5 U && !memPartBlockIsValid(partId, pHdr, FALSE))) ~! `+ o) Y& ]4 \
{5 c) _" Y) B: q
semGive(partId->semPartId); " l, @7 z4 z- } c2 ` return (ERROR);. O* d+ a+ z2 |: M$ O ` B
} ' L2 }5 S1 w+ Z& |. u. S: ]' N' E; t: ]2 I7 _! V0 d W; k
nWords = pHdr->nWords;' L I G6 K" F# c& p( Q
if(PREV_HDR(pHdr)->free)$ B# d1 O( V4 m4 n" y' ^
{/* the prev hdr is free and than coalesce with it */2 Z, b1 h' J5 t5 o' }. Q
pHdr->free = FALSE;* P$ S9 B9 ^5 x5 B2 [0 c
pHdr = PREV_HDR(pHdr);2 m: U7 G' H1 ]
pHdr->nWords += nWords;% \+ Q g' g+ X5 Z8 F9 j
} , S: r3 p# U. a4 f0 E. v( z q, a else, ` c1 n2 w; H; D8 B
{8 W- z* E! \9 N2 i; L; K
pHdr->free = TRUE;; {) d) u" l5 V) s
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));; Z3 N2 D7 `4 g4 m9 t5 }9 d
} : y1 |! j8 O: `7 b2 h" o& q* | 8 s" ]" T$ G' Z9 c /* check to coalesce with the next */ 9 g: u; t; Q$ N R2 }5 V0 v pNextHdr = NEXT_HDR(pHdr);; H3 l+ a( r, R1 M) q. l8 M& i
if(pNextHdr->free) 0 z: o& J+ o/ ^# Q {6 a% d7 V4 M. J- T
pHdr->nWords += pNextHdr->nWords;# o) x* }/ U4 E# E; w
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); ) p+ ?2 C% {) y9 e/ a0 Z, j# M }& ~- Q& z6 d0 f( ^
; \3 |9 p u& z) E6 Q; x$ F
/* cannot use pNextHdr->prevHdr=pHdr hear */5 {2 h, i* h. d1 z2 `
NEXT_HDR(pHdr)->prevHdr = pHdr;: y7 O2 d7 O$ b, B. M
; l5 H4 @' u! ~7 Y+ } partId->curBlocksAlloc--;! Q1 ]4 \, G9 q
partId->curWordsAlloc -= nWords; 6 r8 X! Z% k0 j4 R: Y/ E9 @4 d' P" d7 b8 d9 L* Z
/* TODO give sem hear */3 B2 K8 y7 P# t+ P, p
semGive(partId->semPartId);" y- P# A# K* `: R
! O- A* b) a' S) G: T4 R7 F5 M M return (OK); 4 m0 z- V& w+ x, V, f' _. I}6 y. S0 ^- V% v( s# b
+ Q) W* b( W: }3 R8 [- Y1 V/ ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree). G! j0 Y; ~+ E- K {
{ $ M" |; W% n( S BOOL valid; ! v1 }' m, B) i2 |" `$ X& Z3 V- V f8 |# Z. T- r9 o TASK_LOCK(); 2 O, V. Y Q0 A semGive(partId->semPartId);2 W0 C0 c# v. K8 C0 S' t9 c
+ p- J, \8 Y3 I. K' W valid = MEM_ALIGNED(pHdr) * P) I! G6 Z8 T1 \0 H && MEM_ALIGNED(pHdr->nWords*2) + R0 j4 d& r+ x && (pHdr->nWords < partId->totalWords) " c# r I; D% n- a8 W3 m) ? && (pHdr->free == isFree)/ } E5 z# o" A- w
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr))) 0 o/ ]! u2 H1 c, C* ? && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));' F4 P, M9 Q- w; U$ k
0 d, S: Z7 P4 R% A9 [
semTake(partId->semPartId, WAIT_FOREVER); : X# |/ U# |' D( R _8 D TASK_UNLOCK(); 5 ^8 ]& Q5 `0 ?$ u |/ ] \, |2 K0 t
return valid; b; e" H4 N. ~ p}+ M8 Z+ n4 ]7 V" d/ o
9 Z+ `) t9 H0 g+ r( |; ]static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId# O3 d4 t8 A3 e
, FAST BLOCK_HDR* pHdr 3 G6 C" u/ d7 V4 ~/ G , FAST unsigned nWords ! j" P; J) ^& B- J6 v$ F , unsigned minWords/ c' Z7 {" L$ J6 ~& R, y
, unsigned align) & r. u: |5 o- x{ 5 `. p7 L) w5 w9 Z FAST BLOCK_HDR *pNewHdr; 5 N0 e" N: l4 {4 D/ C FAST BLOCK_HDR *pNextHdr;1 j( V& a& Y% A/ L- C! ]" u
FAST char *endOfBlock; 6 j0 H7 `8 [0 x& t; X& T FAST char *pNewBlock;7 b% s/ ~6 X8 U) P6 G
int blockSize; & z7 V5 _& ~- v" o8 I: H 5 l0 V8 l7 B; J( j# e* P; A9 [5 Q endOfBlock = (char*)pHdr + (pHdr->nWords*2); : x3 a8 k3 k* {) l: h, t + u% H1 i2 r% S: H+ u/ n pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));; f! h1 ] @5 ]5 d7 K: A
; X7 ~; X$ I y8 Q* c
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));4 \4 o+ D+ N P- \9 x, M' g
3 h/ ^% `, r, { h, O* C pNewHdr = BLOCK_TO_HDR(pNewBlock); * `$ b- U9 x) ?! V0 {0 f8 c5 k) K E# d8 M; h
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;. J: J0 x1 d8 a1 M4 V
3 J4 Z" j* m0 F' ]) x if(blockSize < minWords) 0 [4 b6 `" y6 P, ]! Q) [ {: M l) {5 w1 c' G! S
if(pNewHdr == pHdr)$ s! w3 C$ ^7 t% A2 [. r& L% d
{. s6 M; u& a2 \
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); , R" f8 l4 m- @! I2 H! y+ R7 a } w% L* G5 E4 x else9 M3 ^5 ^% \4 e S
{ k8 d2 m: S# M
return NULL; / C: d; L0 C M' N }1 T+ U4 j2 t- i0 R
} 4 v; {2 ~* i6 R7 ^ else8 t+ F8 m) u5 q- x) T. O
{ /* recaculate pHdr */ , n3 @0 |; J8 o/ C pNewHdr->prevHdr = pHdr;/ i% {5 I* F$ s# p% k2 m7 a b
pHdr->nWords = blockSize; & M% ~% X! x' A* I: ? } 4 j3 Z1 a1 k' ?# q7 q! s( J7 \. Z, [( {0 o* T
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))6 O6 p2 r2 i" U5 V
{ ; `# v2 |0 u& v. l8 V pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; 6 P6 ^. l( N: s" G0 x3 J( q2 B5 W pNewHdr->free = TRUE; 8 y% p$ N: N1 x# ]. L4 f2 c0 n, y/ I3 Z h6 W {1 @, W j. Y
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr; 9 k$ F" f* r; M2 V: M }& d( m. y2 N* N- G
else. E4 z3 P- \ ~1 b# C F& d! g8 h
{/* space left is enough to be a fragment on the free list then */; T% e: X$ R& u& N8 i/ D
pNewHdr->nWords = nWords; - B5 z) v4 Y' x/ u* F pNewHdr->free = TRUE;& Y# P$ A* Q1 @8 W: O5 W
/ F" q6 q% e7 s+ @ pNextHdr = NEXT_HDR(pNewHdr); 6 B7 v2 q+ p& w" |+ y /* words 包括BlockHdr */ 7 M( g3 x4 t( e; o' r9 W$ Z5 S pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2; : q" l: Z4 q& Z7 t; y G4 b- H/ [ pNextHdr->prevHdr = pNewHdr; 9 D5 S5 G+ z1 ~2 O! `3 t2 j% a pNextHdr->free = TRUE;+ L7 K% s6 \ b$ l3 C3 a2 S
% X0 V+ N1 F; {; J7 B
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr)); 3 l; K A3 ~" _, R" z 8 R8 ^; V( b+ Q* T3 ^& K: B NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;" E1 ]' h, M4 I# ^; G8 r
} , N) R1 ?' H' d6 \6 Q " {1 N O+ ?' b! E, S" l- {' F return (pNewHdr);4 r; k; U, Y9 e' J+ X7 `+ }
}7 J/ R/ C2 ^' i4 I) b& F9 S
9 N) H7 J8 d. n
static void memPartSemInit(PART_ID partId)6 i7 n k. |3 W0 l. L
{. y2 @0 M1 U8 n5 `0 m) X
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);4 z3 q) P6 [4 _5 D6 E0 R+ f- ?4 g
9 B6 _ {9 ?& C partId->semPartId = &semMemSysPartition;- ~# L; `6 D) L7 R' c7 R
}, B/ w8 y% M$ D