8 } L" J& a, x$ r3 \4 WFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit; ! P- \ C% M. B8 i + ^6 e. F2 y$ d& d2 i3 t( eunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK; : R2 H. o1 [! z, g; h! ~5 r9 y$ g' w9 d8 e. F
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree); . @$ n3 \) G' D7 X) ^! Lstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId 4 l9 L# {1 E; N+ Z2 y0 [ , FAST BLOCK_HDR* pHdr 3 v3 B, x1 o- o) {9 x& r1 `% Z , FAST unsigned nWords ! h0 _# G2 o6 N! X, m$ W; a5 U , unsigned minWords 9 g5 K& o6 U/ n+ I& u& ] , unsigned align);# G& T# _" x; i; I! f3 r# t+ i
/ D, `/ d. h: i& G
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize); " x! {+ A# L" n. C: w4 }+ b/ W: Y: p4 D' y" ^9 [
STATUS memPartLibInit(char* pPool, unsigned poolSize)9 r' ?0 m7 {; b! {& D) ]
{ 2 e3 P% G0 q5 G( } if((!memPartLibInstalled) && ; `5 D: n" X6 [- \ (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore) 7 V- ]: Q& R( r/ Q' \5 D8 X; c# R , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))+ @5 k$ i5 S! _9 s( n
{ : L+ s: y1 R* g6 W2 g memPartInit(&memSysPartition, pPool, poolSize); ! \6 ~9 h) |- m/ ^5 o memPartLibInstalled = TRUE; 4 `$ y0 [/ G b+ ?& y) M }2 O- J4 M& f% e
: _6 n! y( F- w% `% V
return ((memPartLibInstalled)? OK : ERROR);' T$ R! s+ C8 M" b% h2 q
} 2 w7 S/ |4 a8 E/ I: V $ Q& N: n5 s# y( CPART_ID memPartCreate(char* pPool, unsigned poolSize) + d! x8 T- {8 G{7 W9 K0 k% x: f& c/ r4 `
PART_ID pPart = (PART_ID)objAlloc(memPartClassId); " q* K1 N- X% _0 i! w) a/ U / \" H" Y% R" Y if(NULL != pPart) & r- t# ]- g' P0 k% L { + c0 [; x& w3 P memPartInit(pPart, pPool, poolSize); $ u! U6 ^, w: |; D s0 |% K' h } 2 h3 g0 J1 z1 j 6 j" T x9 l; ]( ^) ?. U$ { return pPart;: d# X5 W i! n% v3 R% D1 {- ~ S
} " |9 f) s o3 p" {0 U' Y) A9 l9 K: i! q c8 w: \3 O' ^
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)5 U" S5 q: a ~1 I( l
{ / ]. L' ~ X$ N4 B$ j( M memset((void*)partId, 0, sizeof(*partId)); " V) @7 v: M% u8 g4 K; Y# S- A 0 [$ h2 i8 }' c, L7 I% ~# j0 z+ Y partId->options = memPartDefaultOption; * T/ c: U* D" {8 j* o2 G) E& Q partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */3 V% D. i( K* [ F
4 f) p% U- m q! y3 _, ` (* memPartSemInitRtn) (partId);. N- I; ~6 i: G4 K g8 j( I
. I0 R$ r- U/ V
dllInit(&partId->freeList);, h7 e3 f: x: g: _6 ~5 g( {- T
( h, u9 W5 C Q |: J+ y objCoreInit(&partId->objCore, memPartClassId); o& b2 t9 |) C7 ?$ ]; s4 {0 h+ N
- |1 O9 F, T5 S7 o+ n
memPartAddToPool(partId, pPool, poolSize); ( O7 S0 A. {9 X}5 r' Z6 ^# C* o% Q) y i0 J
, q. h- R7 {4 ]: f6 NSTATUS memPartDestroy(PART_ID partId)) \5 k) o! s( n g5 O
{ 6 E$ X& j) K. U; U3 y- ? return (ERROR);6 I2 W8 X4 v9 X9 [, b4 O
}& N" j; d: v+ W9 F
/ Z* _& W# U# v1 P! C& Kvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize) : q" {% [/ x5 H{ . b9 @/ r0 S! F- s (void)memPartAddToPool(&memSysPartition, pPool, poolSize);$ H: g6 X; G H4 |/ N
}+ `4 \2 E$ Z4 t2 s8 X, Z
& m1 L' a* Y3 g& C0 r
& t, Q" z. T; J. X$ {/ \. |; i1 g+ a
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) ! r4 K/ w% _/ T3 B& D{' z/ C" I" W3 \+ {
BLOCK_HDR* pHdrStart; S& \; N; b' k4 |/ M2 z! N BLOCK_HDR* pHdrMid; ! b& c0 o: d. C" z: f BLOCK_HDR* pHdrEnd; 5 U' U8 c M, C `, l char* tmp;; @4 x4 I$ p: g' p a8 @/ T6 k
int reducePool; e# B; s7 f2 V% m8 ]
* }; k1 d. X# |. Y6 T if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */. I7 W! D. {0 b5 N" K$ R- J; b% l6 G
{8 r& O& }* }& S- f9 t
return (ERROR);/ n2 E# L- s1 [. ^( b4 S
}7 M0 |) P. F6 ?/ E" \) _" L
/ n9 ^6 z% _1 D/ O1 g% L tmp = (char*) MEM_ROUND_UP(pPool);5 J, E8 E {: G0 ]5 g q, q
reducePool = tmp - pPool;" B# v2 j0 x t5 F7 H* M
0 C1 @. `, F% @5 t d* ?$ P4 j9 N
/* adjust the lenght */ 5 c+ F# b( I5 ~# p% S/ c if(poolSize >= reducePool)& t9 @7 Y0 F5 E( _& y
{ & v6 q: X" s$ @6 R poolSize -= reducePool; 9 {/ r3 u K8 J& g# R" z6 @5 x; O& a& ~) C7 M } 6 V9 [) j1 J# V% x else4 z. r5 X9 H9 b o' R$ l- T0 g* J
{; E+ {$ X3 g; Q( d7 E/ e, V
poolSize = 0; 7 x @% t4 L7 | }3 v! Y! ?2 A5 o% _0 _
pPool = tmp;( F5 z* x9 M* w1 T7 ~4 j T& K( F
5 X) G% V8 ~* R0 {1 _/ W poolSize = MEM_ROUND_DOWN(poolSize);# a0 C+ H$ I Z9 G! D
+ J* I6 A9 X& Q; v. A /* at least one valid free block and three header blocks */ $ n3 @- F* K, w, t# ~ if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)1 b& k" P; M# f8 y" Q
{0 x. H* ?& o4 d+ Q
return (ERROR);/ Y( |8 Y' c+ e
}2 O- G3 d* j# i+ _7 {# m) h. F9 }2 A
0 c4 O9 S" ?/ _ /* initialize three blocks *// g' F5 h8 K' x' R4 q" K( S6 ?
pHdrStart = (BLOCK_HDR*)pPool;$ W5 r( E! q, D/ @
pHdrStart->prevHdr = NULL;4 G. j, C- t1 Z3 Q6 M x
pHdrStart->free = FALSE; /* never in use */ 0 F1 M u0 _; Q! t+ y pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;4 A! G& O1 e; ^/ j `
? R& e5 I' N+ z9 Q2 r
pHdrMid = NEXT_HDR(pHdrStart);/ q: I1 h! P5 ^, t
pHdrMid->prevHdr = pHdrStart; P1 D/ M! f Z/ q" i! G
pHdrMid->free = TRUE; /* the main block */9 ^) W- v3 B0 B, C6 N
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;$ ]. p! K$ X' m4 ?
: z$ J: Y$ a3 J+ T pHdrEnd = NEXT_HDR(pHdrMid); 7 ^6 `+ y/ V! k6 n pHdrEnd->prevHdr = pHdrMid;/ D0 w/ a! s% `+ j8 W* C+ D
pHdrEnd->free = FALSE; 5 O$ s. s% @$ T2 A, c$ I pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;5 @* l; W6 N* u1 I; @: ]
2 I; Y* }- h, ] /* TODO take sem hear */ 6 [5 I. ^+ O3 \- `& y+ _# A, y( S semTake(partId->semPartId, WAIT_FOREVER);: n& ^* }& z7 p. S o. t, V
/ D, g3 p7 z( ~8 Z2 o: \3 P* \2 z
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));$ D4 E- e3 l# p: s# n: j
partId->totalWords += (poolSize >> 1); 6 w0 I1 Q8 v6 P& f0 D. K2 z: ] y2 Z' }/ s/ c
/* TODO give sem hear */* `3 n' N* _1 ?- c6 Q/ t
semGive(partId->semPartId); ' N0 ?8 a2 k- S6 A/ R4 i% Z' H. g9 `" O; C5 |; \4 h3 p
8 {; j0 h+ U! F+ p0 u: _ return (OK);! N2 Z3 }5 e2 W4 Y0 n; V4 A0 v
} # W( ^7 W1 [. c" `. p ~0 S* J3 Z1 X
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) 4 q3 N2 O _8 P4 u6 g! \! u{ , `2 Q2 x/ Y% U' ]7 R FAST unsigned nWords; 2 t2 d* D0 J) h9 Q/ r& s4 k FAST unsigned nWordsExtra;* F5 r% z( x+ x7 s: j4 |
FAST DL_NODE* pNode; . j" H4 m9 L% y& M FAST BLOCK_HDR* pHdr; 3 O* S( A7 O& a* ` BLOCK_HDR* pNewHdr; & F0 i- i1 Z" _: R BLOCK_HDR* origpHdr; $ p- ?6 O0 i7 Y$ _8 R4 D7 c7 x, A7 k$ ~/ w
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ 2 @4 |, q8 P3 C. W' j8 ], H& [2 f {# ]5 S" _, B: m; A
return (NULL);! l; B: p. K$ W n. M- B8 {
}8 _* ]( f& C0 Q
% I$ s' k( c2 Y
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;6 E' ~, B! e% E
( }7 \/ U- J* y+ |/ N1 Q( B- L( Z if((nWords<<1) < nBytes) }! F5 F7 T1 `0 y2 d2 K. Z( ?+ R { 7 D. o+ Z& }0 D* s6 S& d" Z /* TODO suspend the task */ 6 f, B( \. `: M4 O" B" k6 b return (NULL); % M/ H' q' M3 ]( t7 o; ?( V& G } ( K1 L; E4 ]7 g( V% S " m- |% m; Z6 i( |5 H# J) a9 o if(nWords < partId->minBlockWords)" }& N3 L+ X# v/ r
{ ' y( S+ v9 s1 T nWords = partId->minBlockWords; k% g; j; w- l6 ? L( d+ v } / b6 s$ y" N0 z% R6 Y# {+ O. ` ?5 a9 n# V0 P- B
/* TODO task the semaphore hear */6 S: N3 ], p+ j' k0 C$ f
semTake(partId->semPartId, WAIT_FOREVER); 8 C7 \( K' [4 O pNode = DLL_FIRST(&partId->freeList);) M- }( E+ `6 L% v; s6 _
nWordsExtra = nWords + align/2; /* why? */ ( B4 ?' S; u9 |9 y) s; Y, _4 j' q4 ]& A3 p0 g% I
for(;;)2 V. }1 Z$ E) _! N. @# y2 K; K
{ 5 [# Z- k4 f' q1 ?9 }6 V while(NULL != pNode)0 M N: A8 x0 i: K" V1 F$ C; H
{; g& {9 i+ m) |: q
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || . M* ]; }+ w) N' n8 q7 X* E ((NODE_TO_HDR(pNode)->nWords == nWords) && $ k( a" u- [$ O$ ~4 Q8 a (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) ) [" F& x8 Z" | {# b% j8 J: P* ^% i8 n! V1 T3 w, h
break; 8 l J% g _3 q- c8 }. K. a }; P6 c# b, J+ g+ I- ~7 t7 e7 P
; V! ~5 Z& r$ Q* C1 w: w
pNode = DLL_NEXT(pNode);7 V, Y O9 t' @* {! l' [, m: h
} " |8 r4 f9 Y) v# Y" ? [1 F" }" Z/ M 5 y+ ?# I1 e9 u& M+ y0 o5 p if(NULL == pNode)7 v/ h {& b5 g1 ~7 k0 i3 T8 e! x) I
{- o% j- o& J0 c% ^8 {6 O& `/ r
/*TODO give the semaphore */: z6 R C0 R$ t/ j( E I4 b$ r
semGive(partId->semPartId);' f# `! s( M a% }! i+ M
return NULL; + Z3 |: ~: H' J8 B } : @% |/ \" j8 e, b' Q, V% S P8 N+ h5 O
pHdr = NODE_TO_HDR(pNode);- M& {3 m' v, v; i' m, }5 X
origpHdr = pHdr; # X/ ^9 m' g' W% y$ |" Y+ x1 L& A2 _' L2 n; g' p
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align); 3 W2 A. F+ V1 j; F0 d' J2 p if(NULL != pNewHdr) - `* U7 s- E. m2 _/ ` { ; v9 m$ c) L1 e. z pHdr = pNewHdr; # v- |; N/ c; W( x( T6 c0 X% L break;% }* l6 m5 S; K
}$ V' p6 b3 u' }: y2 u, f
* K9 m/ @5 N, r j, X' C/ |# m2 }9 _
pNode = DLL_NEXT(pNode);* U0 H. y& J9 `7 m+ y# [; a; R+ \
}0 F, Z6 G. n- ~
. K8 t9 x- } ?5 G- i) D5 J pHdr->free = FALSE;. L1 G% E5 u9 x' k% z* N' |
partId->allBlocksAlloc++; + G! K* C0 n' h partId->allWordsAlloc += pHdr->nWords;. J& H Y3 g4 p6 O3 Q6 B
partId->curBlocksAlloc++;+ T8 M) p% Q9 V+ ]$ i z# I
partId->curWordsAlloc += pHdr->nWords; ! u! }# D' D- _( g/ A: }/ A/ @; [, x
/*TODO give the semaphore hear */5 w7 l% b, m6 q& K+ u
semGive(partId->semPartId);# n" m" Q: I& f( B- J* r7 E. v0 x, O
return (HDR_TO_BLOCK(pHdr)); C9 c' o# ?5 }9 K+ @$ [+ X4 ~ 7 S' q8 g- a7 }5 _9 o8 C
} j! b8 y8 m+ P/ q* M. q/ B. {