}0 J7 I( `# F1 Astatic SEMAPHORE semMemSysPartition;0 q0 n, b3 k/ H i: t8 ^* @" X/ i% X
& i% G% a" A# j! m1 C8 astatic void memPartSemInit(PART_ID partId); 7 s, Z; { n; \. A+ j# D4 m3 ?0 {8 P. T( @0 D6 T/ h' M
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;/ d" }: P% B. T# S
. `6 i7 o: K) |2 a, Iunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK; * k; _& X6 z, ~& K/ B$ a6 j# C4 ~+ u
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);6 U! K2 K* ]+ {; {5 I- H J9 U- W
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId , w( w0 l# |0 I/ J* z6 P: _ , FAST BLOCK_HDR* pHdr ) _7 P; k- E5 _. u2 k, o' R , FAST unsigned nWords 2 W7 E6 t3 J( U% W6 B , unsigned minWords/ o; L- c: l1 f" [
, unsigned align); # f, S2 g. f9 p# u- B" f2 ?1 U1 \9 ^8 X8 o. n
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);2 T& y! V9 U+ A
. B5 O- ~( F( ^STATUS memPartLibInit(char* pPool, unsigned poolSize) 9 o* w; v' E) i' n{7 @! w4 g B% |5 h
if((!memPartLibInstalled) && $ a! W3 p( i# ^1 D% ~) @, I5 P' p0 s (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore) ( Z( I- `9 N& v. |8 d , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy))) ) b, N7 `% [- W! v$ e3 r$ y { . m2 ]' p) [6 i4 P3 q8 v' Z memPartInit(&memSysPartition, pPool, poolSize); . _" w" C" U1 Z) z* P memPartLibInstalled = TRUE; $ o# n1 C5 [5 L7 K } ' p1 p% v. F% \) m2 \ t3 Q; ~" ^, y% H3 F. }. H9 \
return ((memPartLibInstalled)? OK : ERROR);# N# W# E% c, P4 Y, C6 @$ E- T
} : ?: _- A1 P6 E- M* Y, [ 8 Y& B1 O. G2 V1 P, `) OPART_ID memPartCreate(char* pPool, unsigned poolSize)! }% x3 v; f! V1 m+ O# m
{1 ?( N6 N4 h( N9 h
PART_ID pPart = (PART_ID)objAlloc(memPartClassId); 7 D! T. _6 `0 M4 y5 S" h0 ] 3 v6 }1 I% O$ ^# B if(NULL != pPart)- A+ C$ g# c8 f8 c& p2 E
{ . c; D( u) G. [' c% n- L5 C+ h/ k memPartInit(pPart, pPool, poolSize); 4 b, W4 ~3 d1 k/ o }- h9 v7 S/ G( P- J* I
5 ?6 L0 j, Q2 a" V- O2 E1 P% I6 k
return pPart; ) U" d7 v% k" q& y2 z} $ V# }* R- ]# V' n* S' P, j+ j# ^0 W; f5 T6 o8 p0 {% N
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize) 2 @8 r, ^: ]2 H9 S- Y Q, d{ ; ?+ D2 _. h* W3 `7 ?7 | memset((void*)partId, 0, sizeof(*partId));0 n. x/ o; H" |. c
u/ B2 h t* M$ f* T- F: N2 E& d- D partId->options = memPartDefaultOption;+ _, g6 f& o/ k8 y
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */ d. t% F" \5 p* L. T
9 j n. W* ~: }. \' ?7 _- C (* memPartSemInitRtn) (partId); 5 D) H3 e; J% G; N; u3 ~8 n# y0 t8 b0 d& Q 3 G) n( r0 T. U0 N4 i dllInit(&partId->freeList);$ o: z. u$ Y/ ]) V
, ^( N0 P5 P6 @
objCoreInit(&partId->objCore, memPartClassId); % [+ m& c! j0 u' C. F & S- W$ E: J1 l4 b9 z b; x memPartAddToPool(partId, pPool, poolSize);# v, t. C9 y$ l ` r. d- t; ~
} ' h- _- `$ y% z) Z* Y6 N7 k" P/ u; ^2 j2 @7 J1 t
STATUS memPartDestroy(PART_ID partId)8 g- p. t* `! g* ~* n" S
{ 5 k7 ^: f, ~+ s/ a4 V# Q2 D' U return (ERROR);& a- G9 ]5 j/ s9 \# O
} 0 ~1 Q( e$ V+ x 6 x% M* h7 I& K9 wvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize) . ~, \& g5 C% v4 F- t{. P8 H q7 }* J- @* d Y
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);/ D* K2 ?; a& |& E8 R1 M3 }
} 1 \, y5 x# Y: J & B4 j! T6 N% ?" @5 p1 z% V( ~6 k2 x& g4 C4 S; f; z1 o
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) 2 L7 N" n3 k2 k+ @( _. j0 y: N3 L5 L1 B{ / l7 [% m, M) o5 R8 d BLOCK_HDR* pHdrStart; ) l K8 l% M4 _/ j6 o" i/ a BLOCK_HDR* pHdrMid;& ~/ t5 c7 x* }* h7 T4 I
BLOCK_HDR* pHdrEnd; 1 Z# s1 o$ t% Y char* tmp; & t( m; b5 x2 L7 F+ H/ l: P int reducePool; : e+ B" d6 E' d9 [$ o" `3 Y4 x8 b3 o4 W9 ]( ]" i5 w
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ ]# c( K) l. F B {& P1 J0 o, M9 {! K2 j
return (ERROR);! }/ B% v O8 X# L6 q
}) e- q% a) d9 `
* s' e; ?2 H3 u; o1 k; U
tmp = (char*) MEM_ROUND_UP(pPool); ) t& ?- g f) r* J x- H reducePool = tmp - pPool; , G! Z6 m* U1 ]( ^: u7 T) @. s8 o$ S4 S
/* adjust the lenght */ - w1 Q# `1 R n if(poolSize >= reducePool) % i4 ?8 q9 E) P# ?" d* c p { ; {' e# e" [* ]2 k0 P0 U) j) @ poolSize -= reducePool;: O# M' X0 @" p. ~
}; r4 T8 c2 H+ x6 i
else9 B+ B4 f$ F1 k! K0 _4 I# D* s+ }
{6 x0 @0 _! u- {2 h* d/ n* q
poolSize = 0; 2 E2 Y+ ^8 Q P( \7 `$ w. A. U } ! j1 A# t, D' [% A; a: }- C, v pPool = tmp;; ` X, i0 E1 d
* `4 v0 b G. o: {- ? E
poolSize = MEM_ROUND_DOWN(poolSize);# {/ f* |' Q! [* }- Y5 K: G# M% t
* q( f; Y" E8 l) f; A6 o; m
/* at least one valid free block and three header blocks */ / S% b4 I# N' w- X7 G if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)1 H1 L& @: P7 z6 J2 N
{ 7 {( k; t: V& r( Y" @ return (ERROR);3 z& C: y9 S* G' \ B. q
}$ e* ]" J' Q3 Z% L. D: a) O2 {7 D
: d! ?2 a7 ?8 }) Q7 C+ y /* initialize three blocks */ # K. o+ D# p8 x$ w7 ?' ?6 Z pHdrStart = (BLOCK_HDR*)pPool;& C# b7 S T w7 P9 D
pHdrStart->prevHdr = NULL;7 x$ T4 M/ [& s" }) m8 q& S/ f
pHdrStart->free = FALSE; /* never in use */ , `; T6 z! s/ Q0 Q e8 v% u8 k pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;6 c. d5 g" C0 F8 @* o5 m2 i
4 D# j" V; i- x( w1 M& U% N7 Y6 p pHdrMid = NEXT_HDR(pHdrStart); 2 A# n! S0 g* v) ~ @6 } pHdrMid->prevHdr = pHdrStart; ! L2 I1 q" X' N8 U pHdrMid->free = TRUE; /* the main block */: i; d! q; `3 k
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1; 8 c ]6 y0 E/ X" Q* H, _- N9 ^& ^' { J5 ?/ e- r! }& V8 }
pHdrEnd = NEXT_HDR(pHdrMid);1 M- D$ s0 G! ~4 T: e4 R3 J
pHdrEnd->prevHdr = pHdrMid;7 H8 i9 B7 Z3 _2 M2 V' J
pHdrEnd->free = FALSE; 4 h9 @( _& Z% c5 f r pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1; * `1 J& K3 N/ i2 k/ E! y 6 u' v4 y+ q7 G0 e- Y /* TODO take sem hear */, A9 i3 H3 D# |2 O7 n7 J
semTake(partId->semPartId, WAIT_FOREVER); 7 C6 N8 D, z& ~ ) h/ r5 e* o7 k9 m( f
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# P& o4 `- x6 g! `4 b! N$ ]7 T% g
partId->totalWords += (poolSize >> 1); 6 D' d$ j, b. J! P/ A0 d5 { ; x ^9 z3 K( Z2 P, c; b+ k7 u /* TODO give sem hear */5 v( C2 a! y( ^% ]* J
semGive(partId->semPartId);. t+ l- A1 i" c2 B) }/ _9 [4 c
( f3 h; v% Z$ ~) d9 }0 Z7 G, W, _" W' C3 s5 x* m
return (OK); 1 R; ?+ U9 I0 z* G} 4 n! ?8 c* y: F1 F! j, x0 f& z- B6 s9 k6 J% p: s3 l
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)# N) v$ S' q; c1 P, C$ ?( X
{% ?0 Y* b0 X' }; G; K& d
FAST unsigned nWords;" c$ r7 B0 S8 L3 W+ x1 P1 L9 @
FAST unsigned nWordsExtra; $ w6 f% r0 ^9 N H) p0 y FAST DL_NODE* pNode; ) n1 v M2 o9 h' g FAST BLOCK_HDR* pHdr; / W) p. |7 V' l9 l BLOCK_HDR* pNewHdr;# [* P% g+ z3 u4 j# ?# S. L$ ^
BLOCK_HDR* origpHdr; n$ O2 w) v: O d9 K 1 s0 z$ R: \3 d' b" } ?/ ^) e if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ - J) a% Y2 M% { {2 t1 D" t: n1 O5 a$ D
return (NULL);: o O- r/ @8 j( f
}5 m/ ^+ _& `% b0 I9 O, I# l/ B
' F3 e9 c. y; T# O# ]4 O+ d nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1; 5 z6 J7 s8 l0 {$ e( C$ z# z 7 C! l- E! R7 V4 }5 c$ k# j; Z if((nWords<<1) < nBytes) 7 d' j! k' \# a% \+ q {+ L1 _7 D6 W# Y5 z; a
/* TODO suspend the task */! B) H; ~5 q, a, w+ l
return (NULL);$ _: c/ y3 x+ A
} ) i- `5 O$ ^& u 0 C6 k+ A' b0 E# O if(nWords < partId->minBlockWords)4 _8 g6 C, B% d* _
{ . o7 E# G! t1 i7 r nWords = partId->minBlockWords;: v" ?. A( a& x: \/ u9 y
} 1 X% _( o) [& r4 e0 P/ ?) _, ^3 |5 p- Q. g0 R
/* TODO task the semaphore hear */% I" o# z( Y6 e
semTake(partId->semPartId, WAIT_FOREVER); , |: C, ^2 K7 a- N pNode = DLL_FIRST(&partId->freeList); # u/ b7 C0 P/ A# n. [! P; } nWordsExtra = nWords + align/2; /* why? */, O' P$ A3 @4 a1 Y# J
, p, B) [: E" K2 b. l, @ for(;;) % F% r" V% x: e! o+ [ {( J9 f& J6 r8 k/ P9 U. v
while(NULL != pNode)8 c u# F+ H" b6 M& y5 D, O7 C: c
{ 3 k7 g& b1 K! @ G$ V, F/ n if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||. L* x$ _% o3 c
((NODE_TO_HDR(pNode)->nWords == nWords) && " u# B; B1 s3 p- b/ w
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))5 R2 P$ M: v: U3 q. z2 J: B( {
{ * i! Z3 @' h& ^5 C break; 5 Y. k2 M* [; x } ; Z, p) H' Y" B1 G1 d! ~% E8 n/ R( J+ m1 r
pNode = DLL_NEXT(pNode);/ D( P% |: U4 o: f# l
} # S; C+ W* u1 Q, t- F6 ?2 m, Y' V7 W% X4 b; {
if(NULL == pNode) ' G/ B" n! [2 w9 W4 Y# A8 e {0 J! l7 p6 }8 R; F6 y1 u! {1 ]
/*TODO give the semaphore */6 o( k2 C: R* h# w/ y9 d
semGive(partId->semPartId); 2 Z8 {1 l5 W k7 m% W5 ~5 v return NULL;7 |5 ]! t6 U7 i. v. e0 k8 T
} 0 {: C u! t3 l5 P; X2 P/ Q) x2 ^ ; G7 X. U: E' ? K9 l* Z pHdr = NODE_TO_HDR(pNode); # Y7 }2 `6 n" K0 h8 Y4 ~& ~ origpHdr = pHdr; ! m: P% H# z1 P1 V8 @7 i; v1 Z: B' D( q5 }" e* s, }2 l+ g! l. y
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);( ? v) `% j+ E; c) p3 b+ _) P1 {
if(NULL != pNewHdr) : f; R6 d. \% d+ H, O& N {4 V: S4 I! Y3 ? ^9 p3 ?
pHdr = pNewHdr; + N } `7 L# \3 _! p break; 7 M5 L; T4 v* l( @9 i# X2 c }6 \6 k6 e, V( T, q