: g6 D; Z2 o& Z+ Wstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);9 L3 t' X- b1 T4 j
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId$ g+ a6 y* G- a; {
, FAST BLOCK_HDR* pHdr ( l3 k3 _8 O6 C \! | , FAST unsigned nWords ' y0 j5 e& o8 l% r% b' L , unsigned minWords " U9 V- I2 S$ p8 E. Y2 [ , unsigned align);: I1 y. h* `7 l" H. F6 E) O# \
$ R3 n' x! p3 c4 qstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);: b! j: r9 y& J* @; _4 t8 v' @
7 q: G0 `4 i2 \. z2 i" j
STATUS memPartLibInit(char* pPool, unsigned poolSize)1 x$ ^: ~/ t S6 |# n( v
{% |0 g+ L/ U2 a n* [8 j# j
if((!memPartLibInstalled) && 4 Y K. l0 A, l# T1 M8 C0 x
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore) 6 G P" P. y% a1 _ , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy))) 5 h; a1 F/ J4 a: C+ P { , _( _4 e4 B/ e+ e6 l8 b9 r* n memPartInit(&memSysPartition, pPool, poolSize); , f2 {! Z5 o h2 t$ \+ i7 J F2 R9 r% I memPartLibInstalled = TRUE; ^# w. \) D* z! H" t2 u } ]4 V6 F; {7 h" j( A ' @( |, ]5 G( ^" r return ((memPartLibInstalled)? OK : ERROR);4 t K5 L3 y$ K4 Y
}' a$ X: T* e g# D6 p# g( p
, i+ H% Y4 @1 S+ U* ~
PART_ID memPartCreate(char* pPool, unsigned poolSize)! [& |9 Q$ k/ S7 ]( ^, |% `( U
{1 j2 b$ v. z4 a3 d
PART_ID pPart = (PART_ID)objAlloc(memPartClassId); # q6 b: D5 }/ t: [: _+ l& U3 D
if(NULL != pPart) 8 g9 L a, y# | F; M( @ V e { & X! ]- A5 s/ p8 |- b4 y' L: w memPartInit(pPart, pPool, poolSize); 4 t2 r0 }& B: U- k c9 _. e. [ } H: t$ C: O5 q; r3 T4 E- r3 H# D
return pPart;5 f5 P# G6 I7 f0 y0 r1 n- D' v
}' ]5 E$ {9 x+ n) k% B6 e
" O7 \2 Q; {. [/ w8 fvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize) $ j# | f& D' U+ n{$ _* C7 D* Z! |) v
memset((void*)partId, 0, sizeof(*partId));% a/ Q M6 G3 H/ r
8 `' [% ]& ^; J* C7 i' A3 u
partId->options = memPartDefaultOption; 7 r2 M* C) r0 ~) t- t7 Y partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */ + a% t, x. @/ q3 c 7 d- f' c) _6 x) v5 q' p3 c& P9 P" [ (* memPartSemInitRtn) (partId);% ?9 _1 B5 A9 |( v6 v' l
) O3 v9 @% X5 `0 b) m* i$ V dllInit(&partId->freeList);3 B# t, F- ?+ H: A% Z F
) Z; p. C) G; l2 `
objCoreInit(&partId->objCore, memPartClassId);7 S$ t% C6 a- u8 r
9 E% n) U" L; z: e/ k
memPartAddToPool(partId, pPool, poolSize); 4 z- i9 N Z2 Z' [: m* H}- s0 C0 a; |7 e, J2 A! q6 \- \% ^
/ r! t- v) B4 J6 P+ G
STATUS memPartDestroy(PART_ID partId)' ?/ x" o+ ?9 l! H9 O& T
{ ( D% V: h2 b8 c N# l& ]( H return (ERROR); , Q* O {! Y% e" z9 t2 |. u} " ?' L1 r( [$ E' u/ w2 }7 {3 m1 B; X$ ^
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)& b: R# _& m$ E9 a# C
{ ( `# @7 I2 W1 B4 U2 n# S (void)memPartAddToPool(&memSysPartition, pPool, poolSize); ( E. i! v) e3 X! }: o2 C} 9 d3 L0 |3 {& j+ J* W) @, K3 {: L. B
+ U* B$ g+ ^ k6 ~' c5 M( sstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) . F& E9 e4 r+ t" ~{ 8 p& @5 d% v* a4 G8 t9 }9 f BLOCK_HDR* pHdrStart;' ~: L/ i2 n' R6 U
BLOCK_HDR* pHdrMid;0 P# ?( a9 u1 i5 R" ~+ _
BLOCK_HDR* pHdrEnd;5 s( S# F" O) q/ Z! w2 T; N7 I
char* tmp;3 U" a2 k3 @( D' q* m+ [8 n/ y
int reducePool;' B! B$ S+ W) h" h- H3 I) e
9 \$ G3 Z4 m8 Y) X+ Z) R
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */; c# c" X# ?2 Z n" n- ^' ?
{ . S- v7 ?* ~: t4 }; z5 z3 t, | return (ERROR); 8 S9 J Q- i) d' z$ J' C } ) i+ X! C A. u, @) t7 W8 _- _# B& L/ M& I. l2 S% c! r6 M
tmp = (char*) MEM_ROUND_UP(pPool); 0 P% {7 l9 G- [9 R& p- m4 \ reducePool = tmp - pPool;- u2 c: ]1 r2 F
' Z& R) j; g( ~' B" T. r /* adjust the lenght */1 v. _0 a8 \: L% `4 I- ]
if(poolSize >= reducePool) : g; r p0 Q( m; E {+ C7 J A5 G& C
poolSize -= reducePool;- I: q% i" G' V! K M
} / q7 h5 y# ?- d* F! E! i4 c" k else1 P% ?, ~- q7 b+ i |
{ 8 C; _% V8 {9 |" a8 P poolSize = 0; : L7 u1 `9 x* t/ F% Q; s } % x" I7 b! ?9 f pPool = tmp; 9 G! ]+ m" r y. [7 Q & M R' I, B4 n1 B+ u# r! `
poolSize = MEM_ROUND_DOWN(poolSize); 1 ]) `. R- L* \% \; k8 g' S4 u " d q$ ]3 b" X! c9 U' S, P" Y' X
/* at least one valid free block and three header blocks */ 5 |8 S8 V) C0 D if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) , m5 ?" q4 ?, U2 V$ i0 M3 V! \- x {$ D( O# S3 H" V
return (ERROR);5 a; _$ Q: _4 m% X0 L7 z* _
}3 w8 }2 u7 @: r e, C+ ^+ i
% ~! i7 l3 f; Y S9 h /* initialize three blocks */ 9 K2 F) h: q0 L* L0 t pHdrStart = (BLOCK_HDR*)pPool; , I& {2 _6 c$ R: l' \4 T pHdrStart->prevHdr = NULL; ( n) {, c: u4 @" |0 L1 O C pHdrStart->free = FALSE; /* never in use */ - g' U" N, K) Q @ pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; # T8 g2 Z! V- [ m% n2 [$ j) e7 y$ P pHdrMid = NEXT_HDR(pHdrStart);6 b' ^' S; ?3 H" x
pHdrMid->prevHdr = pHdrStart;/ L7 I$ Z9 V: y7 x
pHdrMid->free = TRUE; /* the main block */" u) B/ ~% L5 c$ G6 r' E
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;2 U6 y4 A2 P; x! L
, y' c* J5 z$ W7 F pHdrEnd = NEXT_HDR(pHdrMid);3 t4 T9 t" Y' n: o( E
pHdrEnd->prevHdr = pHdrMid;: [! `1 A# i3 `- e# [0 V
pHdrEnd->free = FALSE; ]$ {) }1 }" V4 ?5 B
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;& Y& Y4 j3 z* O9 }! ?4 H b9 V" S
1 u" H+ @' K3 P# @ X /* TODO take sem hear */) j" |8 c1 T% m/ R v* R% ] y7 n
semTake(partId->semPartId, WAIT_FOREVER); ' M% C# y2 g6 U/ R, f . N* f7 w, A# J l dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); $ p; [ L# a' @" ~4 T partId->totalWords += (poolSize >> 1);7 @" n: c! N7 i5 u4 ]! R. Z5 S6 y6 r# S
! @ Z( k8 K7 G; J /* TODO give sem hear */" N3 j* L, Z% T! ~$ L) A
semGive(partId->semPartId); - l1 W/ G5 E- e& q) Z/ q8 K " H3 y; S5 `7 ]7 i8 {2 X( d u. v3 b5 D$ ~* @& X8 R7 s
return (OK); 6 Z/ r) F$ ]. }' @ b}. k \8 U3 O9 o0 Q: E" z
1 f1 A' K; U( B g. Ovoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)" `9 M% i5 `* Z% V
{- M2 c8 q. ^+ G
FAST unsigned nWords; ; U: B) L! E8 i: c FAST unsigned nWordsExtra;9 a% B% C" S- {3 S8 X8 c4 V
FAST DL_NODE* pNode; $ ~# W; u8 b( v: b! j FAST BLOCK_HDR* pHdr;9 _! a" o3 t1 U+ v: U
BLOCK_HDR* pNewHdr; & k& }$ Q- U9 K* G! ~' s; g+ u8 f BLOCK_HDR* origpHdr; 2 q$ {" @! |" Z5 |- K6 @$ _6 B- m( Z4 k: b6 H
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */3 x- M: o2 [. N$ I
{ * H: X' ]+ m1 v, x+ s, T3 V2 x return (NULL); d7 f+ |) j/ |6 I
}* `, }, J7 u0 o# R$ B& k# _3 [7 i
+ y, n& `1 u8 E- }& x3 i nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! w: Q5 p6 Q8 v0 I* k& ]3 ^' B
4 i4 P! p* r3 G0 d
if((nWords<<1) < nBytes) 0 h, U: U$ ]% D8 {9 h { 5 u* T, E& g2 d g9 h /* TODO suspend the task */6 j% j4 J$ q. G, i$ A
return (NULL); : t3 q- [* t- x% P4 \ } , h1 ?* A7 n8 f5 L% e1 D, L & M4 H4 l$ b/ |+ o if(nWords < partId->minBlockWords)2 h- u+ Q; [ G% H0 L
{ ; x4 J1 p$ ~! c/ Z nWords = partId->minBlockWords; $ r [& O# @0 u2 v# H' L) N }/ N5 ?% y& }7 S6 K' b0 W2 A$ c
5 z a% o0 X8 c1 S2 U
/* TODO task the semaphore hear */' U7 h7 c( l) H, P2 N) _4 ~' {" }0 T
semTake(partId->semPartId, WAIT_FOREVER);. }5 F- d; M2 G# k
pNode = DLL_FIRST(&partId->freeList);5 p! s& ^3 ~# J) j
nWordsExtra = nWords + align/2; /* why? */ 4 M7 O* l5 z9 y6 l2 k, x- G+ c8 X# t, |! n
for(;;)! G7 a! @9 t% ~3 l" G7 N( S
{# b2 i5 S. ~9 b0 Y0 @* i: I: E
while(NULL != pNode) / U7 `5 T( k& u* O" b: E { $ I9 W& b$ X5 J3 Q1 A) @ if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || ' \& i9 B& r5 a. x0 | ((NODE_TO_HDR(pNode)->nWords == nWords) && 3 W4 ]" u; }8 y& y (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))7 r$ H; G1 t5 y
{ $ O# u( n2 C2 [' _0 R# W8 J- d break; - R, F! o" `6 q' G/ { }0 C# {" N2 `0 C' U
, E! m) N. D& @9 S( N1 i
pNode = DLL_NEXT(pNode); 2 R4 c+ Q1 E4 N' p) w# m6 U }$ q+ I" K1 j; c L% I2 D
1 N2 L. q3 J( ~( Z0 e6 t if(NULL == pNode)) r' x+ D9 q' P% [* V g
{+ C, O8 L/ r, m7 ~7 p/ H0 T8 U
/*TODO give the semaphore */ 1 w. H' y8 _5 C; a p semGive(partId->semPartId); 6 U# J$ B* l4 i; z. @8 K ^ { return NULL; 5 ^+ P6 E' k- h }7 ^ j4 m" ? x- N) S/ e$ [) S
$ V; | x, r F pHdr = NODE_TO_HDR(pNode); , y. @6 N# E' N# K8 ?( N9 [ origpHdr = pHdr;& _ @1 V: b( b2 U) l7 K
7 f3 c' _2 p/ A$ \& d$ c4 ?; N4 e1 ~
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align); + q0 V9 E, i5 |. T& N5 P. r if(NULL != pNewHdr)& ?( r: e0 {- G3 k* [+ A
{- r' c$ l0 J0 d) H3 ?4 c
pHdr = pNewHdr; . Z4 k2 H( P! B& E break;+ v' ]2 f( d a( p P
} 9 u9 b( _' H/ V6 g; f( n( U/ Y( Q
pNode = DLL_NEXT(pNode);! H% c: |; I9 X4 Q6 P D8 @2 z; D
} % I3 ]/ }1 ~2 E# S1 C9 l ' Q9 }; U% Y0 i0 b) ` pHdr->free = FALSE;0 B& V7 T2 @: [$ b, v, g! _
partId->allBlocksAlloc++; * M' ]% K# P& D# C7 | partId->allWordsAlloc += pHdr->nWords; $ t; a. r( |: J% \/ a; ^ partId->curBlocksAlloc++; * k z1 N) o/ Z( P' [0 o# X partId->curWordsAlloc += pHdr->nWords; : r7 F4 L3 R- Q& ` 7 S6 { ?0 j2 ]$ G" w" }: s /*TODO give the semaphore hear */& G* @) r2 `# ]. x( R2 T/ b
semGive(partId->semPartId); R9 W0 c# h( `: W3 J return (HDR_TO_BLOCK(pHdr)); + m* r, |" M% P $ Q6 Z+ ~3 [1 \) v+ Y
}5 }2 d- _! S Y5 e( U
* ?" }+ W9 |+ Z9 s! P( N. D" c
void* memPartAlloc(FAST PART_ID partId, unsigned bytes) * Z6 r, K) `, S{ ) A# y! Y* b9 o/ H return memPartAllignedAlloc(partId, bytes, memDefaultAlign); # z8 A7 [; e' S# h2 p} 3 d& P( o1 z& [8 m$ u6 i5 T; r% x M3 Z5 f& x7 {% b# K: d( X1 _
STATUS memPartFree(PART_ID partId, char* pBlock) ' k/ o8 s: E; U7 z! i& e1 [{ 0 t' o/ N" j) c) U8 M1 |2 j FAST BLOCK_HDR *pHdr;$ i/ K( [8 Y" C ~, N& s
FAST unsigned nWords; ; K/ ]0 U0 Q$ n$ P FAST BLOCK_HDR *pNextHdr; ; Q3 X* d* S8 l# z ) L7 i, B- w2 ~& E6 _ if(!IS_CLASS(partId, memPartClassId)). ]/ `8 n0 \( m- q$ \; T! ~. c' s
{ 4 |# e0 w' w' v return (ERROR);. t7 ~7 q4 c3 D6 A* ~0 r
}. D) q X3 b3 E2 B