6 q I" x4 }5 g, \# Q ( \* l$ I4 A8 l, `2 Vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) % L; Z7 Y7 H2 S$ i+ [& ~{ 2 w$ o6 z4 _! z; k- l. J0 |# h) X BLOCK_HDR* pHdrStart; 7 ]2 P5 A- k- v9 o+ ~ BLOCK_HDR* pHdrMid; 7 a! M; F1 X* D! c4 E BLOCK_HDR* pHdrEnd;( o+ U; [" I4 h) }
char* tmp; e4 g4 ~! `! D7 }
int reducePool;6 A6 H. Y: d5 S. }) y
/ d8 f4 O' F/ X" q, ? if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function *// X0 M O. J1 ]
{* n+ ], U5 ]% O$ w) w$ d; Y. ?
return (ERROR);2 g) w& r/ ? ~# [
}# g: f( H9 [, ^; Q; {
# A' ~) J$ |# m$ H tmp = (char*) MEM_ROUND_UP(pPool); 2 h, b6 G" \2 P9 D reducePool = tmp - pPool;+ c# p% C( _, x/ F. S( A d }
( ^% a7 v0 [/ m L5 \, ]- H6 [' N; [
/* adjust the lenght */; `% m1 b3 M2 r
if(poolSize >= reducePool) / a! c6 O. p" Y, j0 O) e( @ { . o7 ? E A2 H: `6 u$ ] poolSize -= reducePool;3 n/ \+ f8 v. U$ t+ Q; E
}7 u; D* N. O2 }. ?7 O
else7 P# \, X2 \8 X+ `
{ # J/ j- D E; y7 c' g+ V poolSize = 0;% \8 n1 Y3 Z2 `3 D% r
}- U) F6 P: V1 y5 E8 F
pPool = tmp; : B: g Z5 W3 @ : }: ^) b# f' M/ w' h, }0 X, T+ C poolSize = MEM_ROUND_DOWN(poolSize);* }: z5 ]& ~8 \4 i
/ D: k6 v& @: Y$ J' p S: N1 S% M5 k5 r
/* at least one valid free block and three header blocks */$ D1 \% I" n, z& q
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) : O! l, G+ ]* Z$ t { ! D* R( e0 X- { h Z8 u return (ERROR);$ z# z; m( h6 x. c+ x. I4 e
}! P8 L6 Y0 b4 w
2 v2 U; p! M8 f) R7 D /* initialize three blocks */ 0 e+ E; Y2 v8 S; Y* L; c pHdrStart = (BLOCK_HDR*)pPool;4 R" A8 T, Z! J9 O% p, W1 ]
pHdrStart->prevHdr = NULL; 3 ~% _% ^- @4 [3 j, `! a3 Q1 c- ^ pHdrStart->free = FALSE; /* never in use */7 t2 o( V9 t6 x0 Q3 Y
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;5 d9 y2 I" T; T* `* a
' v* X7 W, E! L+ H1 P( I pHdrMid = NEXT_HDR(pHdrStart);1 [- P1 O3 v w1 U
pHdrMid->prevHdr = pHdrStart; & h) H- }: G( [; \* l+ f pHdrMid->free = TRUE; /* the main block */ 9 `; t1 H( | u+ @ q8 K pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1; & r/ D ]2 N3 Z ; n8 S4 S+ f0 Z$ K pHdrEnd = NEXT_HDR(pHdrMid);+ _! b) F8 `2 p
pHdrEnd->prevHdr = pHdrMid; 2 z0 V7 P) p9 r/ Q% `% {, E6 D pHdrEnd->free = FALSE; 9 H/ `* B1 a3 ~; [1 F1 o- i& ~/ M pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;0 ^& d) L) l$ q1 j
3 a5 k* P3 O, _0 m, V+ A: [ /* TODO take sem hear */& Z8 Z* c% S: B
semTake(partId->semPartId, WAIT_FOREVER);. Y" W; |* H' S6 \" n. h4 }$ K( ]. h
, P x* K8 w5 c/ t3 r3 P! g
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); 6 X$ q+ E, I, [8 X1 X4 \. ]; A partId->totalWords += (poolSize >> 1); 0 g3 A# o0 L% b . G: _( C. Y* X2 r0 X. e' Q/ |8 k /* TODO give sem hear */; M O: w/ i/ g' r
semGive(partId->semPartId);1 m: ]) \$ Z( o4 m: f
, q. J2 r4 b# }$ {3 e6 f4 Q ]
, j& T9 r4 l3 l4 |% n) \( b' L
return (OK); 8 n8 z' k1 w% t/ j}$ e( v" u& x. P6 Z1 C; \9 d& I
- z! ^5 ~/ {- b4 _7 z% Nvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) # U$ S7 C" B/ w! ]: W4 A4 g{ % S5 b$ L7 \4 n4 X9 l$ [" y1 K FAST unsigned nWords; ! _ c% \7 F0 I( F) I9 e FAST unsigned nWordsExtra; * D" N9 E- X% b, E& \& ^ FAST DL_NODE* pNode;5 L" J ^2 \' T
FAST BLOCK_HDR* pHdr; ' V% D) e, ~% W0 L( o; X* t BLOCK_HDR* pNewHdr; # k) z( _& a" u BLOCK_HDR* origpHdr; m! X9 ?( C9 r$ u
. g- x; d) |+ B: w
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ & y* H; x; @9 m) h! U {2 u+ Y' q# j, y) u3 K& E. `
return (NULL);) F1 l! D% f$ S; x: k7 n) O
} + H. \! M! i- c. o; ^! d, I! o1 Y; [$ I! Q e j
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;/ J k. n) _2 i7 z; f
2 o9 _$ W2 ~* u$ H. i$ B if((nWords<<1) < nBytes); D- e: f( M# M6 X
{: s) X% p' h0 G7 ]
/* TODO suspend the task */ 6 o- O5 |; a5 j% z0 {0 C return (NULL); 5 Z9 S$ O5 `3 g* L$ L5 ` }0 i' c d0 _" m3 ~; ?/ h! z
" I0 \0 C: k! `+ B# K
if(nWords < partId->minBlockWords)! e6 R! R+ O8 _) x3 {
{ , R B; e/ B0 E, | nWords = partId->minBlockWords; 6 O/ I% S0 t4 r8 [ }) D& K6 @# s. R* o
+ p1 ?7 \- j/ j2 U
/* TODO task the semaphore hear */ 5 w& | B. z) j semTake(partId->semPartId, WAIT_FOREVER);- A, l4 I; ~& @$ D% L) F, Y
pNode = DLL_FIRST(&partId->freeList); ! e) w: C3 F3 D6 c* C% }$ I nWordsExtra = nWords + align/2; /* why? */ * g7 v. h& f% O g) S: D8 [( ]2 n! y4 V0 u- x+ U0 o+ k
for(;;) 4 _" k; [8 |: a& X6 a! R) j& x9 k {) K6 {2 l0 D5 s8 c6 ?5 P5 i
while(NULL != pNode) ; k8 _# V$ T2 |1 D {: }( L o& I) E: x* y% o
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || " A$ M" n" R- n: X- ` ((NODE_TO_HDR(pNode)->nWords == nWords) && 3 O, W7 `( x( U* ^& }( ] (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) M# ^% ]: Y; t$ t) ]# s3 Y: e { & A% K; a. j/ y' Q break;6 L5 n$ P# ]1 c. u! Y9 G" K
}. i) f& R* L1 _
! l7 f; d/ q* O/ S% J0 y pNode = DLL_NEXT(pNode); : H0 o& M0 s$ ? } ( Y( j! e6 q- b& d& W+ ]0 Z! `8 _3 n : ?6 m: V' s+ ]# U; C0 k if(NULL == pNode)% J8 j8 O! r6 ~& ~
{ 2 x4 N/ M2 C$ g1 T. K- y /*TODO give the semaphore */& W! k0 {1 D4 H
semGive(partId->semPartId); 1 C! g3 Y. z6 C) x5 y, I" d return NULL;8 O6 }, Z1 x! T
}2 d1 }/ p; g& g4 G2 U5 k
$ ]2 F- p" O1 H$ G( T& q! G1 y6 e B pHdr = NODE_TO_HDR(pNode); - i& X. J0 h- h5 E& ^3 l7 ^ origpHdr = pHdr; , k2 D4 S# X" W% A6 P2 h 5 v# Q1 y6 {% S pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);$ ?0 ?5 y* s' c# C8 u% y
if(NULL != pNewHdr)' w- {6 ]4 I+ o
{ 0 L% R. S/ U3 [; s# X! T pHdr = pNewHdr; 9 [" O( k5 B9 Q break;$ }* s9 @/ B' ]
}( K; t4 b" I# Q) T& s! U9 ]* r
' P; _, c' H+ |# s0 C% p pNode = DLL_NEXT(pNode);7 ~! c) k; ?% x; Z, e* N' }
}1 M% b; N+ H1 J9 L0 q; M. {9 \
1 [: d* }6 e, c# Z' l1 x' j! ^9 d
pHdr->free = FALSE; 6 P* z' x* \- E& W1 U0 Y0 D% S partId->allBlocksAlloc++; 4 U Q/ }0 o/ l/ I partId->allWordsAlloc += pHdr->nWords; 0 M m4 U' I( m) @( F# Y partId->curBlocksAlloc++; 7 d7 N& l9 l+ H2 V partId->curWordsAlloc += pHdr->nWords;. q$ \9 p. r9 X. p$ ?9 X8 t
2 s u( n4 z% N /*TODO give the semaphore hear */ $ S4 h$ k4 t9 d: l semGive(partId->semPartId); b9 y l+ D( b6 R return (HDR_TO_BLOCK(pHdr));7 V: Y- f% _; l3 ^8 I* L1 Y, P' B
3 o9 h. m. [5 Z7 E m} $ V6 B1 n3 v' M6 {3 k+ } 1 n0 J* b3 f0 x r; H+ Yvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)" ?- Y% {/ S% I* K- _
{ 3 J$ Y% n- a9 \; E2 ? return memPartAllignedAlloc(partId, bytes, memDefaultAlign);4 I& }& u% j, v
} + k7 o. L/ {9 a* y3 S( `( Q' N& o; W3 B) L9 i$ C% P a& J U
STATUS memPartFree(PART_ID partId, char* pBlock) ( y) ^2 Q7 `. T" G4 S: g& V9 _" H: [5 ?{ % u# W* I: d/ x- U FAST BLOCK_HDR *pHdr; , @ j F0 G" n' C% A6 B FAST unsigned nWords; , |+ G, `7 |* \ FAST BLOCK_HDR *pNextHdr;0 l+ G+ k$ T1 B8 t) G+ s1 B
# H6 Q, ?! l X, }
if(!IS_CLASS(partId, memPartClassId))8 y& ]9 Q# t% X' l
{ / ]& M- p% X& u0 Z6 {1 A return (ERROR);% e& O6 ?# q! }8 I) X Q; v" @0 F
} 6 o# k" U6 Y+ z* D7 B7 }0 ?' F9 ?6 G/ w, S& `6 ]0 l. W
if(NULL == pBlock) ( p2 Y/ t+ U2 T0 Z { + m/ v5 E+ @4 y$ v/ ^ return (OK); : Y. S1 l! z" W) U7 A }& n& M4 j% {0 x0 K- O
9 I2 a% x1 E: ?0 w" a, p7 I5 o pHdr = BLOCK_TO_HDR(pBlock); 2 y) g/ X4 {# z2 ] . {2 F9 Y( R& \$ v semTake(partId->semPartId, WAIT_FOREVER);6 _" B4 u! G. t: l* k
3 r. P; v/ ^, J5 P8 d/ R3 p if((partId->options & MEM_BLOCK_CHECK)8 K3 v3 A) u8 Y' [; |( F
&& !memPartBlockIsValid(partId, pHdr, FALSE)) . Z# C& N" i; N% m { ( W, p" s& u3 f4 O$ E D semGive(partId->semPartId);! h6 w( c% p* j8 s( @' x' E6 Z
return (ERROR);! w+ }! P8 \2 X
} 4 `2 h9 B6 `4 c7 v ~0 V6 M K& b6 p" B( G0 H& p. W
nWords = pHdr->nWords;# f. m* U# |: R! s/ h5 z Z! u
if(PREV_HDR(pHdr)->free)+ ]$ [ t" X' J
{/* the prev hdr is free and than coalesce with it */1 z2 U- J+ E3 @4 Q7 D2 u
pHdr->free = FALSE; 5 N4 Z$ @ n$ Z. K9 y6 l: O pHdr = PREV_HDR(pHdr);! x- ?. S4 m) C+ Z' B# w
pHdr->nWords += nWords;" P5 ] ~* H7 c4 i. `% E1 F
}# m, u6 K' ]& H( Z) j4 D8 M
else . u4 A- @3 {* v' ]% i {0 G; k$ P$ c k! ^& a
pHdr->free = TRUE;9 |* O( _# w% ~: }* o4 R% I
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));% w# B) y: t( q$ d% ?
}1 v0 k$ u9 H; W6 W& V* ~
8 z3 [4 G5 u/ E+ [
/* check to coalesce with the next */& V# }- M' @9 P
pNextHdr = NEXT_HDR(pHdr);& V7 q2 c% P4 R
if(pNextHdr->free) 8 f. x/ m6 i- a {) y X5 C. x$ C5 d& q) V
pHdr->nWords += pNextHdr->nWords; 3 C- e4 T* J) D% I dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); . p) T! `+ R0 f4 t6 T h0 R& X }6 E5 k7 S9 s2 l/ i+ ~
: r: b" O+ `. n$ }
/* cannot use pNextHdr->prevHdr=pHdr hear */ $ W5 m; c4 P7 E+ @9 i- k$ x NEXT_HDR(pHdr)->prevHdr = pHdr; 6 Z W0 {( l) ?- S) W# E; O4 p6 z8 B6 F9 S& L0 F( ^1 @0 I* g
partId->curBlocksAlloc--;8 f8 Y" s1 R+ z5 L- b0 q, v. Z) k( C
partId->curWordsAlloc -= nWords; 6 G( ?: _% } C# m% y2 s3 K & }2 W1 M$ I7 |: b, U /* TODO give sem hear */ & W8 U( |7 O8 c8 M, [3 m* i semGive(partId->semPartId); . }" D/ w4 \7 ?$ ?) B & r) ~- u/ D; v$ u1 h; O return (OK); / [1 r! \/ g8 X" ]' C# R4 d}& r- v5 J: U0 m- Z. R: b
, x& H1 E' {7 V/ e. ?! \3 pstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree) l- [1 d" p8 j$ r w
{0 f9 r; ^( Z5 V, J+ d* \* R
BOOL valid;' n' Y# K; I" [4 C9 K" l
' y" X/ i) B" G0 x# D6 r' @ TASK_LOCK();* d6 m$ N$ R4 {; W& Q! r; D. x
semGive(partId->semPartId); 9 l- S8 Q" D* V+ K% B9 _ 9 g. ]2 _) U9 N valid = MEM_ALIGNED(pHdr)" w+ r. h, j6 m( `- f8 P) h
&& MEM_ALIGNED(pHdr->nWords*2) ' w6 j+ H5 H# n/ @+ x& Z1 I7 U; i/ T && (pHdr->nWords < partId->totalWords) 6 H3 F, i2 u7 R' v( w
&& (pHdr->free == isFree) 7 v2 y; R- S$ ?1 y && (pHdr == PREV_HDR(NEXT_HDR(pHdr))) : x: J2 Q2 G. X && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));) C& e4 u# @' g: D+ [4 z
0 _6 b9 G, t; H) S. |" C& v
semTake(partId->semPartId, WAIT_FOREVER);: \1 T2 S" \- r2 ?3 ^- j
TASK_UNLOCK(); . x9 n. P$ y+ P, ~% }; N) G7 V& u$ |( s8 j+ e/ n) A
return valid;+ N; v9 D7 ?$ x+ [8 G8 T
}4 C2 F" m9 ~0 z2 q
. C6 v7 c+ ]) f
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId ) [% g0 w3 y& s& t; H; ~( W+ }' Y5 r , FAST BLOCK_HDR* pHdr- i4 |8 _' h$ B n5 I
, FAST unsigned nWords3 Q+ j+ A# @( b+ l8 {# {& t
, unsigned minWords, e" G7 P# x9 ~5 x
, unsigned align) 6 k+ z5 @% }, I( t7 Q/ }$ X! i{ 9 _' H' V; p! G+ w' i! {' \ FAST BLOCK_HDR *pNewHdr;) k o5 r k% b7 X- _& T
FAST BLOCK_HDR *pNextHdr;1 M a. o; A4 I- U
FAST char *endOfBlock; 8 }, K: W; E6 [4 x9 ^: I' T FAST char *pNewBlock;$ s+ T6 v& a- E1 J) D9 A
int blockSize;3 U5 l- }6 z$ c
4 A" @4 ] u. J0 l2 q- y endOfBlock = (char*)pHdr + (pHdr->nWords*2);, W1 K) k1 M0 `
4 C' Z5 ~. i. J- _" z
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));+ e$ ~0 m9 l4 K% x+ M6 X
% J$ p8 t: H$ P% U pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1))); # E6 |! a0 w g8 q, _4 V/ N6 T6 S% a" C% @
pNewHdr = BLOCK_TO_HDR(pNewBlock); , R/ v2 M! B. X0 W& T/ n, b , s) L" h5 x( L+ b+ \& a: y1 h6 p blockSize = ((char*)pNewHdr - (char*)pHdr)/2; # @. x1 h: E* b1 t9 \) A) d* s5 q' i
if(blockSize < minWords) w$ B2 u) y6 W. w
{+ O2 ]- U8 I9 V) Z
if(pNewHdr == pHdr) 8 ?8 {/ k) Q" s" m9 K { - U# @2 `6 K0 U dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); ( J/ j Z# S u1 y V* G: n6 y4 E } , {5 M) [6 t3 @% Y4 m4 Q else2 [, P4 `6 W: W2 d U" Z
{8 T) k& K3 Y( b: U3 {1 Y
return NULL; ! C5 H( g' L' Y! y$ v1 \3 ]" r; f } J5 _" e! z' c; o, E9 l }. n' c* P7 Q& Y; P4 @+ m
else 7 n0 m" H4 w$ o# H7 @, m { /* recaculate pHdr */* O7 o$ b3 l0 o5 \; x
pNewHdr->prevHdr = pHdr; ' K0 O8 _5 ]) X- h; s6 e+ T: K pHdr->nWords = blockSize; 9 r4 U! E8 P1 Y6 [ }2 n. e: I" B7 l0 t2 \- T8 \
$ P2 q% p9 e, H+ D: l1 d7 @ if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)). }# V: W0 ?8 H4 v" i/ ?# L
{' f% p+ k/ y: e* p5 c) x$ K
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; " M) S4 [# E; I pNewHdr->free = TRUE;, j J g9 N6 g, ?1 D6 R4 P( z
# G6 {/ p, B; {7 V9 e NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;* J+ X% Q1 f) ^4 U2 T) H8 ?
} 4 V/ B" {/ Y+ U# j. ~ else 0 w9 w' A0 `7 \1 _ {/* space left is enough to be a fragment on the free list then */3 i7 W$ [3 @$ D' X7 O+ x
pNewHdr->nWords = nWords;' w! V& n k0 Y7 c
pNewHdr->free = TRUE; 3 A, }) Z1 a* ]8 {7 P 2 G. I3 d! j1 J& L2 p. W3 [ pNextHdr = NEXT_HDR(pNewHdr); 7 ~( a$ ]/ T. g& e9 V$ L5 g /* words 包括BlockHdr */ 6 C: A' f; n' a! T9 \ pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2; * j7 p$ g- D& [; [2 Z' j' a pNextHdr->prevHdr = pNewHdr; v% q p7 {2 ~6 Z( ?% ?1 F7 W pNextHdr->free = TRUE; ( ~! r2 E/ t$ y/ Y1 q z0 V+ Q6 X0 i. e* ~2 x0 j) O, l7 F
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr)); : s" s. d+ C, A' P: A( F. n, x$ h/ D6 h
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;" o( d' j6 }! }
} 8 F; V2 K/ V3 z- C* {# r $ a1 r' n" {* B( ?" x, _6 g7 _ return (pNewHdr);% Q h0 n7 {3 O
} U, z+ F/ M: I3 D8 P, h1 o" S: r
, d& I$ c3 u* B* t# @- z) Nstatic void memPartSemInit(PART_ID partId) ; x9 R: R: I( h4 E8 F& V5 s D{- z! a; J/ S. C- [/ o$ A7 l& Z
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL); " h o1 n- w% P5 V9 A1 B5 z 0 K' L/ [; f- Y" Q8 B3 D partId->semPartId = &semMemSysPartition; F$ P# C- C; T8 o( r* F8 A4 @
}1 {/ {$ T' U! }/ [6 m% g
' e& X" t, c" O8 y* M2 u( c) I7 C% evoid* malloc(unsigned bytes) - [. O4 Q# a- F' B; }{ F7 \; i1 |7 \" R
return memPartAlloc(memSysPartId, bytes); 3 w5 {( Z- V& t! b6 A" U' y" E( C* q} 3 Q) Y1 m6 B3 O" a" T2 E+ g2 X" B$ z6 d v0 H5 B
void free(void* p) J S: C; ~) O. ~$ X
{9 N6 m+ f( A6 [8 z7 ^! T9 B
memPartFree(memSysPartId, (char*)p);; `% N1 R8 A4 h# J
} * v: ~, \5 U M: x