- 在线时间
- 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++下的版本,更方便调试。有需要请留言 + s8 B1 A6 b" w
7 |( e3 G# K# C& \1 F' C; C: ]) z
8 e5 k `2 I2 k5 B
$ R. f2 C# ]" {/ t0 W( N8 i) E$ A- w- z *\file$ |( u- \! N2 `- i" p$ ]# P, X( p
*\brief
9 {# [7 r4 L3 F+ d *\details ( e6 |0 h/ T' [! P+ h9 U
*. X9 ^6 M2 r& K u( |
*\author Janson7 ]3 n; t5 f* [9 B0 q
*\version
6 u* g3 [6 z- T* \. ]" R *\date 04Jan12 R4 H% ]% s2 z' _3 Y: J8 ?
*& d2 r% X" z3 j6 }6 m$ Z
*\warning
1 r; K1 Y* Q- X2 V/ a2 y *
2 L2 u9 L% c4 @# L) p1 d- A *\history \arg 30Jan12, Janson, Create the file4 W( v1 i( O+ ]( a1 k* N4 Z2 a
* modify from VxWorks source
2 Z( k7 z6 R0 P& O( a' @ * Legal Declaration: it is for studying VxWorks only.
( h$ h6 \# I) V6 V/ l* U */& T5 P: ]! L- M0 j- Q
#include "includes.h"
. k8 t! h/ a- F! i" r' w) Q3 C2 i9 K' M- g D q: g4 m J" Z
/* The memParLib.h file is hear:* `+ k3 I! u1 M6 _6 m$ D. ~
https://code.google.com/p/vxwork ... rivate/memPartLib.h4 ]; R* J* L5 @" G6 }; g# P6 x
*/
9 V7 C+ I; e v( u/ a7 z, R* P$ d) G
/ t, d/ U5 `; L5 h1 H: ^/* optional check for bad blocks */8 O8 B; H3 J. a$ V3 R
9 H% l2 R. B! Y6 z; c2 d) @ L* g
#define MEM_BLOCK_CHECK 0x10
! j; s5 h+ E7 c! E/ X# d; w- o$ {) U( w$ F6 q# p; t. a
/* response to errors when allocating memory */, t N) w! c) W& {) }2 g
* H2 I" E# V( u- ]
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
' u5 x$ H( h v8 W; o#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40
/ p( T$ q* K) `! M! E1 B) R& p ?5 m
/* response to errors when freeing memory */. I0 `3 `3 I! o
/ R# S6 ^/ q+ A' N! T$ P( `0 F
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
' ~ E6 W, P6 S+ {+ i$ O, ]: M! K' t#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100 |: V) a) |! V0 i
1 i* l/ M- i6 E* R; ? @1 o#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))); Y* ^* _/ C/ ^/ u. G
#define PREV_HDR(pHdr) ((pHdr)->prevHdr), }+ b5 v5 j$ x9 y- w: k4 {& w4 \
! a- b9 X( v1 w7 ~8 j#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))- G; t' f) v n
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \9 l* W) ^7 Q/ g4 c" D+ ?
sizeof(BLOCK_HDR)))
4 m o* M! t3 W% e" @7 U* o9 e! y" e i" ~2 j; a1 g3 k
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)- I- [' A" E( S
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \2 k2 v/ g9 j1 A! b0 m
OFFSET (FREE_BLOCK, node)))5 ?$ ?9 L) Y0 n+ j
% _, E9 p. W6 p3 C1 C) i* }* }
static BOOL memPartLibInstalled = FALSE;
1 k; ?2 z* Q* g- Q s" ?5 k5 t, j5 T' W4 s. ~ d
static OBJ_CLASS memPartClass;' ?+ {4 [' c5 T3 H9 j
CLASS_ID memPartClassId = &memPartClass;
5 j: z7 h1 S1 D/ {* a- ~* f0 S; _3 J
5 Z0 o; ], X( @* m5 }5 }9 ^) i, Fstatic PARTITION memSysPartition;5 m- L4 n6 ^2 Q' }* A) _8 T, G
PART_ID memSysPartId = &memSysPartition;0 \# p# g3 C$ R% V
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;) j% R: i% a; H# ?( R& y& \/ q( X! e
$ d) H( U% @+ }% J& Qstatic SEMAPHORE semMemSysPartition;. s2 j' R; K4 c
4 P* _, `2 p$ v3 Bstatic void memPartSemInit(PART_ID partId);3 P/ S. N. `+ |1 a0 Q8 L3 P. N
7 W# c6 i+ N9 b2 {5 ^FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
: r: R2 y5 L# }2 \/ p. Z: P% C2 ^9 l- I7 U* ?9 H7 F' h: R
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;, v ]8 I/ p, k- r4 o/ S" i
; x( l r' u( I% Pstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
+ U, g! N( Q+ N- hstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 y `* w) @, r
, FAST BLOCK_HDR* pHdr% W$ {4 z' j# b6 q
, FAST unsigned nWords$ r" S; t" f( l+ I
, unsigned minWords: G, V- h" C% w
, unsigned align);
! ?8 M2 V4 D0 `8 N7 n/ [. C* z5 B: I/ U# L. x# ~, T, X
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);' G1 `, j" T8 [5 j
0 `- f$ v% y' H6 {
STATUS memPartLibInit(char* pPool, unsigned poolSize)) w9 b+ Y* K7 W' A, K( n
{3 Y" O( h0 n9 o0 C4 w8 u
if((!memPartLibInstalled) && Y* K9 {) w. D& C6 O z: B2 b
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)4 g- g0 W+ a9 r8 x0 [8 V3 z6 c
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
. c8 j5 o+ m) A% k- E' }" j) C; p {
. e( ]8 u+ h. |5 y memPartInit(&memSysPartition, pPool, poolSize);
( B. G& a5 D% Y. }+ B/ W memPartLibInstalled = TRUE;8 |3 A! i+ \, f; U* Z; h
}
+ T. o: A. J* P7 p0 S |4 _- L ^
0 O. o$ z' r" _; ^* n( @ return ((memPartLibInstalled)? OK : ERROR); N2 I: j$ a5 C
}
+ j, L5 \- A9 f3 N5 v4 Y j8 k
" C2 Q- q$ g: D/ I8 ]4 V9 UPART_ID memPartCreate(char* pPool, unsigned poolSize)
. u+ `5 f7 Y1 ?9 Q% {{
' P" g: D3 E0 T1 }5 G1 [ PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
. n7 }* j ^6 ^/ U' F4 e. d$ i- n
) k4 _- c8 f- n8 u. F4 k. K: U if(NULL != pPart)
4 o: f5 a, R8 h+ ]; Z* R {/ k& T2 V3 w/ P4 R
memPartInit(pPart, pPool, poolSize);
3 S3 T2 L8 T5 r. h @ }
. V+ a+ _+ ?0 a/ n( m4 K7 _5 _7 j) P5 j4 u& e
return pPart;
# Q8 L% O, }$ d* E( F}
5 G( f" l4 e! @% t6 `1 k% g3 K4 |" y. b; H( F# n1 u2 B1 ^3 M: n
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
) Y0 ^: A R. k1 O3 p, ?{$ t4 j& W7 k/ g4 l W' \
memset((void*)partId, 0, sizeof(*partId));9 r8 A6 h$ ?% m; d5 _8 [5 j% c
7 L! o0 S0 \. K n) f7 O2 H partId->options = memPartDefaultOption;
* X, L( n0 T# | Z0 O4 g5 B- z partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */9 E! d3 U8 I7 o6 \0 p
/ o; D# o' B8 Z
(* memPartSemInitRtn) (partId);
. {4 O& ]7 g# o # p- X* v! `& g6 O& Q% f
dllInit(&partId->freeList);
8 I1 F& Y& u K0 F# I9 f
. k# o9 `' J: W" _ objCoreInit(&partId->objCore, memPartClassId);
5 k/ p1 q+ g$ { t6 T $ l: Y- g1 A1 Z6 y. ~
memPartAddToPool(partId, pPool, poolSize);
$ {. t7 E9 [9 e N U* K% {% i}: w5 S6 w8 {, Y5 @& _) Z% y1 R
6 i) \5 N& r$ w. |, J6 r9 }. ?/ Q7 T
STATUS memPartDestroy(PART_ID partId)
~, C) ~) s2 z{
( Z6 @/ |# b' y return (ERROR);
^: O; t1 [9 \5 E+ F" C# B}; F/ o/ Y3 u! X9 z& ^, B, H$ I
9 J5 U0 S9 Q0 P6 Y7 E7 Lvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
# k' U4 o$ Q F% j{ J5 ~6 J* ~- R X" x- L
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);
# e2 ?) Z+ O) }}
7 M- u, l+ H% m& r- |, M( S
% \* M" X( E8 P. h8 ^$ H+ t0 d5 v e; g: s* b
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)3 o# v% [. ?; _" G6 ]. x# {$ O6 h$ P
{, y9 s/ J" c1 \8 L+ T3 I& y
BLOCK_HDR* pHdrStart;5 U- Q; |6 \. N3 x5 [% _( r" F0 s
BLOCK_HDR* pHdrMid;
, G' f* I# X& w- S BLOCK_HDR* pHdrEnd;
- u. B- ^% x ^8 w+ A! E. @" H char* tmp;
B" S$ a1 Z+ m+ ^4 O int reducePool;
4 G2 p. v& ]1 H; }
$ j. I4 ^" M$ b ]* R3 U3 m' O if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */7 ^2 {2 X' {4 p. D$ n/ H
{+ t+ y4 `( r2 z0 ^5 S0 @9 w
return (ERROR);0 M/ K: S' O% k7 C$ z1 M
}7 w1 M& D+ @7 Z* h) e
. f5 N; G- x; s- L+ G tmp = (char*) MEM_ROUND_UP(pPool);# U- b( M1 l3 A: n- _5 k9 a& @5 ^
reducePool = tmp - pPool;
A( p a0 j1 Q1 ]5 i- X& g8 v
1 J/ t3 q( C& Y9 e4 i! d i /* adjust the lenght */
7 f9 U* q7 U. Q- u# x if(poolSize >= reducePool)! y) w: N3 K5 E0 _: w8 M% F
{9 D2 K# e- B; W
poolSize -= reducePool;6 A5 ^1 \! r' S3 n$ ]. D9 H/ z
}
' c' ^/ s$ `0 Y. A7 n else E6 V+ J. m2 H) x
{
6 U& @. }$ s9 v3 \8 x poolSize = 0;9 _' f2 I$ I t# I1 o" E( O n
}
2 R( P1 T5 R2 J% W5 T pPool = tmp;
2 Z/ h( Y- \8 A- Q5 S q+ r
5 t& T! n7 Z3 ]3 h8 s; h8 V Z" s+ R4 O! u poolSize = MEM_ROUND_DOWN(poolSize);
' W4 E/ h3 h r& T7 D ' J2 Q* i2 E8 D# L4 U
/* at least one valid free block and three header blocks */
7 F; U# E( c4 }. x if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
0 d/ Q, o* _! b2 y4 j {
! k+ { O6 \! [( `3 o- P return (ERROR);* V3 g& E3 l* w4 @- f2 M
}
/ {- e3 w5 A, r+ U) h, `: k2 v- v6 {: ^ E/ r1 N$ i& m, v
/* initialize three blocks */
7 `4 s+ V) P! ~* b& \8 ~' L pHdrStart = (BLOCK_HDR*)pPool;
" c+ G/ L/ T2 i/ O8 L pHdrStart->prevHdr = NULL;
% Q) E _9 ^! r; A pHdrStart->free = FALSE; /* never in use */
- L; i' ~0 @* X pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
8 g" C' U7 p& \2 j# n4 v1 u b# X7 D& M; k3 K2 m
pHdrMid = NEXT_HDR(pHdrStart);- t% v: ~+ f) C3 q
pHdrMid->prevHdr = pHdrStart;' u- t0 b/ l( I6 X. \) e& v2 ]
pHdrMid->free = TRUE; /* the main block */! }) N$ j" O" F* C: ]* H' n
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
# |: F( i( o6 p* n# P6 P M; G, d/ [) t' w
pHdrEnd = NEXT_HDR(pHdrMid);0 f# d3 R& u1 {* L/ g* S4 D" v. P( Y# O; ?
pHdrEnd->prevHdr = pHdrMid;
. {" G+ l2 w& |: ~; J: ] pHdrEnd->free = FALSE;
) I/ {; }! |, O- O$ z- M4 F pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
! E" [+ {+ m) F2 R# T, `) b/ f! U
/* TODO take sem hear */) O _8 Y8 t2 {& x9 N1 C( C
semTake(partId->semPartId, WAIT_FOREVER);# y* z5 f9 R% n) }" H8 Z
' S* u' e& _, |9 f# N9 a
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));- [* V% R- ?# Y) D. T+ T- [( y, U
partId->totalWords += (poolSize >> 1);: j- D3 y* F* _8 T6 H( E. f0 A
0 F& Y$ `& {2 h: p9 U$ R /* TODO give sem hear */" M9 U2 x/ J+ x# I( w2 p, o+ @
semGive(partId->semPartId);& a0 x& y# N0 q6 A/ Y+ V
5 `- \8 V* h- S0 ~5 o, Z1 c% l
) i! `4 r8 A. [ ? return (OK);
4 W& O. v2 L" L- _& `+ X) Q L}
. g1 M- U( I! F5 Y
6 L( H+ r) P5 D: _. Gvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
& C% k! D4 b7 {{
( M8 L3 F! R. d7 F5 }% M FAST unsigned nWords;
3 v- i: r, Y$ N. X4 g. k$ c FAST unsigned nWordsExtra;
; X" C1 `$ M; j' u7 s0 | FAST DL_NODE* pNode;
6 _% `: O4 u4 V w5 i2 e6 L( l FAST BLOCK_HDR* pHdr;
# |: C5 u1 @. _5 ~- Z BLOCK_HDR* pNewHdr;- r3 o1 h# o& ]6 D3 L% ?% ^/ m% N
BLOCK_HDR* origpHdr;
) s* z$ L7 v1 L% P( t4 t- V" g8 H% [/ U8 s( _- ^, z
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
' k% t: y1 Y4 J! B* F {$ f9 t1 N' Q6 x! ^) V
return (NULL);
! A4 |# h7 ~; o9 ` }+ E) Y1 U( ?! E& z7 i
* M1 r5 x- y, K: L0 _4 F nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
8 q& h3 T% q1 O: x3 n4 b, _# k
3 [9 r# k" q/ Z$ s if((nWords<<1) < nBytes)$ P2 |- e9 h9 T3 h, p
{) D7 }- t* S5 g( ]
/* TODO suspend the task */
" }. W: v9 n! m! E, d) S- B return (NULL);3 e6 ]7 f/ k1 ?8 E2 N: c
}
* C# \- w: q8 W: C9 D9 ?3 k* W, e$ E! e
if(nWords < partId->minBlockWords)+ ] d @( k" A0 [1 y% T
{ h) R- o! d/ S+ f
nWords = partId->minBlockWords;+ @/ s. q/ A% x) y0 V
}
; s. q# B( ^+ H9 X7 g& d
: \9 c3 Z( [( g /* TODO task the semaphore hear *// w3 N# ^- ?. N3 F4 z
semTake(partId->semPartId, WAIT_FOREVER);2 o- p$ n, G ^3 a! D" Z( n2 X2 T: k
pNode = DLL_FIRST(&partId->freeList);
! p2 L& I1 k" t$ I nWordsExtra = nWords + align/2; /* why? */
! ^& ` v {4 T; s
. p7 Y- g% [+ T8 D" i9 } k r& q& S } for(;;). X3 O, ]6 ~" A( l5 U$ H
{+ z5 u7 W' n: n+ Q; @$ @
while(NULL != pNode)$ \4 j5 O) S- u: V M# }
{! Q/ Z" u: c9 t( K0 h( ?8 @: J
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
' L9 o: A# k2 K8 _0 Z2 K ((NODE_TO_HDR(pNode)->nWords == nWords) && 4 K! Q" N3 q2 H7 @9 a2 s
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))# [/ i! \+ \1 R" m
{, d/ P8 }+ g$ k4 S" K& p6 g
break;+ m( C7 R5 ^9 e" `6 P
}0 G8 |1 R# H+ b- J4 M* p
- g7 M7 u- Z7 |" ~7 x% g: b/ U$ N pNode = DLL_NEXT(pNode);
! F# x; D& ^) v8 J }
. P0 _) J1 t. m/ v; ~% K1 F8 a! }5 b3 L* z+ C# W
if(NULL == pNode)' [9 z& j4 ]( N3 y( j" u
{3 ]6 O" `& F* U6 G1 ~
/*TODO give the semaphore */+ _$ v7 u1 C T
semGive(partId->semPartId);$ R; {6 s+ B5 M6 o' z! Q/ }
return NULL;" i; a2 k, v) x, e
}
. ?! B- o/ Z& Q/ U1 Q5 ^
( ~' J) [& U3 q# D* ?& N+ u+ X pHdr = NODE_TO_HDR(pNode);
( z* b" O- n5 A# V8 e1 X origpHdr = pHdr;2 R2 r/ k+ D# t% c4 i i
+ x: |) p/ o3 Y7 Q$ X( N& F pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
* K. R+ |, \# g if(NULL != pNewHdr)6 y, p1 a7 O( K; M) I+ Y- a
{
6 T# k( u! D/ V: _" B$ n pHdr = pNewHdr;" @" z+ s) x7 y/ n& F
break;
( d x- `6 P# I! m }# [' G$ n* {: [4 d/ Z# O
+ r4 R4 J. h& T8 Q! y" Y& ?% _
pNode = DLL_NEXT(pNode);. r( R& @) z0 _9 c4 |
}
# e4 B7 x+ W& b7 W" \# E! P
6 o. S% R$ M( Z+ U7 C( w pHdr->free = FALSE;
1 \! {7 K6 M% e: g( v8 {# L partId->allBlocksAlloc++;
: ^+ g) V0 }; @* B partId->allWordsAlloc += pHdr->nWords;+ H! z5 K* b0 r* R
partId->curBlocksAlloc++;- X4 I v. T( P; b: N( f5 |0 X
partId->curWordsAlloc += pHdr->nWords;
6 d" l/ N; X9 u/ d. D5 G' g1 B) {8 @: [$ P/ S: V- u
/*TODO give the semaphore hear */" \( E6 |* f3 i/ E3 L$ O
semGive(partId->semPartId);
, V: t. u+ r: R3 E return (HDR_TO_BLOCK(pHdr));
4 y0 R `3 d% K: ]$ j5 b' M8 Q + O% Y- N: {" X
}
# `8 T" L* t! K4 I% M8 R/ }7 @0 }3 _' ~# `1 z( f8 F t4 `
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)+ M8 y K: W* o
{% \) t. Z1 g8 S0 D6 n/ }
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);6 X" ~" G4 P2 X& A; V: v$ \
}, f+ i3 \, b: C, M
- Q- ]4 `0 ]" A8 o; W: C
STATUS memPartFree(PART_ID partId, char* pBlock)/ l/ r" U6 ~* n, E, g! n
{% O4 [5 q' N. q0 A) N0 V/ L
FAST BLOCK_HDR *pHdr;
) Q, V! B+ z. A4 P$ m FAST unsigned nWords;
" Q. ]3 l( g$ z, q2 h K g9 ^ FAST BLOCK_HDR *pNextHdr;, [3 |. i& t& o! I4 n+ `( Q* m
2 v) i, e% P7 g# Z: s. x if(!IS_CLASS(partId, memPartClassId))
% r2 u( k% Q+ i2 N; _# z% d {8 b, W, l+ c4 r. {. @+ C$ n
return (ERROR);
' x/ g9 U. n! y5 R }
C1 r7 z+ Z6 u) p1 [* v( }8 F) v3 m# s2 {6 r. l5 a. u5 E; b
if(NULL == pBlock)
- ^ P9 V; C* h) U% a3 _. S7 u {- L3 S/ |6 L$ H
return (OK);: G A" } m9 y9 n+ l
}
+ s! |8 T7 J$ i7 ~% A3 o( I9 ?! Q( _7 W) k+ \- ^ Q$ l N8 C
pHdr = BLOCK_TO_HDR(pBlock);+ U- \( O* K& ] O
4 ?+ E& H- ^: L7 j6 S7 |) Z/ K( u8 e semTake(partId->semPartId, WAIT_FOREVER);
* a2 L' v+ s" A2 j/ A! @# B5 ?- M) z
if((partId->options & MEM_BLOCK_CHECK)
6 i# G' j9 ~5 n* M && !memPartBlockIsValid(partId, pHdr, FALSE))7 H, g% V% R0 X o2 A5 {* Y# u
{
# x/ F9 C- I: C+ p" m9 S semGive(partId->semPartId);
# m! e9 l9 l& S H ^. e return (ERROR);) _) h7 V6 ^9 K& G2 t
}1 H. ?" s# A1 j$ J, f2 ~+ K5 W
4 F5 K# I- o" G" {' ^" M2 v0 I# D nWords = pHdr->nWords;
% U$ Z3 r) B# }2 B if(PREV_HDR(pHdr)->free)
) d+ F1 a: f% x1 H& F' f, r {/* the prev hdr is free and than coalesce with it */
" \: W' R3 ]& r6 Z pHdr->free = FALSE;: t2 l5 e5 b; G- [9 L
pHdr = PREV_HDR(pHdr);
* p2 C4 A" Y( o, t& | pHdr->nWords += nWords;- i& s7 D! W9 x' A: B4 K( ~
}
& n8 O; q( G6 i else ^( R1 Q, M& |
{) d" T% E) y% M& T5 I) l, J
pHdr->free = TRUE;. }1 r8 W2 ^6 v+ N
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
* K( G/ H/ x8 O- t; t" g. G- G }
- s% @* ^0 E) e1 Q; p
2 U, V+ C* {, ?3 R, G7 x /* check to coalesce with the next */
4 H% w) b& t5 Y# a4 g0 A' u9 L pNextHdr = NEXT_HDR(pHdr);; V9 o; {1 `% S- v* a1 A+ j
if(pNextHdr->free)
0 P; u* u( K* T/ p0 S {$ w' l1 d" _! J. l
pHdr->nWords += pNextHdr->nWords;
( F/ {6 }. l& {% n& d' q( ` dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
2 m Y2 F: \# ~( I, c, |6 a) L }
6 W3 Z$ T) y# n- @, N, Y* X7 a$ j, \- l3 g3 I. S) }/ Y8 B
/* cannot use pNextHdr->prevHdr=pHdr hear */
% n# w6 |5 Z9 K# o" X3 c; ^( i NEXT_HDR(pHdr)->prevHdr = pHdr;
6 a6 H: j ]) \1 l! B1 M8 m* `4 t, ]# M/ P
partId->curBlocksAlloc--;4 D/ x6 ]& g( d% `, K. ^
partId->curWordsAlloc -= nWords;
* S0 O$ S" ~) ^- v4 @
+ N, H" O9 E2 L8 o( W /* TODO give sem hear */, U9 y+ y: c& e% g3 u/ v
semGive(partId->semPartId);
' N" _5 _, I1 W, ?; | E 6 g9 k$ Z, p4 ^7 H4 T3 x7 q0 l
return (OK);
* K( M0 {$ W1 E, J) {( _}
/ V9 v+ X: o! D8 L* w* W9 |" Y
- Z; k( U7 `, C7 {static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)/ { R2 d/ ?# S
{3 U. k* L, e4 A5 Q) ?9 U( k: h
BOOL valid;0 B% j1 [1 x) |6 v
i0 N9 b7 T) n
TASK_LOCK();& ~ e8 F2 r. p/ L1 L9 M9 `+ U& ?
semGive(partId->semPartId);4 D# Y6 ~& J' O
% v4 n7 N" H3 s: \; I) U, r* u valid = MEM_ALIGNED(pHdr)
% `' q) E$ U+ _2 N6 o7 e9 ~ && MEM_ALIGNED(pHdr->nWords*2) j% N" W7 E" f2 E( F
&& (pHdr->nWords < partId->totalWords)
* X8 e6 w1 b# m d6 G && (pHdr->free == isFree)! U# Y o) E0 h8 n! i
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))) [2 y/ G* B. T
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
1 C9 [2 }! b: b2 p2 ~$ V: h
) z/ h" t& b+ ~% K" Y2 ^, M semTake(partId->semPartId, WAIT_FOREVER);
# m" |: Q( d7 K" a# m) d0 W TASK_UNLOCK();
$ F! A, S7 x0 h0 N' z7 h/ O& k) h- Z/ V! c/ _/ Z0 `+ G; ?$ x# T& x9 b
return valid;4 q8 {1 D+ Y$ ^ t/ j) v( S. l: e+ O4 G
}
( d2 O$ E" S" X j6 R. S# }( N2 ]- ~
a1 B7 V/ i& z: ustatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
0 T4 U7 e3 N! Y# I( Q/ w , FAST BLOCK_HDR* pHdr/ J# h+ m1 k7 x, }9 {3 B# p
, FAST unsigned nWords
3 l3 m1 _! M4 z) M& C: e , unsigned minWords
& |. U6 q+ m0 x' X. Z2 ~" j- g5 |5 N , unsigned align)
. H3 k* }5 a' E% j3 l{' E) Y# w/ H; J/ u# p
FAST BLOCK_HDR *pNewHdr;+ p8 j% ^4 x0 Z9 P
FAST BLOCK_HDR *pNextHdr;
8 T# M: s$ E* u& t FAST char *endOfBlock;
. q8 ~. K( d3 q! \- F$ o FAST char *pNewBlock;
1 N- s/ H/ n& y2 ?# U' {; y: U$ R8 }5 Q int blockSize;
' ^0 u b: a6 L E- C
4 Y1 B( l- M7 P- C- o; v endOfBlock = (char*)pHdr + (pHdr->nWords*2);3 T/ h+ V2 J* S$ n# T5 e3 J
( p& |) ?; ~. B7 I# d/ _& s& A pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));4 b: m C# ?! d
) q# _5 e i8 N# |
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));4 f- I9 O. w( N! s" e' o: k
$ ?2 K3 n: \# U8 K. Z! A
pNewHdr = BLOCK_TO_HDR(pNewBlock);$ j% y; |, ?# {; A8 I5 o2 ]& T* @' |
, P4 _: m6 F$ d6 W" o. l# H" `
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;* l) J) i# t$ m6 c% c6 s$ n c- x
4 v1 _0 d9 C# L" |- g( p Y" L& Q if(blockSize < minWords)
7 K* W! G3 d5 S4 s- E& g2 j {
/ b `2 E- i- P2 ~+ v if(pNewHdr == pHdr)
' B5 k8 G: E3 C, O {% N b$ B# H" o0 l
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
8 y% w1 \" v1 S5 o }
& Q6 M( I* W& E B7 `) C else( L! ^3 _2 H6 p/ Y" z
{! o, M a2 x- f% I2 s A0 }
return NULL;
# d6 Y; d( k9 S. r) [ }3 s* U% _ R9 J! k5 o: l
}
# g& B% w6 T6 X else# j/ N2 F- ?; C
{ /* recaculate pHdr */
# Y ^) N# {1 t pNewHdr->prevHdr = pHdr;
. ~6 e7 ~* z+ S* B$ x) |( r pHdr->nWords = blockSize;
$ |6 Q* H1 Z) I1 i7 w }
5 k: ~$ i6 V) H
; n8 R8 i6 Q+ O, ]3 o* R if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))' D* r( s. _/ p0 V% B* [1 O
{1 Q0 r0 |# r" l+ Q- m" q+ s
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
5 R6 e. L! A. s* {$ W pNewHdr->free = TRUE; l5 _8 e) V6 P: Q- Q9 @# `: I
1 a" {9 [5 X6 @ w NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;4 v. {4 G* ~9 i' z9 i& }
}
' S! @4 L9 g+ U2 |7 N' @ else
$ X& s7 A* M7 R {/* space left is enough to be a fragment on the free list then */
+ S$ p6 P0 q; I/ ^3 ]; g! ]9 v pNewHdr->nWords = nWords;" D5 l* r) z$ ]% ^
pNewHdr->free = TRUE;
! p7 {$ _0 J% ^1 R6 t1 I0 K2 _+ K2 ?. }6 I
pNextHdr = NEXT_HDR(pNewHdr);5 ]7 Y+ n9 |2 H+ H7 v3 V8 p% f: B1 X
/* words 包括BlockHdr */
( [% q; x! a8 a) a, r pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;/ p# P* f. n; j& t8 R9 h/ Q
pNextHdr->prevHdr = pNewHdr;; \! ~, c% E2 J9 I6 j; f. [
pNextHdr->free = TRUE;& x: K3 O6 ^$ d' z4 r2 I& z3 ~; ^
& }3 }# K1 y$ }) \# F+ \, V+ E
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
2 y! t4 {4 A5 F! h1 d$ l- _4 |: ]% [% ~: l, \3 u* b1 w
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
! ?4 ~3 v9 L9 b o* B }+ _. H% K4 E* i! }# K
A8 T& }0 i) g, j
return (pNewHdr);
. ~+ F; p. y4 M& ?" x) O9 J3 v0 m}1 x5 O) s/ Z* U4 G/ k0 ]" Z' @" A
/ a4 f1 u0 G1 V1 a! @, s4 F) }$ Jstatic void memPartSemInit(PART_ID partId)
, C* x8 X/ Z. ^7 ]- e2 q{, k8 O: b6 _. n+ b$ H: s" c/ ?8 x
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
' P! y$ u9 ~! L& _6 ^' E K( G7 b& @9 v) g
partId->semPartId = &semMemSysPartition;
+ |/ p: ]. O5 \* x4 ?}9 ]$ }; ?3 s' I6 e! f& m; v' w
5 `/ N+ d, J( j% o, x1 j
void* malloc(unsigned bytes)# W: N3 P5 j4 }" D: |9 k+ k
{
- a; u+ U( d4 O8 o+ \ return memPartAlloc(memSysPartId, bytes);0 ]. p, M% f" `( o, Y& _- K, U
}; i; D8 ~% z' L. K
! n4 j2 U. ]' B j3 h/ `6 ^
void free(void* p)8 x2 g$ s) b; t# c. p
{' y2 w7 g+ L) o/ n8 O
memPartFree(memSysPartId, (char*)p);# H6 q6 Q1 E+ {& M" d N+ Y
}8 H7 V% W% \$ ^# L+ K
|
zan
|