; J5 v# J# ?1 r* p( M$ Z return pPart; X: k% g; j) g, L9 ^1 [ q& P% V* \; _} o0 u) [8 P: s- p' Z/ D; Y
- v# y1 B$ F( W% G% z' ^
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)& x% ]3 k8 E" s9 r# u3 ^! B) C( E
{. F( z& s; N" Y* x
memset((void*)partId, 0, sizeof(*partId));$ ]* J$ N8 N! C5 w8 A* q* @
# g" d/ k1 \1 y; R& R0 c8 Q# H, F
partId->options = memPartDefaultOption; 1 W5 X$ [. p/ M4 N- [$ R* O Q partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */ * V L5 a1 Z* v n) s, o& N* f' d6 Z; G# \8 D
(* memPartSemInitRtn) (partId); 5 ^! D0 n4 c; t: u $ ?' L6 Y8 U7 M7 f dllInit(&partId->freeList);2 N: S9 j- O8 @( k" q
. a, V; @9 ]: ]9 `- o2 ?8 Y$ n0 }
objCoreInit(&partId->objCore, memPartClassId); * Y) H, b5 k# @9 R 4 d+ A( n/ {* }, f# F/ L6 x: w. z
memPartAddToPool(partId, pPool, poolSize);0 C3 e' ?" r+ {8 _
} / j9 {7 X6 m7 @; D5 _" p ' P+ d6 p. w, S9 }+ G KSTATUS memPartDestroy(PART_ID partId) ! x7 b/ \8 G( U6 \, s2 Y{5 ]% X/ Q1 @- i6 l. l; j
return (ERROR); 9 \) C# F, \+ ~} 9 ~+ p4 p6 `8 n6 I N! ^ ( {; P9 i$ q& O0 v# Uvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)0 V; M( X" i/ \
{ & [9 E8 W* C, }, Q* ~: | (void)memPartAddToPool(&memSysPartition, pPool, poolSize);% h. G9 @% ^* ]% J& q' X
} , T q! g9 m* f9 X 9 r6 s/ O+ A& h+ y2 n2 r8 [$ m9 X+ b6 c! r' Y4 @% J
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)( z+ w8 k- q$ q0 P" l2 Z( r
{ 9 V8 F! p, s" {0 D9 I, \8 F& z- a BLOCK_HDR* pHdrStart; + I5 R3 X# i: h) Q; D BLOCK_HDR* pHdrMid; ; U$ U* {! f' {1 i BLOCK_HDR* pHdrEnd; \# i) v, ~0 R' d# R1 R
char* tmp; ! r# p# s% A6 b- F int reducePool;# c# U! S* M. j
" ~+ T) v/ m" ~: R. z if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ ! r1 w# L" x& X* z" U( ~/ t ` { ) @' A) G# M, z6 v return (ERROR);8 r4 n+ s3 Q1 x5 {
} - R2 B( e# f2 o/ H* [% \! m1 [& I- [6 _
tmp = (char*) MEM_ROUND_UP(pPool);6 F- O/ i9 ?, h0 Y
reducePool = tmp - pPool; & ^! J$ z. l0 `2 ]; z0 r6 D: n 4 P. U- ?- \/ X6 r' o2 `6 v* f /* adjust the lenght */ 6 \0 s5 J" N3 d5 [( d1 @ if(poolSize >= reducePool) / x7 A6 q; B/ d+ N8 } { * w; V1 K) C1 |) n poolSize -= reducePool;7 x5 }- ]5 k- e j. H! v/ O
} & w/ K; {: d6 C7 m1 B3 u else% l, a$ T7 `) r7 E: a( F
{ / u* j9 O6 |' `! }/ t poolSize = 0; 6 ^% k1 O2 l9 R+ `+ a1 X } : X2 i4 Q0 O" R7 t5 w% p- y x pPool = tmp; ! z2 C( Z: ]/ M: r 5 a5 h( C3 U& `) r+ _ poolSize = MEM_ROUND_DOWN(poolSize);! e) L0 ? t9 j i% U- t# |
, }1 r& b% w: r9 ~' z5 s& R/ ] /* at least one valid free block and three header blocks */* }7 Q) R5 ~$ y8 b. y. t/ Y5 Z
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) / Y; g- h+ t7 j0 m. Z' T: C {( Y* n' a7 c6 b& Q$ f) \/ d
return (ERROR); 5 N/ w# E+ J, u* P9 f }$ u; Y3 r0 D% z0 ^/ r: N* `
% [1 Y0 k, \- V5 k% M
/* initialize three blocks */2 v4 Z8 Y/ ?7 m! L* X: B" w
pHdrStart = (BLOCK_HDR*)pPool;# e! t( L+ B# k C1 s6 U. |5 w7 p
pHdrStart->prevHdr = NULL;+ g: H7 u0 O1 A
pHdrStart->free = FALSE; /* never in use */# A6 C" E6 X5 D2 g% `
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; w7 {$ a7 Y# K* b$ L# _
! c# I/ K! C* b' p1 o- e pHdrMid = NEXT_HDR(pHdrStart); M7 S Z& A% B; M" v" M pHdrMid->prevHdr = pHdrStart;$ f( `1 F' t/ t/ a0 B' i3 m
pHdrMid->free = TRUE; /* the main block */ * [# T$ Q/ p6 T pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;& j6 V$ ?' Z& r& Q: p' T+ t F
X, x* L: C" _3 h" L# d; d
pHdrEnd = NEXT_HDR(pHdrMid); q A! n, b4 l( {
pHdrEnd->prevHdr = pHdrMid; ) T. ]6 h8 }4 k pHdrEnd->free = FALSE;& |; D) `/ x& M1 i
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;+ U; s- Z4 G2 n) a( |& j" B
! K. S* p* @0 V. s) V7 N' n) y
/* TODO take sem hear */ 4 g5 A, N$ N v" a* N+ I semTake(partId->semPartId, WAIT_FOREVER); ( O3 d ]: ^ I2 g* G; H- t / j: k! y- w. f8 Z3 [- w0 I8 |$ B dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));5 D, P2 G) ^ a3 T' N, Y
partId->totalWords += (poolSize >> 1); ! w% ]7 L" F0 B) O, _: i) W2 o' V- ?, K8 ~. N
/* TODO give sem hear */2 Z# ]: w0 [* d8 o
semGive(partId->semPartId);3 m/ ?! d4 U& T, `
# z+ O+ z6 O" ~/ g( ~ 6 p3 d" v' c- O1 y1 h return (OK);" a0 A8 c1 O4 C3 v/ b: K
}+ u, E7 u! ^3 F/ ~& F' a
4 r0 T! t7 `* w' P
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) 7 b/ W" c4 O% i+ i5 \{ ; p0 b* a+ G4 [9 A2 m FAST unsigned nWords;; S8 D; ?, o; u* q& ]/ G
FAST unsigned nWordsExtra; " j4 H3 v* ~2 X* A5 \! z; R1 O FAST DL_NODE* pNode;$ {9 X# ^4 S; o0 a% c1 Q* S5 N
FAST BLOCK_HDR* pHdr;2 A& N" m2 ^/ b7 o0 _5 ~! F3 z
BLOCK_HDR* pNewHdr; l% d" _; F4 @' o+ \2 v9 @
BLOCK_HDR* origpHdr;2 U+ j6 }$ Q j
: t( S; C. g9 e5 O9 J; O9 l$ `% U
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ 9 c+ U& _) r/ @/ J {+ `2 _: L. G I# {# ^4 X
return (NULL);4 x1 _' x* j3 v" p/ K$ _
} ) c6 S/ K; p* j3 w - X% J. }. d% `+ i5 p; S0 t nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1; 8 y1 G6 u2 _2 i9 h' _ - q# N, o, C9 X# d5 c, h if((nWords<<1) < nBytes) 6 n8 Y4 I5 W7 g { V3 G4 [7 \4 d$ p4 ?. c+ ?; n" }/ z /* TODO suspend the task */ + @3 K- |1 w5 F( W2 m return (NULL);/ v# ]$ v" G( _9 ^& r' M% \& _
} & g, u, ^5 ?, S$ m ' [/ ]2 ] j9 M! ~6 Y3 G P4 X" J if(nWords < partId->minBlockWords)$ ~! P! g" O% d A' ^& n( n
{ 5 E$ j& t' O* a* ^7 |: R" S nWords = partId->minBlockWords;5 J. ~6 |' \( \1 Z
}. L ~. g' ^9 ^; i$ @0 `
& C# G7 A3 ]% S$ G# k/ s7 r /* TODO task the semaphore hear */$ T; A* d7 z; Z2 S! A: D
semTake(partId->semPartId, WAIT_FOREVER);) ~- O- n+ ~& t/ y5 g0 R/ Q' c3 E
pNode = DLL_FIRST(&partId->freeList); ( a) h5 U0 E& V- h( |8 a: U nWordsExtra = nWords + align/2; /* why? */ , }9 g6 G# r2 Y1 @ 0 `" b/ W1 ?* s( q* k! ` for(;;)6 c$ l+ s- G9 r. {4 M3 H5 }
{* e) [0 X0 F7 I9 _3 M
while(NULL != pNode). _* {9 V# Z8 O$ S- R8 l5 B8 O8 U4 p- Q
{ 8 D" s+ r: `8 u/ S3 M if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || E7 x6 K; y' x2 b6 x6 E ((NODE_TO_HDR(pNode)->nWords == nWords) && 1 t/ \: p N3 S
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))* j- a8 B# j; J% g% J
{ ! z8 z' w* C' d0 Z7 F break; # X& M5 e; I, L, b4 J0 i } " j1 K4 z$ b9 k $ g* X2 N# I/ ]; F pNode = DLL_NEXT(pNode);+ M' u7 d% D# ^. c) I6 ^4 t
}9 e+ Y$ k6 L2 R: T
% H- ^! S! {- J$ m5 z( F# X6 @ if(NULL == pNode) , a, X. ~/ E7 I$ K {& y7 B% n: X' z" _3 V: }7 h q
/*TODO give the semaphore */+ U# e' u! e( O! C/ N6 u
semGive(partId->semPartId);' g1 S6 I3 D& F. Y$ \8 [) K9 G
return NULL;+ u! ]5 w3 Y: t6 R" y. ~ N& L
}& z! I0 I. [: x v
4 o8 W% C4 Y3 j
pHdr = NODE_TO_HDR(pNode); ( t4 X% O/ F' O! f2 i. K/ e origpHdr = pHdr;7 {0 [ ]/ G/ _' M
( j; |0 B# i* y# P4 \) o9 q5 T) G pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);- I7 L6 _ ?- C/ W5 V; b/ [
if(NULL != pNewHdr)$ b) Q7 @, ?1 H% Q; `* i m( v K
{ ! o2 Y0 B4 X# _1 J: W pHdr = pNewHdr;9 A+ `+ X5 A( D" b7 i# L# ^
break;& ]1 T* M7 I: Z* |1 Y
}/ T" o) j6 v, `! Z- z2 V$ Z! M; s
% S5 G9 a0 r1 s; i% S+ _( j
pNode = DLL_NEXT(pNode); ! q# m- M* W; B. q( a2 ] } $ b6 v$ t' F1 z# I; Q3 i% b% N; M 9 @, j$ _4 P J! h( d pHdr->free = FALSE;1 F5 V; f9 f7 O2 N! V
partId->allBlocksAlloc++;' n( F1 x6 l" c& `+ g9 \$ A
partId->allWordsAlloc += pHdr->nWords; 1 m8 N! H- q4 F' Q* n4 k partId->curBlocksAlloc++; 0 B- t/ ~5 i( \& H5 _6 ^ partId->curWordsAlloc += pHdr->nWords; . e: g/ V1 Y% f8 {+ l5 p( E; ]8 V3 s3 U% N% N, _7 w9 r5 x6 u! X7 S
/*TODO give the semaphore hear */. w6 ?# J, V( y
semGive(partId->semPartId); ) g! s2 T* X% |& d; j/ D" z$ C return (HDR_TO_BLOCK(pHdr));' k) {, M* ]/ G* I. x9 x/ J" W9 z* V
6 m2 m" X$ ~; ?void* memPartAlloc(FAST PART_ID partId, unsigned bytes) / D- ^; L/ R. C{, F2 R" t+ t" O1 y
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);" V4 g z1 x7 E8 l0 J
} 7 l( Z6 X, ?2 I% U* q 1 c9 j% u$ q+ I/ Q6 X' ZSTATUS memPartFree(PART_ID partId, char* pBlock)1 b& I* L2 g) A X3 g% e: K
{ 2 f1 x% X0 m% L w FAST BLOCK_HDR *pHdr;, F1 f; f: l' U* D+ a. _
FAST unsigned nWords; : [; p# j% R6 {2 w8 G3 u( s FAST BLOCK_HDR *pNextHdr;) w2 m# X6 O* ]8 {; R, ~
- T% L8 {6 L5 k
if(!IS_CLASS(partId, memPartClassId))8 [+ _' S2 E( z4 o- s- s
{( x0 k" }4 A' N$ i W* Q1 y/ _
return (ERROR);# B% C U m5 K9 L! `4 r
}# W/ {, S X) ?
8 @5 Q: e/ L) C" @; @9 t$ T if(NULL == pBlock)/ P: L9 d1 |: T1 {# e4 P3 M5 n5 z
{& e. k* g' `3 y. b8 G' F6 \2 Q
return (OK);* j# a; h- Y0 i. @3 f
} % w& X! q z; F2 q2 P& v+ j ! Q! i1 b) Q; B: J' ]& A/ N pHdr = BLOCK_TO_HDR(pBlock); . ?5 ^! ~+ T7 r) X - b. a9 M! O/ x$ P9 ^ semTake(partId->semPartId, WAIT_FOREVER);: g _5 p" B2 ~
# A' ]+ S9 \( p
if((partId->options & MEM_BLOCK_CHECK) ( V5 c; }: ]3 Y && !memPartBlockIsValid(partId, pHdr, FALSE)) 2 F9 M* s8 b. N { + D( D% A' i4 j- @, w2 P* k, H" l semGive(partId->semPartId); : f& i" i5 \3 p. F& T) V$ Q return (ERROR);$ }9 ?8 g3 _) W9 X; H
} 7 \) {: q! E6 i 5 Z* A4 p9 i2 r' F9 _4 U7 H nWords = pHdr->nWords; + @' s/ s* S: e* I: M if(PREV_HDR(pHdr)->free) / G9 Q' m# v" M0 c6 F: k# a: D {/* the prev hdr is free and than coalesce with it */ , Q/ x! f* ^/ |0 q pHdr->free = FALSE; $ @7 ~8 i# i. A* m/ q pHdr = PREV_HDR(pHdr);" P, ?9 }* k" {1 @
pHdr->nWords += nWords; 8 P( D/ ^' _; G d }7 f$ y" n3 z5 A+ I
else$ r2 b! D% s2 z7 m$ k; R7 F0 ?
{, c* ]! ?4 q; R. `
pHdr->free = TRUE;% x2 s& l& E2 \8 ^+ @
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));% ~7 b8 f5 n! o1 u& V7 G& l) [
}/ p$ b$ l* ]( K0 l8 Y
' {8 y) ~* V% O0 Q/ O3 r( r3 i0 A* v- u
/* check to coalesce with the next */ % {3 Z% W, W7 B( h7 [ pNextHdr = NEXT_HDR(pHdr); ) s' e# ~6 Z" S! z if(pNextHdr->free) ' B+ W7 Q- C2 E6 c" |( K4 r { 6 ?1 T7 P0 x/ d; a- j" `0 U: O pHdr->nWords += pNextHdr->nWords;- y, u O5 x, ` F4 l, b* z4 s4 h
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); + J# ?* Y: x+ d* ~! q }" L: k- G0 O- l; ?1 R
' G6 [0 P8 d& u /* cannot use pNextHdr->prevHdr=pHdr hear */ # h3 X" Z( t$ J+ _8 V9 F; g NEXT_HDR(pHdr)->prevHdr = pHdr;, {) v; N" @/ g u
9 P$ f" ?' U5 E& N G
partId->curBlocksAlloc--; + Q+ ]: I0 }$ v U partId->curWordsAlloc -= nWords; $ f. U2 }, [( m5 N 3 ^: [$ ^+ C4 t! f1 L! S /* TODO give sem hear */- C# C: Z5 D% G, b0 _
semGive(partId->semPartId);% z; ^0 y. K# ~9 v4 F! w
! z" R" \# ~1 G8 Y return (OK); # y3 A# }' {3 B6 e& f}0 ^+ |. k E# r* f3 u% a5 c
2 X( C: ?. g1 rstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)* W: e. }2 v1 ~+ \8 r2 }
{ / I0 X% ^& z& ^/ h; b. T6 Y BOOL valid; 9 i# m7 | y" u 2 C! |* b& O* ?# R, f9 v, s TASK_LOCK();3 Q! {) j8 l+ G* k+ n: {- e' E5 m
semGive(partId->semPartId);0 I! _6 H2 b3 P! \8 \( Z& s
, s: E+ U1 w0 t/ t- Z) v
valid = MEM_ALIGNED(pHdr)2 r: y b2 L1 o* R+ r* w8 h3 e
&& MEM_ALIGNED(pHdr->nWords*2)" [7 `* ]& _, ?; z- F2 t2 H) H
&& (pHdr->nWords < partId->totalWords) % l6 r5 y v8 T5 e9 ?+ V
&& (pHdr->free == isFree)- W5 n8 e2 h* `' P3 Q
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))! t5 G; _1 k' ?% J8 d
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr))); 8 |5 l* U. C$ c5 f 6 }$ H; B5 c3 ]: f semTake(partId->semPartId, WAIT_FOREVER); I: O) S% P+ |- U3 k TASK_UNLOCK(); 5 P. w! F, S& j; I3 v8 s: B. f' S0 G/ k y8 ^) a- u
return valid; 8 O! k, p6 O* d, T& `; z- p, J) q% r}% ^! W+ j9 E5 b. u, I
- {: @) L$ i; k, ]' O
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId% |% w+ ^0 ~; _( }6 m) h7 D+ g( L
, FAST BLOCK_HDR* pHdr $ N/ M- t7 g& n2 c , FAST unsigned nWords5 u) p3 O$ I+ F$ i4 Z# I' W8 G- o
, unsigned minWords 5 y& F9 e' x$ i' r, a , unsigned align) 4 U1 ^+ M' {8 }4 e& g{7 t( P8 e0 A2 r1 w+ a5 b' e. ]
FAST BLOCK_HDR *pNewHdr;( g! ^" F; K1 P t
FAST BLOCK_HDR *pNextHdr;) C/ X$ Z7 Z( J
FAST char *endOfBlock;# f/ c& [2 z0 T# x
FAST char *pNewBlock;2 M/ U# |+ @% |" L
int blockSize;; w, }% v8 F9 C2 M/ J% l
) E" l5 s+ _ O5 y/ R: L( R endOfBlock = (char*)pHdr + (pHdr->nWords*2); ( i6 T2 V5 \4 g' s) H 9 h- {! b4 N7 S8 I pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));1 U) Q7 |& ]8 d" P
/ f8 J; F8 U$ o9 b R
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));& T, ~& `) ]; ]/ e! \" o
' U3 W" X4 f$ q% I& z
pNewHdr = BLOCK_TO_HDR(pNewBlock);0 x$ [+ @( \/ N/ s' v1 M1 w/ K1 B
1 G V4 O/ V+ B; Q* Q$ Z. y: w1 R
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;2 `+ P% z4 I. c; E
$ y( ^/ M, ]6 m2 y9 b& C! O if(blockSize < minWords)# ]5 `5 O+ [- W/ W
{ ! Y1 j/ O' ^; T* V% c if(pNewHdr == pHdr)) g% D ]" W1 m! ^, X- ]2 y6 @
{ / v. `1 t9 ]5 d% v* j dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); 5 f% A0 c8 h9 v8 w: [+ H" A }; z' A- X0 ^! G9 v$ `4 p7 H
else 7 e0 | f: u6 ]' y# l) s& R { + g0 c6 C ~# z return NULL; 1 e4 z0 r% I, U9 Z% q2 S8 | } r! r S6 G3 H% m# ]! ]; c
} ) L; q+ B. a$ z/ ?. P else ! H* L" N; l9 w, D& H { /* recaculate pHdr */1 K- a1 O" [2 _: U. n
pNewHdr->prevHdr = pHdr;0 `( ~0 I( w* P5 x5 N" S3 A
pHdr->nWords = blockSize; " ~$ _% D- y) E9 ?9 ^ k1 _. E } ( V$ I8 E& Q- w: N8 j5 p3 D* H) ?) T! _
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)) / U% ~/ d% q0 v2 u& q7 H9 u {) y( ~: p" M5 L: {
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; |& [$ w: P, Q2 y, K. g3 K
pNewHdr->free = TRUE;9 b6 t F( F: r2 P, v7 Z! ~
7 r5 `3 j/ |+ \6 j! L: a
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;6 P, `1 v" J0 l8 l& \$ A
} 1 F" S( F7 G4 e/ y& X6 q else a+ d3 F* i% b( c& A {/* space left is enough to be a fragment on the free list then */ 9 w: X9 c& f1 ~0 ~, I' v pNewHdr->nWords = nWords;( B/ i2 U( I/ }' c7 s( I! W
pNewHdr->free = TRUE;$ \* i4 H2 c$ H, B6 ~
* e4 K% z" h! v pNextHdr = NEXT_HDR(pNewHdr); 1 G8 q. ]5 s! O2 `+ L" k+ Z /* words 包括BlockHdr */ 0 U+ _5 P9 X8 Y pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 W8 X. }* m) d8 S* H
pNextHdr->prevHdr = pNewHdr;2 h! l2 V% }+ X& J. x
pNextHdr->free = TRUE; m, q$ ]( U Q; `1 F3 Y + O8 r( L$ I* l Z/ o dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));6 y! U* Z" \1 I6 o