' e/ P9 }1 ]& L" p. H /* at least one valid free block and three header blocks */ 7 ?8 ^) e& Z- n8 y9 X; v if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) 8 W/ r0 ]. q4 O$ v. S& g: O/ @7 z0 L {* |. j' i& u- Y; F l
return (ERROR);2 M- i0 H- H" G* p( v% v
} 6 r% y7 C* ~2 k. j$ z: [0 z, G1 x3 e# H# s+ @$ N
/* initialize three blocks */& M; c- z" X0 W
pHdrStart = (BLOCK_HDR*)pPool;6 B( E9 ?$ b9 i! v4 K1 y( d, o2 `
pHdrStart->prevHdr = NULL; . N' I' ~: o9 @$ `4 h* t pHdrStart->free = FALSE; /* never in use *// M% K- J0 Z1 v5 v, ]
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; ( i( |# j3 \- |$ ^0 A( P' g$ g2 X( P% L7 d' ?4 o. u, [
pHdrMid = NEXT_HDR(pHdrStart);/ Q' s4 E2 {1 v( f/ F
pHdrMid->prevHdr = pHdrStart;3 r% H# ~) G: Y8 l# L' A
pHdrMid->free = TRUE; /* the main block */ * c/ }% K5 B: D+ C, z pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;3 e& E4 G7 Y7 _
) o( t: ^' H T- h9 \' v. c2 s! f pHdrEnd = NEXT_HDR(pHdrMid);, V# u2 B! N( c: F& a3 @+ I
pHdrEnd->prevHdr = pHdrMid; : ^, m6 r. j0 p; c6 h9 Y pHdrEnd->free = FALSE; 7 R3 E0 B- W9 m9 U7 N, L% \ pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1; # `. c2 b" ~1 _8 t9 S' e, L5 g% y( _9 l o
/* TODO take sem hear */; }7 }; I# y4 ^2 U$ M
semTake(partId->semPartId, WAIT_FOREVER); " R( u/ p" }( c9 E% a; { , X* Q7 q9 C" N5 I7 ]7 n+ _ dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); " ^# k6 H. y; z. S) a* K partId->totalWords += (poolSize >> 1);9 s0 Z/ B) L$ B+ l+ V2 I
# s' V1 T& R' J% I; g: r7 p3 c- L /* TODO give sem hear */6 R6 a" U) S: |1 ]! N) d
semGive(partId->semPartId); . `5 n) H* a6 v& J( y4 e 6 G; F8 D4 k2 b9 w2 ~ ' ]5 [5 h1 L% p& }9 b5 n return (OK);) m4 ?7 V% B0 I& c7 J% r( M
}! K: r( g) D0 F1 P6 E! g) f$ i
% t, L2 S S3 Lvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)) ~1 c( Q, `* x
{ & V5 n& b3 `" D9 g3 I6 }$ w FAST unsigned nWords;' g4 s' y3 z8 g; {7 n. K
FAST unsigned nWordsExtra; " B' u3 \0 x& v5 u/ S FAST DL_NODE* pNode; " H4 N6 ]8 v8 T+ @ FAST BLOCK_HDR* pHdr;& ~ G/ y5 K4 I' E$ D+ @3 N# s
BLOCK_HDR* pNewHdr; $ R+ [& w! z# q" W; H# o, ]0 f6 z# U BLOCK_HDR* origpHdr;# u4 y" L0 O$ ^0 C/ W
& z; y) {* l$ L6 S8 F" T5 N
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */$ o+ D6 m, N) O$ [. e8 |
{ ( Z$ j# p6 W) a/ }; T7 B7 e; o- A% r i return (NULL);1 ^& N6 D+ w& ?
} 3 s7 i' X% J' A8 t$ i4 B! z ) P) i. }7 l. D$ i( D( X nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! i+ X; L, y) _& a/ T' P$ l, t
! V: b+ v8 j( j' m
if((nWords<<1) < nBytes)4 r* u* k0 {) S8 r2 R, Q. c
{" `1 {8 T4 j9 }$ @ U% M& A F
/* TODO suspend the task */ ( ~. b$ O0 n. N; F/ K4 M& ?: U# s return (NULL); 5 u+ c+ C5 N# Q4 _ }6 E8 E+ V) X& T7 c; _
2 S& M5 b. I4 R/ C ] if(nWords < partId->minBlockWords) 5 a6 r6 D9 F8 m5 A# _0 z1 f { $ R( O6 q0 M. R7 i" B" ~ nWords = partId->minBlockWords;+ [+ M% y& J8 `6 F
}5 }& z* y( E9 E* Q; A
. P" ]: i* v4 _/ a. a1 | /* TODO task the semaphore hear */8 t$ S1 [) A, t! H% S: B" h
semTake(partId->semPartId, WAIT_FOREVER); 5 p% a, s9 D) d$ p0 u+ p pNode = DLL_FIRST(&partId->freeList); " h) @! u( G( q& u; J9 H nWordsExtra = nWords + align/2; /* why? */ j- S* `. |2 b8 P8 o2 Q3 s5 i
' H# Y% B% l2 m) ~8 V
for(;;)/ X1 `5 }; g" e' j8 m% R4 f$ t
{ 0 l: T! k# O' \7 k) M; V while(NULL != pNode) 0 w% N9 p" g' I+ E: l; [+ \ { 5 F/ e3 \' N* X+ j# s6 z, e if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || 6 F0 s5 e i8 [3 q: r4 F ((NODE_TO_HDR(pNode)->nWords == nWords) && 2 ], p8 \: s5 ]4 { (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) 4 }# f9 {4 j1 t1 d- M6 g C/ C7 n { $ d- f. z0 l, n- b8 ?0 F break;% @& h) s, m8 _9 X3 z0 i' A2 U
} 6 i: Z. F& I' ]/ ?7 [ 3 ~& ?- s t0 J6 ~" V5 |& j( } pNode = DLL_NEXT(pNode);# H A: `3 I$ O$ `# h+ J5 D
} - |6 n! \; x& N/ `$ ?; f6 @ 0 Z y& m) U5 n0 M& V$ N if(NULL == pNode) , G( m2 z8 p7 t { - q& c$ C- Q! P9 `1 ^7 h2 s /*TODO give the semaphore */ . b/ L9 h6 N( z1 _8 K) Z3 ^ semGive(partId->semPartId);& |$ _. U0 I$ b% H5 u: V
return NULL;3 B1 Y( F: y$ u" J3 |/ j) l. Y+ {
} 7 n$ A: h9 w! d9 g! |" U! O ( h: m5 o" [! ]" P+ V pHdr = NODE_TO_HDR(pNode);2 n7 H: k+ W8 X7 d2 e
origpHdr = pHdr;( A; w5 s- g2 O0 H4 b
- b& P) I/ k) m E pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align); : B' t- {; g' Y9 w- B$ [7 q if(NULL != pNewHdr) Y8 _* G# |! e9 ~2 H2 r: R {( D% k6 d; p( N& n* ]
pHdr = pNewHdr; ; W, ?0 l+ X, a% f9 v: L break; N9 f* C; T$ Q' t4 r; `0 w
} ( Y8 l( U- a+ d+ C0 w1 z. a5 D" Q2 M1 e8 A 5 Z& T P3 f; V a0 `" |/ F pNode = DLL_NEXT(pNode);7 t" z: R5 j) ?2 ]: [; i
} ; _( k* z" I( j2 {1 V; J5 V! s3 E , h. O6 N* ^5 I& T4 U pHdr->free = FALSE; * Z {7 S+ R2 f- B partId->allBlocksAlloc++; " T: V" D. o+ R" w2 o- q5 D3 g partId->allWordsAlloc += pHdr->nWords;5 I: \1 c2 a: ]7 X
partId->curBlocksAlloc++; ) m* ^; Q0 u, ^/ ^ partId->curWordsAlloc += pHdr->nWords;( ?. e* T) O, j! H3 V4 @
/ s F! P5 P, y( G4 A /*TODO give the semaphore hear */7 T7 N/ ~1 ^8 c, r
semGive(partId->semPartId);; ]/ j7 e7 Z0 a- u- H( o
return (HDR_TO_BLOCK(pHdr));: D& l7 p+ ~5 C
- ~4 P2 o1 C' B) E' X
} $ R( v/ G: S0 v4 x- A3 }9 ?9 f7 Z) p7 |$ \$ [, B
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)! _. `1 X" x$ F
{ & C( l8 n n. W4 r8 x7 ^ ^ return memPartAllignedAlloc(partId, bytes, memDefaultAlign); % h9 q' T+ m4 }}# Z: X. Z3 ~$ w/ Z. }! _8 {& {" o
! U( ^9 A6 {+ l+ p3 {. E: ?STATUS memPartFree(PART_ID partId, char* pBlock): V7 w7 y8 s- [; O* w4 ]
{ " ?. H3 f" ?! [9 k, ~ FAST BLOCK_HDR *pHdr; n, h* j7 i3 U2 L! V, x
FAST unsigned nWords; 8 h0 v1 y8 h. X& f, ?2 }' D FAST BLOCK_HDR *pNextHdr; ! ]% W* Y2 f; t) i# v 3 X' T7 o0 c! y# Z4 w3 a: l if(!IS_CLASS(partId, memPartClassId)). o4 y) D0 ]3 s* v0 K- h9 b* b
{ 3 z5 r" H9 d. T1 s return (ERROR);. H/ P; S: M' ~5 ?3 o& ^% \
} / D- U! |& Y0 _' L ' @- {# \" n5 |/ p- M9 Y if(NULL == pBlock) ' n' a+ |( _2 ]: E( d8 c0 Q { ' C8 l6 L- n, v8 @) r return (OK); 6 l% y, X a) k } 3 e, t/ |0 y# N' ? , n% z9 u- w- S$ P" z3 h pHdr = BLOCK_TO_HDR(pBlock); / y7 Q. `7 J) O/ r) ?- d& ?6 t2 C- q( i8 @/ n8 P& H8 u
semTake(partId->semPartId, WAIT_FOREVER); 0 ~& i6 y% p3 ~# {6 j _9 p8 O- o! f, J8 A
if((partId->options & MEM_BLOCK_CHECK)8 b K" T, W2 U" d# {+ E: l
&& !memPartBlockIsValid(partId, pHdr, FALSE)) 1 B7 O1 b5 X& m7 v3 i" R8 @2 Z { k4 l3 f) o- b
semGive(partId->semPartId);3 ~% a# u7 e4 q+ \
return (ERROR); . V v( j: v- x; l4 R1 b! j } ! C9 S& i% Y7 ` l - ?, `! b& P: w- y/ w- W7 u nWords = pHdr->nWords; 3 W, I, K/ i" `% N9 r1 U6 w1 N; R+ X) S if(PREV_HDR(pHdr)->free)$ {2 t, ?! o- f- j( ]% e
{/* the prev hdr is free and than coalesce with it */2 i- G' D( t. y q
pHdr->free = FALSE;; I: j+ q: e! q
pHdr = PREV_HDR(pHdr); 5 V3 C: \8 g' V8 A; w pHdr->nWords += nWords; 4 n E3 \% b& N ]7 i, I& K }9 I6 R% |/ `$ | b' u4 n6 D
else3 g3 N8 Y0 {: X; e; o( ^! I
{5 b' x8 X& v$ K$ L2 }
pHdr->free = TRUE; " A/ j! I' ?( c3 b: l9 M dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr)); % s m: M" b7 l1 @! u! e } 8 u* j& A/ _- u8 ~/ }' ^& O, G5 F1 _5 r& |$ ]+ p+ G% \" R \
/* check to coalesce with the next */1 G3 H+ W0 a' w7 [% C$ z
pNextHdr = NEXT_HDR(pHdr); ; a3 O1 s0 j) W" [- W* H6 ] if(pNextHdr->free) " z# T( y% Z, K- d { 3 l; L+ x2 w' t& |% S3 W pHdr->nWords += pNextHdr->nWords; 9 h6 D1 Q: A$ e( U' S- t+ r% e dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); ! d. k1 w% C: f: N# y0 W }! ] \2 J: o9 r% q- m1 z0 G
3 W+ Y, n6 `; ^0 z; C& v /* cannot use pNextHdr->prevHdr=pHdr hear */- H+ Z R8 F2 h+ u) {7 o. R
NEXT_HDR(pHdr)->prevHdr = pHdr;, o j3 N: N! t0 g9 V; U
3 q, E w" y) n; n, q
partId->curBlocksAlloc--; ! }, l$ R4 N e5 j# P7 l% ^ partId->curWordsAlloc -= nWords; ; ]$ P7 ]6 |8 R# C V) i& h4 g + E0 X- [6 u4 D$ k2 r7 g- f /* TODO give sem hear */ ! K' Z9 m* F. i: X7 o semGive(partId->semPartId); 5 W4 g" j4 ^8 S 0 z7 t7 W& G- x
return (OK); 0 [4 W% t4 S z2 P$ F) m" w4 C} 3 v# b$ d2 p4 R* R n0 T 7 c* x4 [, \& k& Nstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree) ; H) p* V' o+ E9 I/ o{ 0 Q) I6 w9 L e: N BOOL valid;* O4 S" j/ P: Y4 C8 B
' d3 x3 H; p5 S9 W B TASK_LOCK();3 ~/ F+ o+ N& t" s9 y$ Z9 p
semGive(partId->semPartId);1 V7 N; G5 D! I F! G4 e! \
{; F/ k5 m4 v/ C! Z' N! j
valid = MEM_ALIGNED(pHdr) ( d: a4 o. [) G && MEM_ALIGNED(pHdr->nWords*2): w- h8 a: p) Y! z
&& (pHdr->nWords < partId->totalWords) 7 ]# r9 z& `: n && (pHdr->free == isFree) , i, J! k8 }; O! Z+ E. R6 x. q && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))' g5 k7 m2 ~5 M5 i/ y% y# c
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr))); + ~3 K/ y3 } L0 f8 ^3 z 7 S) t1 j" z5 k& a3 B semTake(partId->semPartId, WAIT_FOREVER); 5 O1 O! c9 ?# W4 n; ^! [' }$ Z# N TASK_UNLOCK();$ x% E g/ X5 I; k4 Y4 v% U, P
: N8 r0 v; u0 j, c$ R* F return valid;/ P& z: a) b F. v9 `
}& N$ F- n8 f# Q- }5 B+ G3 z' W7 ?
) _' ]# m; i4 d. m, d- r0 Ostatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId' j2 p; F) q# u n/ l
, FAST BLOCK_HDR* pHdr% N8 u( U4 Y: h# i& s# K4 S
, FAST unsigned nWords 7 W( ^$ z) @! P, N1 {) V( V* w , unsigned minWords' _4 w2 s4 O9 \' o; t/ J3 X; k5 i
, unsigned align)* ^' s$ e% |: Z+ u; v* {4 n1 A
{ % ^* d* o) `6 x FAST BLOCK_HDR *pNewHdr;2 m3 _1 E$ c# e# C
FAST BLOCK_HDR *pNextHdr;9 k' w; o7 V$ t
FAST char *endOfBlock;) H! G4 v0 q, j; L4 p Y
FAST char *pNewBlock;1 d, `3 d1 ^ u l, A
int blockSize;8 H1 S* ^, R9 G$ l4 Y+ V2 h0 Z0 [
0 V/ C9 l* H' L: F- {: u- F$ y
endOfBlock = (char*)pHdr + (pHdr->nWords*2);, |& T/ ~9 U$ a. ~, e$ T
) R9 F4 S& u. D3 } pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2)); 7 R, j6 e- |1 R ) a" p1 `0 [3 v' z6 t" J% o pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1))); 2 n# s8 d. W' @+ L0 B8 O+ R7 W ], }( a/ ?$ M4 Z2 S
pNewHdr = BLOCK_TO_HDR(pNewBlock);) ?$ `: u9 v1 j& |" h& t+ d
6 u4 d ?2 R' Q
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;) Q) ^* `: O. h; r' W
, j4 l. Q$ |4 B% W! v! P. f
if(blockSize < minWords) # o# v7 W4 c' ? { 0 x" B6 Q N; @+ a" R. O8 R if(pNewHdr == pHdr) - L; S: q% P- @' a; d4 D8 J {0 m/ s" s7 F: O" r
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); ) n5 F( _ }# z% A& K: J } ; m: [. t3 T* n7 u: e( o- f, M2 q else ; P: C6 t* R! M; _- p% U; w { 0 p$ M1 `6 t5 V return NULL;' I$ p& a8 W. o( h) D
}$ P7 k" O0 a* Q6 T/ Q
} / C; k1 w( t& E% q& L% a/ q else ' O4 G( {2 K% ?" c5 [* w2 w { /* recaculate pHdr */ 1 a: B/ |* R0 }$ y pNewHdr->prevHdr = pHdr;! [3 t4 J3 }& C* ^/ P
pHdr->nWords = blockSize;$ L) r: ~9 y1 a& A
} 8 N$ [: T4 K# j0 L: r" C 5 c! h9 R1 D# I7 R' U if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))) s0 Z1 G9 N# G4 e3 M
{ 2 s7 A1 o3 H; k8 F pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; ; E, G. i( v$ J pNewHdr->free = TRUE;4 u; j( m6 K5 S: B
5 L- o' h! Z, Z+ M% t7 \7 E
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr; % T: S! d( B* H& N- S }7 T1 s' i7 x) C9 T
else$ Z. l. a( y& a9 x* X# ^% e
{/* space left is enough to be a fragment on the free list then */ 2 Z* U5 h7 J* c/ B8 n) L8 O1 ` pNewHdr->nWords = nWords;5 L2 Q. d( i1 K Z
pNewHdr->free = TRUE;5 _# I. }' W/ ]
# q/ W8 }" l R2 Q7 h/ a9 W* I% H
pNextHdr = NEXT_HDR(pNewHdr);! r* Y# j' L$ T. U. K, M$ R
/* words 包括BlockHdr */ + X" y8 H1 C7 U1 D8 q" ~. Y* N" \ pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;4 K/ q) G/ v* F3 c
pNextHdr->prevHdr = pNewHdr;" h: Y' m, _: J! Y7 H1 E8 h
pNextHdr->free = TRUE;. C6 G$ w+ j6 E0 ]" |. T
/ N$ z9 ?" r: m dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));% [2 I# w/ r2 c
( g. d5 W+ C% S1 X6 R
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr; % B. e* x! q7 f1 _! A5 H }% C3 m; j- ^6 `
7 U4 B3 k% e. I6 J return (pNewHdr); - t2 K6 K. M" T6 }4 d; v! D}) Z) ^+ @ ^! Z. v