想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言; @6 a7 y( E: F$ S( T. |' e" Z1 a
" [2 [- Q* b3 B. y
. l/ i5 i( G. z0 a) o7 p, x9 y8 E! F9 x. n0 I4 N5 k
*\file9 \, P% o0 e. b/ s
*\brief / G1 f2 I+ ~/ `& i3 e: z4 t; S *\details 9 t8 p! K! Y& m, y7 F* R* g+ _; J
* , Z% y B" K9 v& V2 n *\author Janson9 S9 v( Q+ ^) |3 X, D1 i7 u+ O
*\version " S9 L) ^4 e( s *\date 04Jan122 Z; _. M/ d( p* ]! \( I# \7 L# c! K% z: t
* ( u* P$ i6 b/ C5 Z *\warning ; U1 V& q8 q G2 f. ~
* ) D$ ?: c4 G6 Q7 p; H *\history \arg 30Jan12, Janson, Create the file" r# d) r2 C3 [5 r& @. r
* modify from VxWorks source + c" i6 U, C! H; E: j* l * Legal Declaration: it is for studying VxWorks only. & b0 F' ?+ M3 p */ & L% e. \( Z5 _0 n" Y* V#include "includes.h" / L$ W3 p! r$ k. p+ J* t" o , D# B+ B# ^) d* K) Z# V/* The memParLib.h file is hear:2 J7 k3 N4 f/ G6 H0 I9 f& e8 i9 r https://code.google.com/p/vxwork ... rivate/memPartLib.h - b5 \7 P8 [* p# v u/ @*/ 2 D+ m" I6 S1 X0 X0 ]" M G , j. G3 K! l! y- l/* optional check for bad blocks */ " [$ m# u: g) A# M ; s2 e9 V$ N9 O" a7 Z#define MEM_BLOCK_CHECK 0x10 , W! q/ i; `/ f. v! x3 c6 \# s1 r# A+ b! I& v/ Q( x
/* response to errors when allocating memory */ 2 W$ a% N3 q: ] V% ~0 g: m! L4 X
#define MEM_ALLOC_ERROR_LOG_FLAG 0x204 W5 z" V8 a6 m `+ r/ p& F- u+ V
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40. }3 p7 Z3 _. ?3 `* i+ _ _/ ^. M( I+ {
; ^* B$ U4 {' u3 D W
/* response to errors when freeing memory */ . j. `7 t+ s6 S4 x6 E ; {3 G7 h6 b! m#define MEM_BLOCK_ERROR_LOG_FLAG 0x80. g0 J2 u1 W/ ~! N+ V
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100 9 K0 G, {; E3 M; V' q' m p 5 c5 B/ I8 G7 y; n' K# A* o4 q#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))) 0 t3 Z5 L2 U j( S6 t6 m) l#define PREV_HDR(pHdr) ((pHdr)->prevHdr) , e0 O5 }& u$ o( Y+ f7 N # d! r$ W3 a8 G+ }& Y8 M#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))# |$ D' ` N# [. B; k
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \4 e' L8 y& T2 G+ m
sizeof(BLOCK_HDR))) " K9 x& p. {+ I % p2 w" ?/ o% n6 R( a' E' P: X8 M#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)9 ~7 f) Z/ n( M! k- F( c4 [4 o* b( Y* K/ [
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \" `- m+ j* N" p. |
OFFSET (FREE_BLOCK, node))): t& {0 R5 `- o. o0 k1 y5 h+ k- s
$ [; |) P) Z3 P" N* a/ J& J: Fstatic BOOL memPartLibInstalled = FALSE; $ \5 J8 j1 x( @( o + U2 @ h* T' f3 V5 rstatic OBJ_CLASS memPartClass; + F' M: V* {' Z2 UCLASS_ID memPartClassId = &memPartClass; + X/ X3 U7 m: v' L2 i. }7 k% E 7 x8 x4 D5 `) Z" k5 _' @static PARTITION memSysPartition;3 X3 _3 J/ A. ?; x% g- Z
PART_ID memSysPartId = &memSysPartition; / k$ `& m5 U2 ?2 }, ZU32 memDefaultAlign = _ALLOC_ALIGN_SIZE; / _ M$ P" h7 M# b C* O% O0 k2 o K% k; i T) |
static SEMAPHORE semMemSysPartition; 9 O5 _! M' J, O- J( M! e7 @: Y9 N 4 l t8 L: S# d9 ?: g! wstatic void memPartSemInit(PART_ID partId); & f# c% R' X0 ?- H' j' J) h; A) \- l/ [" G
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit; / d- w2 d3 ~6 c: P" l 5 c: u' Z8 U. r( O0 lunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK; w1 j3 e, s4 L+ `, N
/ A' t( [( A+ C9 cstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);$ r/ P' b% K& s8 b7 n: K3 B* [
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId, L' E7 C$ h4 H
, FAST BLOCK_HDR* pHdr) K( Y- ~0 C$ q" a' w1 v
, FAST unsigned nWords9 h) G- I, @) f/ T
, unsigned minWords * r& {- C7 r1 m8 P H6 g% E , unsigned align); 4 O- B3 a. _; L# w% f9 P; n ; x* w5 {8 ^& v5 o/ b8 D5 ]static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);& \: T2 }6 \7 w E9 P
) z- S1 G6 N6 B1 J( o. D! P
STATUS memPartLibInit(char* pPool, unsigned poolSize) 1 c$ g0 q& f& g, e6 z{. Z) h4 I, B* l; b8 U
if((!memPartLibInstalled) && / y& j; b9 w% U: x: Y. E (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)# {. b( q% k/ }: L. g( r2 y
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy))) H! A- f: s6 i& f { - G9 k) N3 l3 D4 \ memPartInit(&memSysPartition, pPool, poolSize);) q% {% q- a, m" @3 y
memPartLibInstalled = TRUE;) @# d6 N* { \: M' ?; c) X: U5 x
}0 m+ b& g+ T9 F) c+ U/ v: z
7 m0 V% h6 |6 U) I
return ((memPartLibInstalled)? OK : ERROR); 2 a' k! C* x! ]9 i# R, z9 o}; k6 H1 }. |' Q. ^& x3 ]
5 L' }! T. z/ t( O5 G6 a9 V
PART_ID memPartCreate(char* pPool, unsigned poolSize)3 W/ T P I; F1 M! }6 q- i# n
{1 g/ ^# [# O& \2 c/ ], |- n3 J
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);6 W# Z3 V9 s, G
5 L+ M$ [# ]. |1 `! i5 M
if(NULL != pPart)7 r$ e% ~5 b* E) S# Q* h
{+ M& V# I$ o, w1 _; d
memPartInit(pPart, pPool, poolSize); 3 O) x0 j$ V: u, {+ {* b& b } , o: x! o0 U" E4 y' L , X, E, K+ B0 }9 g0 B( x return pPart; / _- @$ |# u* a/ c( Z( f8 ~( P! k( M} 5 x9 ^' _, c; R U2 L+ W: M) g$ o4 `% a, B( N% u$ G" c. S9 r& X
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize) : f7 ^6 t0 S' ~& [9 w+ K G{ $ [6 V; V! a1 I+ b, v. X' w memset((void*)partId, 0, sizeof(*partId)); + d: U7 Q. `; J% f. g4 f, v' K+ h8 c 5 G# f& B4 o, F5 c! L0 B; z partId->options = memPartDefaultOption;) D* l# Q7 X4 l/ d9 X
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */1 I3 G9 y2 Y- ]! Y1 X- r7 X
& y4 }' C/ ~% a8 z+ o (* memPartSemInitRtn) (partId); 4 d8 y! t6 _& v* P5 | ; _! c0 Y) Z( a' L( u# F
dllInit(&partId->freeList); * n- ?- N; B* N Y8 Z' P5 j 7 e! H: h* k O$ G1 a' v( Y( V
objCoreInit(&partId->objCore, memPartClassId); : a8 A# N5 D V. S4 c5 k/ ? 8 R$ K$ g) v$ {- y
memPartAddToPool(partId, pPool, poolSize); 6 v, d; r2 U1 k* a}' p' j! K5 p% L; i: m3 F
: J; o1 p! r. ~# x, a4 K' t
STATUS memPartDestroy(PART_ID partId)% m% {3 D5 Z+ P) `4 D5 F4 ~
{ , z+ r6 I$ F/ W9 m2 H0 g8 z return (ERROR);% o/ u: E& S9 `: \! k
}/ }/ C) y' j7 ]( \; n/ z/ j
. ~- i- L, L9 V8 `$ k
void memAddToPool(FAST char *pPool, FAST unsigned poolSize) + ^4 ?4 N; R2 R" L$ \{$ I1 C1 t; A; w/ X3 [( B1 R6 b
(void)memPartAddToPool(&memSysPartition, pPool, poolSize); + h4 Y, X9 Z& o7 ~} / x. x/ {# [$ G& ?8 t" z+ b4 j8 m% _ ?+ T; Z3 b6 Z/ O( i
; k: Z3 k) N2 v. |1 I! v* T% Z" i
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) 6 j! y( [) }0 R( S2 b5 _/ ^8 P6 C{ 8 | b3 e* j* G BLOCK_HDR* pHdrStart;' N, |; g6 e5 x$ w) W
BLOCK_HDR* pHdrMid; 7 E2 h2 W) y+ y2 }! n: ^1 | BLOCK_HDR* pHdrEnd;: e% E4 Z# H; C, p+ C7 m; M
char* tmp;, R* s, i0 T! N a
int reducePool; % n: {& I1 x$ J6 B' _4 J2 A- u S; X. v6 s' g
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ 1 G' z* {' ~" r2 W { # e$ h5 e g. d Q: s return (ERROR); # {1 e9 l2 e3 V }, L. X9 Y9 K( G, a+ O
: _. ^! g" \1 d6 e, ^0 Q% w
tmp = (char*) MEM_ROUND_UP(pPool);. a$ E: S1 V# k5 a- }8 a5 u
reducePool = tmp - pPool;8 Q( a/ Q D) R4 M! l" Z
% g3 t, e2 F E; t' q, @* e+ Y4 m; e
/* adjust the lenght */ ; b( T9 a7 C- r; l, u7 y9 C1 P) X if(poolSize >= reducePool)0 `8 [5 {7 r0 E4 a! Q0 d
{$ ?7 W6 C' N9 W6 [
poolSize -= reducePool; r- b6 x+ R4 C# L
} ' j$ V. G& W/ B/ _* C+ [7 | else * b% v0 e# d$ k {0 ^' O5 {6 ?7 R1 g! Z
poolSize = 0;+ P- f7 B$ M0 S
} - {% V% K% A9 e" c4 R1 {- } pPool = tmp;$ t. h5 y3 c0 a8 |8 @
; s& n9 L, i/ |/ s8 l poolSize = MEM_ROUND_DOWN(poolSize); 8 y# D0 l+ ^) W( G) }: I ! U4 N# |) Y0 G7 a7 R /* at least one valid free block and three header blocks */! H* w, Y( @4 U9 ]) I0 W m
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize) s P* W% P2 I$ x4 V3 c { 2 H& r2 x7 Q! ?% o$ W6 L return (ERROR);( f! I3 `" B+ Q, b- g B
}) F+ y+ B, h) X' W2 I" F
' z9 V6 r* ?( L7 _ /* initialize three blocks */) f! a5 d, w) X
pHdrStart = (BLOCK_HDR*)pPool; : G- `7 z e% E) [ pHdrStart->prevHdr = NULL; " [9 q; F- s8 P; G' [. \; V; q pHdrStart->free = FALSE; /* never in use */ " T$ |$ }# B; T. H L& _ pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1; 7 I! h9 y! ?. Z b6 v0 i; C , \- u7 y; V c; _' D( x& | pHdrMid = NEXT_HDR(pHdrStart); , V! |4 S! e; b0 s pHdrMid->prevHdr = pHdrStart;- Y% d$ _2 ~" S% Q! `- D& O% [
pHdrMid->free = TRUE; /* the main block */ H8 t9 q D, {9 p3 n { m- w8 Z6 |
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1; ; Z- M( F% R4 z6 D1 Y1 c# t J3 K9 G
pHdrEnd = NEXT_HDR(pHdrMid); / G4 g+ `: |: c8 y pHdrEnd->prevHdr = pHdrMid;( }1 T% N1 C# h( E
pHdrEnd->free = FALSE;/ r0 b! r. V4 h, x' U* @* M, h
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;: j, ^ |4 F/ E* I. G k, Y
3 d, O. `' T( v; N /* TODO take sem hear */1 T; b7 {% B4 z( m, P
semTake(partId->semPartId, WAIT_FOREVER);% v# w! y# \/ n
W: d* a' w+ L* o3 W dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); & B% b$ t$ h! U1 X. V5 a partId->totalWords += (poolSize >> 1); / Q+ D) U0 A! j/ ?" D- M" V 2 C% b- J' \. X" i* y0 J+ i /* TODO give sem hear */ 4 v3 o4 }+ b7 [: G semGive(partId->semPartId); 7 ]& g! N; v5 e8 Y x ' }- I# O8 o+ k2 y; j( d+ Z; Y3 z8 w& i1 R
return (OK); 2 K- B7 W6 k6 f2 E- v$ v; c( l} , L2 S5 o5 X; n$ i % p+ w9 R! m0 ^1 v9 N% svoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align) 9 K0 H* ]; Q+ y) R& v{ 3 v! Q' N3 _0 I FAST unsigned nWords; 4 g( X5 {; ~( i t, r4 t' W FAST unsigned nWordsExtra; 2 c' s1 `! M1 ?' e FAST DL_NODE* pNode;) Q* R( E, z; d
FAST BLOCK_HDR* pHdr; : E- ^! l8 G& {) G BLOCK_HDR* pNewHdr;3 o/ y! h, _! U( \! l2 I' i
BLOCK_HDR* origpHdr;" S" O) b: D8 i, A7 y* p
" p, p1 b7 P! @) X* q
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ . t7 |) q; K$ U {& d$ V2 J/ y/ u7 S. r
return (NULL);' e5 ~5 d k, I
} * S! p: L, ` W" R8 T 2 R7 E1 e& v7 h t' Y1 | nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1; 2 e* L& M( v. B. T2 l/ N9 S1 ?; Z9 s5 U0 M& v+ a
if((nWords<<1) < nBytes)0 e2 A, ?0 ~& o. I; m
{# g3 A/ t/ B6 m8 }: @
/* TODO suspend the task */8 s/ c: j4 \1 F4 T4 a. a' N
return (NULL); % O! Z: ]/ e; b2 c& [5 T }4 y5 p- O. c, n0 n6 U4 P3 W0 G. M
5 j' ~0 e" M$ |$ O9 ~/ A if(nWords < partId->minBlockWords) 8 Z$ U6 b ~6 n5 W% W& e+ U1 e {7 ~6 p5 o$ l1 O. `% l5 A0 k
nWords = partId->minBlockWords; 2 O( [3 c2 [' M8 [- p* ~+ X }) w* h. C- ]. ?5 G7 h# v
, f2 x0 A- M4 `$ {: V; ^" F
/* TODO task the semaphore hear */ " |2 }2 T: L. f, | semTake(partId->semPartId, WAIT_FOREVER);$ b/ n8 c) ?$ N
pNode = DLL_FIRST(&partId->freeList); . P$ j. F( P. v2 } nWordsExtra = nWords + align/2; /* why? *// k0 o b! S" {% @4 o" D q6 O3 E
6 C7 ^0 o) U0 ~( y
for(;;) ! R- @5 c3 j* E: [/ [; I4 k5 L { ; c; M3 ]) I p% [/ f5 f while(NULL != pNode) 4 M. K' s2 ]. N+ [9 Y8 K; v6 N { 6 G L. A; I! H: S) y0 a+ d3 L/ | if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||/ A- R8 d. v* t Z
((NODE_TO_HDR(pNode)->nWords == nWords) && ; i' Y$ \ H+ Y4 @8 G, u( O/ _/ Q
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) $ d0 B6 x7 i7 U+ K5 O/ | { 3 q% `/ t+ t+ E' Y! o e9 N break;1 F4 d) m; S& Q1 S5 }& C( W& n
} 9 H- [* O: B2 a; `; j . S' g( N0 b' V3 V7 m d4 P pNode = DLL_NEXT(pNode);9 f( h5 ?& m8 U, \1 T- T; B( o3 ]
} & {- z3 X) V( b" |! T0 J! e& x+ h$ k" i, }' G
if(NULL == pNode) % Y9 R# X T8 j u {* F$ ^- h2 [# j! J' g$ K8 B
/*TODO give the semaphore */ 5 D/ w/ {- U" F* I7 |3 K+ R, Q semGive(partId->semPartId);1 U; @& l4 D4 }# c
return NULL;) r4 {& o7 f/ o7 o1 o2 v8 u
} 5 J1 s! U( B$ a4 H 4 W. P, W% R1 S4 Z pHdr = NODE_TO_HDR(pNode);& q7 D; a" o$ u A& T
origpHdr = pHdr; ) J8 ^* V' n w1 _! C. K0 w , A: n0 s1 S! S- C6 i( N& g pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);5 [: J8 d* \9 q5 F. u
if(NULL != pNewHdr) : F2 j+ i" O6 t: V R9 M { _ g: L1 }. Y" P pHdr = pNewHdr; # w- [( |+ @5 P8 o0 A3 l' J* Y break;* x! A' {" @. [4 q1 |9 `. s7 U# N
} # p7 ?: e& X' @- g- x1 K5 l K * O+ `3 U# x+ j, I& @ pNode = DLL_NEXT(pNode);* b) A! l% H: I
} 4 g5 Y! Y5 e5 r& l ! u" d3 t& l0 Z% x% N% G pHdr->free = FALSE; - x) [& H/ ~7 f0 {9 J* p9 @ partId->allBlocksAlloc++;! E3 y) ?( m0 u1 G$ a
partId->allWordsAlloc += pHdr->nWords; 7 m$ q' w3 a! |+ N2 Z' P( R partId->curBlocksAlloc++;( K( T/ {6 t% ~9 Y1 a
partId->curWordsAlloc += pHdr->nWords;/ W1 Y2 Z2 i, H7 P. y
# T5 r( ]: B/ ?6 |. V3 y k4 Z+ i) x /*TODO give the semaphore hear */& C4 W" ^) s, c8 S7 N
semGive(partId->semPartId);9 n: h+ G6 d) |6 W* r* @8 q& Y
return (HDR_TO_BLOCK(pHdr)); 9 c* A. K3 Q, K) M" n$ i 9 q/ }( b2 a9 o. Q. y! Y% i
} & b0 D7 g: W0 i0 T/ C 1 \9 ^8 W2 F) [" }' bvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes) 5 l* p$ v) q4 W! n{ M0 J: X+ z8 ^: a
return memPartAllignedAlloc(partId, bytes, memDefaultAlign); $ b" [' a$ V* F! t* `} . @& ~& C4 r0 J' w2 d& g& `. j9 e+ t* T( Q# L0 W
STATUS memPartFree(PART_ID partId, char* pBlock)( C' V- y. F* M3 U! U* U* U
{8 E- s' K! s: u- e: j
FAST BLOCK_HDR *pHdr; 1 L) z6 T& F5 e$ ~& t5 c FAST unsigned nWords;/ O8 J! b Y9 |9 M F
FAST BLOCK_HDR *pNextHdr;# p7 _$ ^- z+ N
4 Z+ ^. v& p9 L/ k7 U! x
if(!IS_CLASS(partId, memPartClassId))+ l& Q! O ~9 A! ^+ W% b% N
{7 \% U/ j' L3 G1 n" H
return (ERROR); - D) C$ q% R7 d( ~+ r( q+ V5 { } , J- \: I# s. _8 [1 e# v$ U& ^- A0 T* S( \/ o) a9 S, S1 }: Z* l7 e
if(NULL == pBlock) 8 F: [+ t7 j( l+ {5 m& x/ ^+ k( c { g3 w* s' @) c6 y0 z! o" A
return (OK); 9 L9 ^9 e* s* A/ C }/ {4 J7 u" D0 d9 B' H
9 f8 Z# c/ U* L4 b) S7 `$ k* n semTake(partId->semPartId, WAIT_FOREVER);0 c& M: k- X/ N8 F* Z! K# \
( ]( A* u) P# B5 y9 Z% h# t
if((partId->options & MEM_BLOCK_CHECK) 2 Z+ ?, G- m5 R6 ]; o0 | && !memPartBlockIsValid(partId, pHdr, FALSE)) / b5 E! z, @$ u8 \4 | { d8 L+ o) z1 U" E( Z% K semGive(partId->semPartId); 3 ^ F! N0 d) h/ w g) Q$ J* E& l i) K, ~ return (ERROR);2 t( |" J) j, n7 Y2 R9 g6 A
} E5 R& d+ ]) g$ `2 D 1 c0 M$ q# J; y6 o( P nWords = pHdr->nWords;4 D% x* R) z4 J% o& C8 V
if(PREV_HDR(pHdr)->free): J) k ?( L+ X C) [
{/* the prev hdr is free and than coalesce with it */ : P. K I6 ~0 J0 Q1 X/ g pHdr->free = FALSE;/ q4 p/ V- Y8 x; z& V
pHdr = PREV_HDR(pHdr); - B. \. T; q3 u; Q+ Q4 \2 k5 \ pHdr->nWords += nWords; ! |* n8 K2 ?5 V/ U, n. K1 ~ } } : R3 J+ \3 ?& C0 O else6 F; ?% ^+ [& l! S/ ~
{$ Q; y0 Y4 H8 l- S; F
pHdr->free = TRUE;, O m C4 s4 a4 t# ^1 |
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));7 k) W8 v$ c; u; E f
}. M4 b! |4 |' u; v0 m3 Q" |1 p
7 J( r+ F) G) q* k5 l
/* check to coalesce with the next */ $ c7 r+ G5 V$ y6 k9 Z7 G pNextHdr = NEXT_HDR(pHdr); 8 ]; @) w4 l+ c if(pNextHdr->free)6 F$ ~$ ]- A' B; s& Z3 N# d2 _& n) B
{ * w: a9 M @( D3 ]3 e2 V& k, X pHdr->nWords += pNextHdr->nWords;) X- |! l. C$ Q' r
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); 3 }; A5 B4 p, A8 v9 j% h d" U4 v }% D+ f6 q \* \8 V4 o
: d4 H k6 h! ^0 X9 O3 v; F: ^ /* cannot use pNextHdr->prevHdr=pHdr hear */" G/ c2 Z; i" L3 ~; [( M
NEXT_HDR(pHdr)->prevHdr = pHdr; * D0 \* q# F( W, U1 [' J8 ^2 j . m" a0 E3 S4 o9 \* z) a partId->curBlocksAlloc--;0 l1 ?( G; e1 Y3 f
partId->curWordsAlloc -= nWords;0 U9 d: m1 V3 N0 Y* j' j
; R' A# T/ p4 W _7 v) M i8 e3 B+ z
/* TODO give sem hear */ 6 V' v2 g0 z2 k& n; @; I t# I/ { semGive(partId->semPartId); 3 M! @* y7 g, o: t9 I) Y0 e) Q3 s + a( t4 S' ^( d) c/ ]
return (OK);* V) [' `( X7 Z: U# ?$ m3 ^
}+ u6 n3 ~# d7 h% J3 K& W
1 ?* x. q- v- q* a5 S1 M2 Y$ Kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)7 K8 a7 W* I! {6 n, k- g9 ~- D$ N
{3 P1 B; L- K3 c9 q
BOOL valid; & p3 A1 o1 N S0 {, h T0 r2 W/ h" c N" N1 j% K1 t TASK_LOCK(); # { V3 y" H! U# A" b3 \ semGive(partId->semPartId); 4 d2 j s; L$ F" J1 w! j, }. @9 H 5 ]/ ~2 c: M7 }5 w8 Y valid = MEM_ALIGNED(pHdr) : d- {1 \6 c( v# B( G && MEM_ALIGNED(pHdr->nWords*2)% m J3 v+ ?& A' w0 |
&& (pHdr->nWords < partId->totalWords) . X9 X6 y6 y/ D" Z& b) j0 }: G* R
&& (pHdr->free == isFree)* o9 y5 \. m, v& Q, B* w' s2 F
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr))) 5 H( w" s4 k2 @, R+ H( j && (pHdr == NEXT_HDR(PREV_HDR(pHdr))); ) b4 T) P0 _5 M4 D) S. ?+ T - i. f( N5 T- W; q$ w$ [ semTake(partId->semPartId, WAIT_FOREVER); 0 H+ |/ Z4 d* G* v _ TASK_UNLOCK(); 4 _; y- p" i4 H! g& J$ ~, x1 H8 @5 c+ w! ^( f" O
return valid; \1 H" Y& e4 P3 i
} $ ?& k; X; e! O g. P1 ]- k( {4 o: E. F
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: d5 Z1 |3 H7 N
, FAST BLOCK_HDR* pHdr3 y- _( X5 _4 g6 v& K4 B: P w
, FAST unsigned nWords: j8 D! [) ~+ g# b" d
, unsigned minWords , x q9 L: |" [9 u0 U , unsigned align). B/ E8 `5 n- w6 h7 A
{ ' _* X3 K- Z1 `* X; I- \ FAST BLOCK_HDR *pNewHdr;( ]1 N$ Q' X% C1 C5 X7 W/ l
FAST BLOCK_HDR *pNextHdr;* x; [% C3 E5 N+ v- @
FAST char *endOfBlock; 1 a; d& R6 O' k* u+ r, r* ~0 I FAST char *pNewBlock; $ Y" I) I+ b- B4 M( R int blockSize;8 |7 _2 d i3 R5 X8 Q0 S3 ]
9 e3 W. v6 D% b3 m
endOfBlock = (char*)pHdr + (pHdr->nWords*2); 5 X4 P1 ^, ^/ h I# }* m! t! s7 S1 T) t/ d( F, \
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));: L; E: L- d# V; `
& `! j' K+ J# C1 [7 i
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));" P ?& ~) C! M! L
8 w5 ~% [$ _8 |- \
pNewHdr = BLOCK_TO_HDR(pNewBlock); ; I3 I; _9 p0 a; H& ?4 v$ a5 L$ d% e5 Y# Y0 X
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;6 H3 C/ v8 I4 ?
: h1 ~' {- F( k8 X$ P; d
if(blockSize < minWords)# S- ]3 n7 x" [; x9 {
{ 8 O2 @% y2 O( a( x+ q/ p3 T/ O if(pNewHdr == pHdr)* ^6 P( a E: o4 s
{8 K! Q u* M' q [* {9 H
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr)); , x) z2 e) s: n' @, r5 K; [+ l } b/ Q4 Z* o3 T1 E9 t m4 C else9 O a- P; p8 \' i: o( y" t- A
{. e h, A0 u2 J+ {
return NULL; ! _- U. U5 @. _, h }' q+ @2 l: O9 q
}' O2 |2 W! L0 q% w9 M
else 1 b6 x" v$ s" g { /* recaculate pHdr */+ ?" [0 K3 {3 r" ?3 e
pNewHdr->prevHdr = pHdr; 0 q: l: e" _$ H" c6 ~ pHdr->nWords = blockSize;( W! Y3 E6 o% K9 A% Q5 ^0 F2 `
} - R, w8 Z8 n1 l% `# N* x4 J4 b- m7 {
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)) ' g" L2 \/ n. X/ ^# \0 v+ G6 d {4 y8 L' s! C& U3 g* G! N; W* U
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2; H) r% t! G% u4 K( @ pNewHdr->free = TRUE;, r5 w2 D! F" n
: a2 j: N- d/ T) ? NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;( D$ V; g \6 N* n3 w% Z h
} 5 K- M! A. x% L" @9 \6 { else ( o. M1 L" v& D {/* space left is enough to be a fragment on the free list then */ 7 Y7 E/ j7 T: G+ H6 a pNewHdr->nWords = nWords;) Z G7 t( k5 q( w, p" p! X# F4 N
pNewHdr->free = TRUE;* c* b$ f1 T% f" ?% V2 t
; }$ ]" Y* q7 i. |- B0 {6 S' T. h& I
pNextHdr = NEXT_HDR(pNewHdr);3 q8 ]+ o& b5 o% ~# H( L! m
/* words 包括BlockHdr */ 0 H' j& v3 e0 `- J" Q) ~; |- g pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2; - Y+ u3 W- l' j+ ~9 a' }' ^ pNextHdr->prevHdr = pNewHdr; 1 `, ?( P. G! g- k pNextHdr->free = TRUE;7 U( ^/ e2 |5 j9 e' e
6 e1 ]8 T9 k& e- H4 J# Z dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr)); 4 o6 w4 H9 a5 j8 ^: x% ?: E . d, x1 z: e( K4 Y NEXT_HDR(pNextHdr)->prevHdr = pNewHdr; 9 l1 Y- ^; p7 e \ }9 _; ]: F9 J. B2 B. n
, Y4 g4 \# b$ \1 { V) r9 D7 z return (pNewHdr); ; o3 Q* q, y9 z$ M) v}3 ^0 j0 m& h, G$ J+ M/ A/ K