4 d) m* p8 q" v, _0 Y+ I (* memPartSemInitRtn) (partId);$ }+ Z& X$ @; f& T7 h& q6 J! C
# r* {1 e6 k2 ]8 W; Y( S
dllInit(&partId->freeList);+ F4 B s( o! ^: n' H2 X0 e( t
5 [, E* R1 J2 B5 t4 N
objCoreInit(&partId->objCore, memPartClassId); - X, a( D% Q) ^- a( z: j4 R ) _1 [0 b1 @0 V9 K memPartAddToPool(partId, pPool, poolSize);! ^/ `3 }$ `9 i u
} Q/ X2 X H8 }& z- ?
! a! Y4 z0 |5 `) `5 b
STATUS memPartDestroy(PART_ID partId)% {& ~2 L8 J6 [
{' c9 J7 X2 u& F- |! p) W( X
return (ERROR); ! Y ?) p& Q E2 \* s} ! n" E5 r! }7 G) l2 u/ O S3 K- K& O0 z$ e" ~9 g
void memAddToPool(FAST char *pPool, FAST unsigned poolSize) : ^- E% f) t9 H{ ! s0 R" ^7 q. O2 u4 a# Z (void)memPartAddToPool(&memSysPartition, pPool, poolSize); * t4 g7 t4 G5 G& A6 P} * Z4 J0 a0 N" @% [, P3 P. u. X7 y A3 R5 @" i- b, ]3 [
) L- g$ [' s, \. E! Ostatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) , d" R: j) P$ [. ~/ _% W{: z' g# o* s" h" P3 J
BLOCK_HDR* pHdrStart;& t# k- D4 U, F, d
BLOCK_HDR* pHdrMid; ' B! g5 i8 [' S N, ? BLOCK_HDR* pHdrEnd;) N& w) g+ c1 i) q* X/ @3 T3 W
char* tmp; , E8 k* x' r$ ~7 C; z int reducePool; 0 v4 l x' e) n) y" I * J+ m5 N5 P q9 y/ c* l if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ E: p6 a1 Z: ?
{' ~/ a; {! C; t8 [; k1 t
return (ERROR);2 L/ k2 {! j4 u$ x) W. U
} 4 F: R6 U0 o! S" Z; n1 ?& m2 ]. O% `3 O: O) a0 e
tmp = (char*) MEM_ROUND_UP(pPool);3 ~' ^: O8 ]# N+ e( O. U
reducePool = tmp - pPool; # W( X7 } S' [. E! }' W, h# r v" J. j# J1 ^$ _$ \: s/ Z' `
/* adjust the lenght */' y. R' F$ @6 p+ V! {
if(poolSize >= reducePool)0 Z& E' ], o R: p
{ . g, V1 j! N; d poolSize -= reducePool; 6 s' Y# q* k& H& @3 M e0 u( { ^ } + Y6 v3 C9 ]" a else g3 K5 J* L# @
{ ; a4 Z6 M$ R8 r+ w% k+ r7 ?* U poolSize = 0;/ y+ ]0 I1 [* N. ^8 |8 G# b
} + W# P& e4 v7 ? pPool = tmp;3 w8 s, L: s" U/ g6 R# R$ `
% [; A, Q9 l' |+ e6 V& ]# a2 b* a0 f
poolSize = MEM_ROUND_DOWN(poolSize); 1 Y) u! v' n1 _3 m i' _6 C/ b1 I ) d# e% {% T2 M) u# _" m
/* at least one valid free block and three header blocks */3 Y( `2 G- {" |! i: f8 x; c
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) 1 X+ `& c' L" i$ E {% t0 m+ P: `& G N, Z4 d
return (ERROR); % {. C& B2 X R L8 F: P w } , N! ]% ?% Y! Z. c/ J* \5 p1 t$ P6 W7 }5 I# H% n$ p. I
/* initialize three blocks */ & X6 [1 s: A {- {- ^ pHdrStart = (BLOCK_HDR*)pPool;5 ~5 K0 Y( i; q) Z5 H
pHdrStart->prevHdr = NULL;. M2 Y9 W8 X0 s2 t; Y7 s1 p2 Z1 C
pHdrStart->free = FALSE; /* never in use */ 8 U, r& P1 R% M1 b9 P pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; + i* m, ?3 Z' l3 r 4 m5 U( O1 z; ^% u8 ` pHdrMid = NEXT_HDR(pHdrStart);' n4 X& p2 J! \4 _7 x0 J) T/ q
pHdrMid->prevHdr = pHdrStart; 1 I5 ^" U6 ?( p( X0 Y pHdrMid->free = TRUE; /* the main block */ / t& ?) [! \, }3 B" M/ \$ | pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;+ y3 B9 p+ Q8 W/ v4 H6 x1 Z( b* ~
2 D7 j2 ^# A Z n3 s' P
pHdrEnd = NEXT_HDR(pHdrMid); - l( a4 {/ b1 I2 z+ W+ K pHdrEnd->prevHdr = pHdrMid; + l+ C# n2 U8 E( q6 S5 l8 _4 m pHdrEnd->free = FALSE; 8 @8 r( w" P2 w9 c, ?: V pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1; d9 e7 {' c3 x' ]7 n/ ]$ \
& x6 a: Q5 X) `# C2 l /* TODO take sem hear */ 5 P+ @* x/ S/ X0 o6 R5 V5 | semTake(partId->semPartId, WAIT_FOREVER); . F E$ L2 A8 y* Q% @1 x . N4 p, @+ ^ }7 Y+ X+ I3 ?' p
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));4 m' m" Q0 ]& I8 i/ i; b
partId->totalWords += (poolSize >> 1); 9 M: e$ M+ A, [3 A2 U) h, |% i+ @ / o1 G A- a) N5 R8 J1 { /* TODO give sem hear */' D. }0 x% u- D$ l
semGive(partId->semPartId); ! ?& y+ C I2 ]4 q f/ u! { - Z$ e4 L3 r& L* Q+ }: Y$ u# U + l" R7 M) f# n& H& j return (OK); 5 G7 o& ]: `( Z+ _} , T$ v4 }% q1 r$ W' V( s- t, ^6 Q* g G( q3 ^ ]. Y/ v. u
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) & V! c6 ?- W, N3 p: T2 |{2 p' E( z; d1 |: }; t7 c M+ c
FAST unsigned nWords; % g! e" f1 i" K. j: w. V$ ] FAST unsigned nWordsExtra; ; a0 u9 D v. g0 j) W" ` FAST DL_NODE* pNode; 1 s& ]: t6 s r% D3 Z) j FAST BLOCK_HDR* pHdr; 5 F, N* M& }, Q7 _/ a9 { BLOCK_HDR* pNewHdr; ( ]9 h- H9 _0 K6 e- C BLOCK_HDR* origpHdr; % A2 w3 S* H: h3 v3 l1 I- @3 P: b0 p& {# }
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */5 W5 f" Y `4 K7 L7 b/ j- a5 g
{" i2 G, w: P1 [ u( y3 ?% ?9 Y8 h
return (NULL);2 J; U" Z( Q! Y- Y
} ; v# u+ @+ d4 [' T$ r9 K% G1 Z+ D8 K8 C' Y! F# U9 y6 }/ B3 _
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;$ q+ X2 E- X& L
: K! t" D' d2 |6 E3 ?$ Q if((nWords<<1) < nBytes)+ L# y* X% t/ g2 u) U: W$ C- X
{# \7 }( O7 |. u( @3 e# b7 D* h
/* TODO suspend the task */ ' U+ [8 R& ?0 q. ^. P& Q- A return (NULL); 9 ?0 d6 m. m3 s }1 v |) s5 L: f9 K
/ X6 B N! E7 A5 F: f if(nWords < partId->minBlockWords) # ~7 _6 T9 R' ~) d0 p8 R { + h( O: i% G1 `- r0 z( Q( l2 z& N nWords = partId->minBlockWords; 9 W3 L! J* d# F% U1 G) x/ N }+ z) x/ B8 U# m, q @
& t: S% b2 \; Z- p /* TODO task the semaphore hear */ % H/ }0 T6 [, c, H semTake(partId->semPartId, WAIT_FOREVER); ' c( }, B+ ]* Q pNode = DLL_FIRST(&partId->freeList);8 { }" O) ?0 y* |- Q6 M
nWordsExtra = nWords + align/2; /* why? */ - U: q: r0 W& U- U5 j8 _ 3 b3 _) E. x# j+ ^9 L) y for(;;) 4 r. W* d; g; E& q) ~ { 8 f, }* l4 y, d( I while(NULL != pNode) 1 Q3 G$ ]$ D. w2 l {7 p3 {( h! e8 m; a# F9 d3 o
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||' u; I. {. U( t/ X
((NODE_TO_HDR(pNode)->nWords == nWords) && " r% m3 W& z/ P. Y* w (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) % `+ J* Q; Z- ^& U4 v+ c {7 g+ ]+ R5 d$ ~
break;* ], a! i2 S8 d8 b! r* X) j5 |
} 2 w; A* W/ O: y+ N; G7 `' P ; @5 k8 x' |$ x$ K0 C, q& O/ g pNode = DLL_NEXT(pNode); A0 p" s6 U! t; B# i }, w" ^- \& O& D z5 B
: C, ^( S+ {* U# N8 y if(NULL == pNode) 0 L) ?8 X8 {% s& ^/ M0 w { 9 Q6 P& h4 Z G /*TODO give the semaphore */4 D- X4 q8 ~4 F) c
semGive(partId->semPartId);8 f( U0 t, K! k: V/ O' h; J: D# W
return NULL;4 \4 W- o7 B+ i0 U& P
}4 \" \8 F% Q: P6 E/ t2 [
: s2 P. P" o, r Q7 d& G1 I pHdr = NODE_TO_HDR(pNode); ?# f p' D9 \) a, A! T
origpHdr = pHdr; k& R4 ?- M7 f% t7 y2 M, Q6 o! I2 Y0 T: ~; p
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);5 ?# f$ r) E' @4 O
if(NULL != pNewHdr)0 E0 S8 `: I1 ]8 s
{: s) A' l# ?( t8 j+ |7 Q& p( |
pHdr = pNewHdr;' G- ]1 ^' m1 g1 ^4 a1 f. d. F: F
break;& Z+ D9 w) g y: t( @
}/ K$ X/ D! k6 i3 O8 R: W
2 o# }* U) L; w* V pNode = DLL_NEXT(pNode); 4 A0 s* Z1 m) g" h* ?' n }+ P( f7 w( F8 x2 t* k9 `" T% z
9 z8 s7 D/ }: o; [0 w7 _
pHdr->free = FALSE; $ y: z5 y# b' O! [5 N partId->allBlocksAlloc++;3 L: r) \6 a( I) Z
partId->allWordsAlloc += pHdr->nWords; ! g2 p' Q( b) d l3 Z# g partId->curBlocksAlloc++;$ h; \3 \( I0 N1 O$ H! e/ |/ h
partId->curWordsAlloc += pHdr->nWords;& D3 {* k8 S/ n; c+ N% O9 h
/ z( |* F* q* r5 ?' s /*TODO give the semaphore hear */ 4 Z% `6 H9 w( Y& T" I9 c% C semGive(partId->semPartId); # g a; S4 h* j: T: J* N) t return (HDR_TO_BLOCK(pHdr)); ! {; V' p; t7 D( [9 m% ] 4 t" Q# e' n# z6 {
} 2 j; N: o( L% S: p4 Q# x3 ]* T' X; m4 ]6 E, }
void* memPartAlloc(FAST PART_ID partId, unsigned bytes) 8 h" i; q4 E# Q{ 3 R' D1 h& s8 j. q* }- }+ w+ a: u4 k return memPartAllignedAlloc(partId, bytes, memDefaultAlign);( E& e, z+ E) ]% \- t, |
}2 Y( h A: r' |& U: V) W7 ?& \. h
2 m4 L, D8 ]% n: \1 JSTATUS memPartFree(PART_ID partId, char* pBlock) * _/ x/ P1 D/ `{ $ l$ v6 H+ ]/ w5 U- W! x FAST BLOCK_HDR *pHdr;( i% r# U- k1 Y
FAST unsigned nWords; % [+ B5 S/ V3 P& e6 d" a: L! M FAST BLOCK_HDR *pNextHdr;/ P& A3 W7 C, O4 ?. j+ z2 S8 b
; k& a$ y+ B1 H8 N5 X* z
if(!IS_CLASS(partId, memPartClassId))7 Y; i% V' N4 Z, B
{ 2 |( Q5 h! M6 T! Y; k: U4 u- L return (ERROR);% s# p6 b* T# |1 _8 y( n) e
} V _2 s# z! E1 } H& a' y
( v N2 g6 ?8 F. n if(NULL == pBlock)2 m6 N4 u) f% Z/ O' ]
{ $ n9 L2 f5 t) A5 o return (OK); * p6 N2 h2 |: b- R8 x- ~ }8 a1 [' U0 ~7 D3 |
: Z" t [1 x. [. k D pHdr = BLOCK_TO_HDR(pBlock);6 I x4 d+ U# h' q
5 k# Z" _9 a5 G! n
semTake(partId->semPartId, WAIT_FOREVER); 5 A0 p( I4 [. v0 L2 S2 d) ^ ) }2 ^9 U) j' I1 N6 E% H( N if((partId->options & MEM_BLOCK_CHECK) + c3 m U0 Y P9 _) r: A( T I && !memPartBlockIsValid(partId, pHdr, FALSE)) / w I$ W! g2 Y { * D C8 y; n0 o) x# @* T0 m" W semGive(partId->semPartId); . |6 c& v6 V" C; q6 Z return (ERROR); + H& H7 T; i r, C' _# O- R }- c$ A; x$ }0 {
, U8 ~/ z9 G' m( Q" q" J2 _
nWords = pHdr->nWords;) U; n, |* k% O& A8 w V
if(PREV_HDR(pHdr)->free)' a: B2 t8 \+ \2 ]7 N6 M5 `
{/* the prev hdr is free and than coalesce with it */ & o. O' x! t8 l( q7 ~ pHdr->free = FALSE;6 q! N& W- l3 H
pHdr = PREV_HDR(pHdr);3 b- `9 u j* k" I/ V' q5 Z! U" L
pHdr->nWords += nWords; ! f! w3 C7 m3 l8 k7 T9 o }1 u" V* [; s9 [
else 5 p7 G/ W o; U {2 L3 u% l) a, F- M
pHdr->free = TRUE;" I3 L6 J8 b7 M/ _4 `
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr)); + E' t) X5 M" I+ {! P } ( [+ N1 K- K6 W ^3 q 7 u8 C; p; ~0 Z2 o, P7 |" N& A /* check to coalesce with the next */ . P3 w5 J+ u' L. `- ^$ \# u2 t pNextHdr = NEXT_HDR(pHdr);0 u0 X; D8 ~5 F' p" f$ y4 s8 M
if(pNextHdr->free) ' S; y- s+ P6 n B$ ~8 Y. ? { 8 y7 k& N9 Z4 P9 A1 I pHdr->nWords += pNextHdr->nWords;$ ? Z: p% k# B3 m; ~7 A6 X5 E
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));, d8 T1 m. F5 b) X% |5 Z* N9 o
}; E& \: P# `: F; f1 Y6 A n
/ b2 P) C' y; t4 l6 h- w i
/* cannot use pNextHdr->prevHdr=pHdr hear */ ; u) F c) G- ?% M$ X+ s NEXT_HDR(pHdr)->prevHdr = pHdr; 1 `- M) X4 s+ h% N$ S" ^: M4 Q/ D, H. S" m3 M
partId->curBlocksAlloc--;( A) L( D7 r" Z) c( Z- U
partId->curWordsAlloc -= nWords;' A2 ~% v, A* R6 J5 Z$ i( R
3 _4 B+ I8 L3 j/ R /* TODO give sem hear */ ! h- B5 m) c0 I2 H2 I- f8 D semGive(partId->semPartId); " J6 @. n8 x6 H3 w 8 i8 S0 D. w( a) b return (OK);& c2 x4 F C: T$ T. \, _
} / P6 z) ?, F7 T; V/ b4 D# _3 P. U" H8 d' R* c% ~+ D4 n
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)( W' x! G. M) w
{ : n1 m$ X1 V: h4 O( y BOOL valid; ' e" U" \+ U. q ]5 e, y( Z) Z* y$ m! \
TASK_LOCK();! S, D) O/ u4 L
semGive(partId->semPartId);8 t& S: r6 V( d# y e; W }
' U- H* Z' I$ m$ N+ M7 k; [ valid = MEM_ALIGNED(pHdr) * a: I& n7 B5 p- B2 M' y && MEM_ALIGNED(pHdr->nWords*2) & r5 I( ^- {, M, J* t# p && (pHdr->nWords < partId->totalWords) n5 I T8 F+ U0 `* M2 ~0 T && (pHdr->free == isFree) ! _* g O& S- v: Y" c. o && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))! T3 e! s/ L1 }
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr))); ' w& d2 y8 x; L. } + N. V$ A/ M5 G: _# \- o semTake(partId->semPartId, WAIT_FOREVER);+ z5 c2 q' H2 j% _# }
TASK_UNLOCK();" r; q4 U! C7 Y- v2 s- h, m$ Y
# W6 Y* G$ D: @! H. j/ @ return valid;. v8 V$ M; F1 l6 G# @! u5 z0 a5 M& p
}: t& n5 g, E# L( `0 y+ e
8 n3 y; f' Z5 c( D: q* i) ?static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId6 Y( c& Z5 s! S; `3 a+ V& {% f/ a2 j
, FAST BLOCK_HDR* pHdr( ~* O/ i5 u( L+ T' Y) I
, FAST unsigned nWords" l* r( r& l9 b- @
, unsigned minWords7 p1 o0 s/ K) R2 M" O& m( E! n
, unsigned align)- e R+ j/ `! ~
{ % R8 a* f7 o: d# |/ I. k# p FAST BLOCK_HDR *pNewHdr; 0 Q8 m0 s) x" W! o FAST BLOCK_HDR *pNextHdr; / ]9 v5 m" g+ n4 L! r; F FAST char *endOfBlock;% y1 t5 ~5 P- i* P1 n g k' E) ?, X
FAST char *pNewBlock; " F$ y+ _+ {' E; z$ k$ } int blockSize;, Z5 N; h( W, Z6 P% H$ m$ Z
$ ^% B1 H& b$ s) h! q/ l6 n2 g
endOfBlock = (char*)pHdr + (pHdr->nWords*2);- z) |) V2 p0 G