- 在线时间
- 490 小时
- 最后登录
- 2024-2-3
- 注册时间
- 2013-2-28
- 听众数
- 117
- 收听数
- 46
- 能力
- 268 分
- 体力
- 39235 点
- 威望
- 1340 点
- 阅读权限
- 255
- 积分
- 31237
- 相册
- 2
- 日志
- 0
- 记录
- 0
- 帖子
- 1388
- 主题
- 937
- 精华
- 0
- 分享
- 0
- 好友
- 111
升级   0% TA的每日心情 | 衰 2020-10-25 11:55 |
---|
签到天数: 264 天 [LV.8]以坛为家I
- 自我介绍
- 内蒙古大学计算机学院
 群组: 2013年数学建模国赛备 |
想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言
. ]7 |8 g4 W- F$ b
) g0 s9 J# g6 s( G; Z5 t" {% j" N5 N/ F# R( X
, B+ t9 z, K' t& G
*\file+ T& ^* k$ k; `7 S9 J! ?
*\brief k, I) W, R5 e3 k: u; R
*\details / `. V3 @; Z& U" ^: A6 P
*
, e8 n" T7 J Z! S3 S9 o: G5 m+ _4 z *\author Janson1 I( U0 e# l' Y) x2 }; S
*\version
& O$ o& J) w" K! E" |1 e, I( a *\date 04Jan12
* n ?7 E( T" k5 [1 | *
2 o9 Y* w" h \3 B; Y% j *\warning & e8 r/ v5 ~0 h( Q3 l4 v7 [
*/ x" ^5 v. G$ h0 C# p w; v+ h
*\history \arg 30Jan12, Janson, Create the file5 c3 ?0 s# w9 B9 p9 L; Z( \
* modify from VxWorks source! ] X# G* o2 t8 W6 q
* Legal Declaration: it is for studying VxWorks only.
! x5 Y% ]2 ]" k */
( g+ c& F- x( d. A7 G4 Y8 g7 V# g( n#include "includes.h") b9 [- v( K/ `( _; ?5 P3 i
5 p& ]0 p( T2 F& s/* The memParLib.h file is hear:
! i* h B- ~& V1 jhttps://code.google.com/p/vxwork ... rivate/memPartLib.h* U+ l" | f$ f1 Z" n" `* K
*/
- O7 _/ t0 ~- U) {$ ~" i$ @
6 o& \, E( G% R3 W: Q/* optional check for bad blocks */7 m% A2 W; P, V) }0 {
- i6 I$ g E+ {
#define MEM_BLOCK_CHECK 0x10
4 G7 p I2 }4 i; d
; J) s7 p5 s- ?$ f+ D; `/* response to errors when allocating memory */7 q8 v+ Z0 B( i, \9 K' V
* p9 x+ G3 H+ G9 E4 y$ E% G
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20) |# _: X. p9 ]! J* P
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40
$ O$ Y4 u5 h5 G, `% A5 x
4 D' \, ?! j2 K; [" v- ~& v/* response to errors when freeing memory */' j, m* z9 v( i+ S
& u" o j& u- t2 b! Q' o
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80% P+ d: Z6 R& Y( g, k
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
+ W/ c5 d& j, w: @
E3 V! X3 X! o- j: f#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))1 w. B6 a K% z
#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
% @9 A) q% r* Q6 F5 S
4 W5 W q8 }* o. Q#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
1 i6 Y2 N7 I, _; g#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
$ ~# A% J( x9 ^- e sizeof(BLOCK_HDR)))1 x4 Z% L% y- F3 {: K
( i2 s3 D5 T/ u+ N' B: S
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)- v% ?1 Z* X4 x- @
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \
. T8 H u! [( V% ? OFFSET (FREE_BLOCK, node)))* \: K# N( F# t, t
' U0 ~0 L! F! v! O9 u+ I
static BOOL memPartLibInstalled = FALSE;' u: A1 p+ p# G4 }
, E+ d5 i3 i& y2 B/ f2 s1 p+ C' b
static OBJ_CLASS memPartClass;
$ W4 U; O' P& H+ S9 XCLASS_ID memPartClassId = &memPartClass;
% P b! M! P% r- E% c, H2 k% |
! i1 B. q! S9 r8 A( v" tstatic PARTITION memSysPartition;
! J% H& O2 D. v2 u% jPART_ID memSysPartId = &memSysPartition;
8 \; t( N% t" S- @ l$ K1 K. @2 |U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;9 u- z( r( s! T2 O
9 O6 a# t" X; I
static SEMAPHORE semMemSysPartition;
3 S2 S# D9 A) r6 l% t5 P) t1 a2 |& {( F8 g) k* L; Z
static void memPartSemInit(PART_ID partId);! H) G8 m% |. t9 N- e5 a
! g0 s: _3 o) OFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
* i5 d) _: X! ?7 ~/ R1 T9 s3 R9 }* k
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
; O& e1 t" N ~0 D* r% V5 ^6 m5 w' i
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);2 [" |7 Y2 ?# j! c1 h: c
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId! i1 x4 m, ~- z. w7 l9 [5 w* L$ |
, FAST BLOCK_HDR* pHdr- N' u, [: p v" I- N
, FAST unsigned nWords
& q4 l5 v: H/ d6 q& Y6 z , unsigned minWords
2 ]! b+ i0 N- l1 }' A/ p , unsigned align);
/ O5 l, X: ~3 q/ I+ v$ T6 K
/ X* P, w; C: G4 B" B8 bstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
4 L& f, U# ]9 y/ `& m4 s" J6 F/ ]
STATUS memPartLibInit(char* pPool, unsigned poolSize)
' P4 Q* u' s; m/ }{6 v" ?* d' }, g, P
if((!memPartLibInstalled) && 9 l2 X* _5 Q! R, u5 |. k
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
$ j* A' I; }0 k2 `' F , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
+ F$ b* c4 l% t: c& l# X9 [ {
% U+ A- P% o" ^, k6 b9 F/ d6 ? memPartInit(&memSysPartition, pPool, poolSize);$ L' A# l% K! S1 b1 v5 V) V) G) u' ^) m
memPartLibInstalled = TRUE;' @3 H- F# F) }8 g0 d5 K
}
: ^& k+ |3 h" y$ p- u/ c. @$ d2 z
return ((memPartLibInstalled)? OK : ERROR);4 c$ E5 }. `3 [! u3 C0 K
}: J4 Q: n m, u6 f( ?
1 \& d" J2 b1 _0 M+ [PART_ID memPartCreate(char* pPool, unsigned poolSize)
( t+ c, N" [8 J* X& Z& B{5 y3 z- N0 f: ?
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
: K" j2 F8 N# \2 Z! |% \. k/ ?2 C. a7 e/ K# f
if(NULL != pPart)% J0 `! D% e1 N0 J+ t
{
; |2 {& U6 | A( o memPartInit(pPart, pPool, poolSize);1 ]2 h5 L6 l s; @5 q& O
} @7 I9 Y0 c Y2 w
! J) ~0 ~6 U4 B0 \1 ~4 b
return pPart;8 U: e/ `/ t3 Z
}
5 P( p* Z& C6 E) r: {5 O) m
' @ ]3 Y. S; Y! w: [ G! ? F1 @void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)1 n- V5 a8 {; ^9 ^
{
0 \8 r: o" l7 ~/ T4 t' w memset((void*)partId, 0, sizeof(*partId));6 _, o n3 Y7 c: ?
C2 @5 p# w! I: j, l) b6 J% T
partId->options = memPartDefaultOption;
1 \& `9 r! i6 ~/ D4 ?( Y partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */3 ]: P' [) V8 G# |) s( @' v* H
7 e& M' b) B: b+ \' o
(* memPartSemInitRtn) (partId);9 B; N% l Y( l
$ N3 u7 u- s" @# u3 D- x) Q. R
dllInit(&partId->freeList);# P* R% g6 n9 y% {# U9 K
) V# Q( ?! Q, A; _2 I) U( |$ o
objCoreInit(&partId->objCore, memPartClassId);
& W2 }# d6 L" T* |/ q; q# w# W
/ s# O% O* t3 k& ]7 G memPartAddToPool(partId, pPool, poolSize);2 @3 E, X/ K/ ~! p9 w# H5 Q
}1 U: g, F+ D% M
( b( z: Z. Q* g
STATUS memPartDestroy(PART_ID partId) j- h- q5 F6 J2 l. D& _
{
& e. o; ?! ^- v4 a return (ERROR);& i" L: ^- M& C! C& [0 @, ~& m
}" _# ?# N/ `% g Y
/ b7 [4 R- B& i
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)9 O2 ] v' W5 t; a6 `
{9 S! Y; ]& e% Q: f- a/ b/ H6 w# _8 _
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);8 G# \7 s& F1 k8 U+ o/ U- j
}
9 w1 X) }9 Y) J$ ?+ P% r n4 s* ~6 B2 o
1 m6 O% O4 H2 z; c/ L n3 z0 N
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
9 c% H- B! x+ M |{: G2 s/ D* i I( c z+ o; S: V
BLOCK_HDR* pHdrStart;7 h# H% F. R$ Q$ A
BLOCK_HDR* pHdrMid;
* \- C' b8 z" ~1 | BLOCK_HDR* pHdrEnd;5 i# i0 n) Q4 f p2 j2 X
char* tmp;( O0 O& w% G0 C/ Z' B" U5 I
int reducePool;4 {8 t" `' Q& C; S( E
3 r q+ j" a( H* v5 } if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */& D/ |% o! z" B1 H
{2 d" C$ E1 @- I! G4 M& B( Z) l1 k( m
return (ERROR);
, U$ z8 r, k) ~( y# y* M+ H7 d% }7 h }. j7 Q( |1 I$ i0 }9 S
' E5 x4 c) M& l6 @" K$ \( [
tmp = (char*) MEM_ROUND_UP(pPool);+ d9 U- H7 U, D: y; L! f/ z8 Z
reducePool = tmp - pPool;
3 x l8 s9 j! ]# v. j2 M `0 c1 o$ t
/* adjust the lenght */7 G, m" C" u' V9 ~
if(poolSize >= reducePool)2 ^5 u1 v! r& u. b# h* P. r Q' U6 E3 ]
{
, Z+ X' E8 z" I9 F8 b poolSize -= reducePool;
; ^! u: r8 q6 U' B n' A }$ V8 Q% p* S# ~
else
9 G" F% `1 O) R% r6 ]" z, r6 U {) q) d2 h& R+ O0 O& U$ D& V& i0 `
poolSize = 0;
7 ~& t* |0 d' }: W$ _ }" R# ^+ g5 s( W2 C, a, R4 ?
pPool = tmp;
* D8 ?; J' g% ]5 i9 f
# O" G! I8 G8 ^) C poolSize = MEM_ROUND_DOWN(poolSize);) V5 Y6 e9 t- y9 O) G# O) S- P/ f3 p8 n
' W" I5 o7 \( ] g! M) I
/* at least one valid free block and three header blocks */* o% ]) ]. L$ Y3 [6 ]% M* m- M) }& r( H
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
/ I0 X9 x5 i. j \% Z8 n3 n7 n {
' `- n) y$ m: z5 R. \ return (ERROR);5 i/ i; ~+ a6 B( w& f& `, P, |+ V
}1 b8 U$ e9 l" Z/ R
6 k8 P( y% y: W! n: ` /* initialize three blocks */
3 o8 C7 b" X( k1 G: ? pHdrStart = (BLOCK_HDR*)pPool;% O) C6 [9 g0 d1 [
pHdrStart->prevHdr = NULL;
& R, x% a) e! p9 U1 W pHdrStart->free = FALSE; /* never in use */
" b4 r5 n n: [% d pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
4 H$ q( N+ z' D9 i1 ^
) ]7 i( A+ ?: z5 o- L8 a) w pHdrMid = NEXT_HDR(pHdrStart);
P* l) q& F" c: D pHdrMid->prevHdr = pHdrStart;
# o$ G/ ?8 Z9 D) x) M) z J pHdrMid->free = TRUE; /* the main block */
+ N' J' I: O1 D/ Y& t6 V pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
0 b0 ]8 f+ X/ y5 J6 g" B" c8 x( D7 l U" ?" b% h. Q
pHdrEnd = NEXT_HDR(pHdrMid);
, g2 q) F8 Y& x: B) S/ l pHdrEnd->prevHdr = pHdrMid;
" L; {- B& @3 n pHdrEnd->free = FALSE;$ u8 {. M" H1 ?+ I
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;" l4 k- B8 E6 G, _; `6 l3 Z
6 n3 w# r$ v) i* {6 i' M' h+ ~; H9 H* l, h
/* TODO take sem hear */1 Q% `0 P5 [$ G' A# \
semTake(partId->semPartId, WAIT_FOREVER);" X% H( A1 u1 E1 v* r
* z6 ^/ S' l) x3 ~$ M) W dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
1 [& V0 @+ c! c6 p2 j! s partId->totalWords += (poolSize >> 1);8 [' g3 i( ?" n' v+ Y& b4 O
! F* `( O% s a# h2 y* [ /* TODO give sem hear */ J7 v: w/ }8 U
semGive(partId->semPartId);
4 k9 q* b' G- M6 G1 q
0 [9 M; [5 a/ i/ v1 ~2 k- [9 M- q& d1 a* J- ~
return (OK);5 e; n4 o+ X! b# s$ A5 t
}
: u8 @3 u" [9 M; C1 k: f
+ B+ S! \2 H- dvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)! ~" h L) a, @/ t
{7 S% t/ [9 n4 [$ e6 b
FAST unsigned nWords;9 o, W$ O1 \2 M" H ?) n
FAST unsigned nWordsExtra;
, n* N8 F' T- J& n' a! O6 D FAST DL_NODE* pNode;
& I. Z' A- L4 `! @" p FAST BLOCK_HDR* pHdr; g, u, d- c! K; h4 S; E4 z" Z3 G
BLOCK_HDR* pNewHdr;3 @3 s" x6 j3 Q3 } U/ m$ x
BLOCK_HDR* origpHdr;
) L. ?3 J( I( f& \/ ]2 J+ i$ J" Y7 u3 \8 B; _1 a5 |; b
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
2 i& h) d+ ], r0 ]0 w5 e {
5 ?# J. A9 x! V" D6 _1 L# t- m5 { p return (NULL);2 r' [1 ~2 |7 m, u/ X9 s1 S
}
; {& G4 e1 i& w. N" t' l: U1 o$ W& k* E# \
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
6 u. m* A* P' b; a6 g
% m1 b6 W [$ |: b if((nWords<<1) < nBytes)
3 c+ ?/ J4 x5 t+ e {4 o2 C/ ?1 J' t# o L1 n3 l# c
/* TODO suspend the task */
: |9 i- N( G$ S& N return (NULL);
$ x8 l# J8 k* y5 U' u3 t* E0 ^ }+ c% `5 _1 l5 ^+ g
$ Q+ U6 v6 W5 o$ u Z: k5 r" P if(nWords < partId->minBlockWords)4 q+ I/ H8 S! K
{
: M# Z% K. A& s; _7 n6 I. I$ {# a( t nWords = partId->minBlockWords;
6 g' w! r# m% @/ {8 B" z }2 [' P7 N0 u. ]( X: z
. S) I7 d" m3 k& n: N0 u /* TODO task the semaphore hear */
: X5 L3 n7 C6 T5 u Y- ^ semTake(partId->semPartId, WAIT_FOREVER);
7 }0 Z" s" [- r; @, M3 ]& f pNode = DLL_FIRST(&partId->freeList);
9 a( O4 X# @( o% a nWordsExtra = nWords + align/2; /* why? */9 f- Y6 \0 g; f0 Z' T
$ j; X' o; X; ?" z/ O
for(;;)
9 @6 x! Q5 q. U7 @ {
. s H4 g+ k5 R8 m while(NULL != pNode)
& ~3 J! U' c$ Q! ^. e {
; x1 l7 w2 H+ x& z. F: p! K if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||0 ~" K8 E. r4 B$ \ \: L
((NODE_TO_HDR(pNode)->nWords == nWords) &&
$ |5 g G4 e3 @/ R% g5 ^/ W( A9 H0 I (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))" N3 V9 @ O2 y0 s6 h
{
( [( r) g" i. ^; W/ d break;) ~! X7 J! r2 K% v. \4 h# l
}& N6 @, D4 S, N! C5 |
# n& Z' t$ i, n- o; |! n# `! A) w9 G pNode = DLL_NEXT(pNode);( @7 N0 ]3 X1 r4 G& V
}
$ S( T# X( j+ Q3 ] E! a! w& k4 L& h
if(NULL == pNode)+ \" X$ j1 ~' Y0 R3 F
{. w: e" Q# W: q& b) }# V
/*TODO give the semaphore *// d3 i6 e3 @% _+ P9 Q! V7 P. X
semGive(partId->semPartId);8 S7 U& q0 O* M0 y
return NULL;
9 q, N1 F- p) q* Y }
v2 M5 j0 X: ]2 R5 _7 D- s; \
& d% r6 B, K1 j% q+ P pHdr = NODE_TO_HDR(pNode);
5 Q9 S3 J" j' H" V origpHdr = pHdr;
v* w. H0 h0 F ^9 C$ R; H+ t$ M) M! h: j# W
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
" X6 ?, m6 W. }7 \1 g+ z if(NULL != pNewHdr)
$ j" {7 @) _. [ {" \; c0 L4 x2 n9 V- [
pHdr = pNewHdr;6 N3 S3 q7 `( n( p, S
break;+ I/ @; i) |* @( K2 Q
}
7 P, M: e7 n+ Q9 s1 ^, ^. V
( ]1 Z; M8 s: \4 a$ i4 q pNode = DLL_NEXT(pNode);+ ~5 U( K* S" x z: P
}
* O( Y+ R0 n. g- Z: S9 b3 t9 E" v) J7 o' r
pHdr->free = FALSE;( \0 E1 }& K8 q& R- t/ j) U
partId->allBlocksAlloc++;
/ F& Z* a' P0 M. K/ i partId->allWordsAlloc += pHdr->nWords;+ p, e3 e* x9 [$ b4 b( H
partId->curBlocksAlloc++;# L5 D, ?: z% @* ~
partId->curWordsAlloc += pHdr->nWords;
9 p" j, J0 N8 v/ v% N# s# t/ o' k# f3 T) F# U- s6 A
/*TODO give the semaphore hear */3 a" m+ t! B& o. L# C" e" Q" T
semGive(partId->semPartId);% a* ~2 M7 I. r9 V, ~; U4 j d
return (HDR_TO_BLOCK(pHdr));
! E F' i* r" H9 Y+ `: u& W& x2 T; F ) l" `+ k; G- c' b
}9 F* G& j1 W `6 @" l+ @9 M# L$ G
% o, K1 T4 z7 M. r- z& `
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)- j$ T, o2 V7 J, N$ }
{
9 }. W7 F8 X8 ~. D! W) Z return memPartAllignedAlloc(partId, bytes, memDefaultAlign);* q2 j! M9 O. Q5 ]
}0 Z2 ~2 P5 g7 ~9 C* |' t" `! ~
3 G$ ~3 R; X% p3 ]2 p
STATUS memPartFree(PART_ID partId, char* pBlock)
( t) U" T* h( [, Q4 g% S d{+ Q; Q/ V2 K1 ^ X
FAST BLOCK_HDR *pHdr;
5 m' N" j; R* z/ d% L; ? FAST unsigned nWords;) p/ {6 S# m- `$ c6 } \
FAST BLOCK_HDR *pNextHdr;( E' Y$ W! ~ {
* b0 u2 d1 z h% S3 Q; p/ r if(!IS_CLASS(partId, memPartClassId))6 w2 [+ H r7 A$ u. t8 }! ?
{
) c8 h+ `% r; N2 U6 M( M return (ERROR);
- ~% z: n5 }' ?/ X1 w }4 L! H# c4 u0 v1 h
. z6 G2 v- f# F2 u$ b9 R+ C if(NULL == pBlock)
% n. P' W' B" T- a, ^7 n3 P9 ] {
5 D' L6 m1 V, G5 v9 l& }# ~5 b return (OK);. ^# t% c0 {1 |* n
}, i( }2 i3 \8 |& U* z: W
( X# ]% ~) ^1 Y6 K7 O+ g" i
pHdr = BLOCK_TO_HDR(pBlock);
4 f+ B! R1 p# ^
_# M; q6 p1 ] semTake(partId->semPartId, WAIT_FOREVER);
* t/ l1 a9 c) ~" o+ ^9 Y7 I5 \# o' g9 N' Q/ ^1 O; ~6 S# A
if((partId->options & MEM_BLOCK_CHECK). [& `& u! J: L5 T3 p' j7 H y
&& !memPartBlockIsValid(partId, pHdr, FALSE))
8 e4 ^: }& S$ \, @3 A {
6 ?+ A+ Q! p5 r; M/ X# N0 X2 L0 h' \' h semGive(partId->semPartId);
6 i9 j& O, H) m$ v- \& ~ return (ERROR);
3 ?' k; K4 N8 ]0 [; ~. m# l }; I; v) j( t5 f, P& }2 ?
, H! o. t/ N6 ]0 c9 f ~ nWords = pHdr->nWords;/ C* R6 n3 r6 B3 z! U
if(PREV_HDR(pHdr)->free)
" F! x! u7 j. q$ O {/* the prev hdr is free and than coalesce with it */
3 v6 N2 ^! z) |8 T pHdr->free = FALSE;
0 z3 Q( {6 L$ m8 s( L9 q- v" u& v pHdr = PREV_HDR(pHdr);" Z& t' c9 q( A8 \
pHdr->nWords += nWords;3 d5 y0 N% q5 T0 N
}
! k9 Y! C* H# m9 S% I else
" u7 N# t* V- ]8 j; b+ b {
, f" }+ f! ]/ h! \! D* } N pHdr->free = TRUE;
- V) d& M6 I0 e, Y2 U dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));( c( D: b) R0 o9 n5 A4 {
}0 R( ~4 k6 M+ {( q% j% r2 c, j
# q" u/ F( ~: }- p5 s; _6 `0 Y /* check to coalesce with the next */
( s& j# ?4 X. P8 x pNextHdr = NEXT_HDR(pHdr);( o/ \+ t0 b' ]6 b9 _
if(pNextHdr->free); Y: E p. P* K6 ]9 _# {6 L) }" }8 w+ ?
{ e y" x: ]$ s; _2 l" `0 ]
pHdr->nWords += pNextHdr->nWords;
( F, l! ~4 u$ b7 O/ w1 X dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
/ h# _, p3 P; Y3 o7 ` | }( D) ?. ^4 r4 \7 M1 I6 q2 A
3 @7 P7 X; J& S2 C3 t) S
/* cannot use pNextHdr->prevHdr=pHdr hear */
5 ]; V! E4 A2 Q NEXT_HDR(pHdr)->prevHdr = pHdr;
( o: b: _# }% N0 r
s2 g7 `# g& N partId->curBlocksAlloc--;) z* h: \3 \" d- A$ F
partId->curWordsAlloc -= nWords;1 E \" `5 Z7 J
% b; ~ s5 g9 u* V+ X( X2 o /* TODO give sem hear */$ Q. w! Q5 ^' ?# L8 p- H) _8 b M
semGive(partId->semPartId);; f7 p1 `" d& ]- j
4 m0 v) l, T2 \ return (OK);
, H9 D4 }' O' c" J) p}6 \( h' z) k0 F! `
, ^/ H) Y! l+ p1 ?$ x( q1 f, a$ Qstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)/ d- ~- U$ w x
{6 ^" H, S7 i' m7 m
BOOL valid;! }0 ]1 j1 y J/ r; z4 n
( A6 t B8 X1 K$ U8 T% }- U# k TASK_LOCK();
( p* o. k' E- t0 j+ ~( N semGive(partId->semPartId);
/ Y7 H O, Z' T0 f2 x+ V! m
- w& z5 x0 H9 N9 P5 r/ x1 b valid = MEM_ALIGNED(pHdr)
5 M0 I/ B/ D& L6 e& R# b && MEM_ALIGNED(pHdr->nWords*2)
4 C' Q* k3 K: v6 w7 l. `) o6 k3 X && (pHdr->nWords < partId->totalWords)
1 k( |: a/ _0 \* u, n4 \9 q && (pHdr->free == isFree)
3 F; }8 z! ~2 ~7 Z3 i && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))8 \ G, E/ Q' r" L# K
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
5 r9 p. l& o( Z9 }7 R! ] + @8 ^/ H8 M0 h: p
semTake(partId->semPartId, WAIT_FOREVER);
( D" i" q P/ S' Z' P: P TASK_UNLOCK();
' z/ T* i4 k3 @5 F
% |) f S/ v6 s7 l2 m3 S3 J return valid;. e+ v4 r1 z3 q/ Z
}8 |$ m5 {+ J* J6 W
w2 V0 g9 Q5 f* I
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
% E! e5 d5 t! h , FAST BLOCK_HDR* pHdr$ ~ ]9 ], v2 p% ]
, FAST unsigned nWords, r3 t( r/ B' p
, unsigned minWords. z G& X. Y6 y/ R
, unsigned align)/ c- F* w5 Y8 i2 k9 y
{
9 Y+ e6 i, W6 \, T" d* H FAST BLOCK_HDR *pNewHdr;
' |9 ?) c5 z; H! s; n- X1 l1 ]( ? FAST BLOCK_HDR *pNextHdr;/ R% [- d" R& g# C' h6 a
FAST char *endOfBlock;
0 k. e) r h% q FAST char *pNewBlock;
9 L0 c8 L" i8 V* Y. n int blockSize;. I5 f% v9 J( L' c' ]& c, ~4 [
" q i/ P4 H) Q1 B3 s endOfBlock = (char*)pHdr + (pHdr->nWords*2);
3 o$ n: w3 u1 l: M/ Z! d3 X9 g8 X" N$ K
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
9 |+ _) b9 J& U3 p1 W0 o+ A
/ O; J7 ?; L; Q/ t5 n) { pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));" J( \5 \* m5 }5 @" }
3 W# |# u! ^% `8 O: O/ X
pNewHdr = BLOCK_TO_HDR(pNewBlock);* @8 c v) B* h6 C5 |2 u' u6 `
9 i/ ~) _ y1 F0 v) | L" Y+ j blockSize = ((char*)pNewHdr - (char*)pHdr)/2;6 x7 ~' F9 f& ^2 W/ F' s3 e8 h: h
3 b, M( A: S) \1 t
if(blockSize < minWords)
/ N; A1 V6 U; k* I/ G( T7 K {2 d4 H- K+ X) F2 @; V! w7 s+ z) w7 M
if(pNewHdr == pHdr)) q) }1 l9 a% [8 G% m7 ?
{" [& f. i6 C5 y( q& ^. v
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
9 M+ e' }% m# i& H& A% o }
. n; P: K( H$ x/ |* Y else. J; x9 a! i! f. l
{
5 i0 `% z# W2 q. `; k return NULL;
+ P* S. V% u0 ?. h( e }' j" S$ p. F$ t* |( p
}
2 p# S. b8 S7 {* ] else9 @ B* Y- j( D
{ /* recaculate pHdr */' l5 }( @7 U8 }8 E
pNewHdr->prevHdr = pHdr;
5 X+ ~! h& k6 o! v# Z' x2 D$ n8 D pHdr->nWords = blockSize;
) [$ [6 f( ~. n% d( }+ P* @. Q }
1 E8 {9 K0 G* I6 [0 x
, i2 v$ p% ~' ~6 a" s( ]/ F) o if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
/ b$ I* m b) L {% H$ V1 m7 `3 _/ y! | H
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;' E7 L! C! X) d. S
pNewHdr->free = TRUE;0 v$ Z0 C ]$ l+ `4 ?9 _% ~4 Y
% h- a; v4 |; A( y5 e
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;3 N0 y' e: T3 I- C$ r* {
}
* W; S4 T0 n7 X g3 c else C( s" b v& c5 L
{/* space left is enough to be a fragment on the free list then */
) \. m6 [6 |6 b3 {6 _" v7 F pNewHdr->nWords = nWords;6 R+ c" Z; [& R! R6 K* ]4 q8 B
pNewHdr->free = TRUE;% |+ l E' @* J) t
; S6 R$ r$ t' w* F# R& ?5 W. h
pNextHdr = NEXT_HDR(pNewHdr);. X L$ E4 ~- {9 f" l7 U4 i
/* words 包括BlockHdr */3 @9 @" k* n+ e& i" r; ~9 x& ~: o
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;' m% D* ]9 Y# p2 O' Q1 A; |
pNextHdr->prevHdr = pNewHdr;
% o0 M/ _! n; L pNextHdr->free = TRUE;. z) ~% H4 M! Q1 M7 Y7 r
* |# i. y% ^' X [+ f% \4 b6 q dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
$ P9 I( L& g! k5 a$ G; ~& I. s& {4 f/ U5 |' d5 b* z
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
0 a6 B2 M) \& Y1 D( F }
H3 W. p0 r/ p- X% q' P) d7 l3 ~ X8 C. L# M. U3 T; O/ g; ~/ H
return (pNewHdr);: y. w) ^1 l7 ~8 @9 R
}6 u; @" \$ z0 o j( l
7 i3 E2 f+ K+ W+ g; G- l
static void memPartSemInit(PART_ID partId)" M5 b9 n9 a+ j4 n9 Y$ _0 F/ g) {
{
; ^* l% d4 X7 Q* {# c) V. N semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
- e# m+ \# l1 I7 |9 t, S9 `' K+ f+ R2 R/ y& i) L
partId->semPartId = &semMemSysPartition;
, ]# g# B0 b. ]# O' U}# X( }) X; r9 b% N9 V
8 {$ w( T/ Y( d) W8 `- Z: S
void* malloc(unsigned bytes)
' \+ {; j' X* f" a$ E5 z7 a{
1 U4 v D! t5 S2 X$ N return memPartAlloc(memSysPartId, bytes);& M% _4 n* X; `+ s9 y! z: L
}
0 o9 [, H, X$ n
4 t, d+ v# y; g f6 }4 m0 ~; Lvoid free(void* p)
5 H/ j9 F' ?2 y6 O/ g{' W0 F3 d" W- H7 ~% R$ R
memPartFree(memSysPartId, (char*)p);8 g" _; p R' v8 w. D9 }
}
* [& x M$ Y' } |
zan
|