- 在线时间
- 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++下的版本,更方便调试。有需要请留言
8 v$ ~' ]3 R$ g' t1 d) d0 c3 y
) H" A3 h' F w/ p- u! P( p, P0 }% B- Q/ `
: F ^* f4 J4 z' F *\file
5 o. r7 j$ Y6 f# A7 k *\brief : i2 c8 {6 i+ n* _4 F m9 \; m
*\details 0 ?! e# B3 H$ P1 P$ p
*/ q- R% W8 h6 i' w
*\author Janson! h/ M, O. y8 j
*\version
4 w6 G) E& `2 w! T: t) S5 M, D6 }1 i *\date 04Jan125 Y$ ^* s+ Q- J! ~5 P
*8 {* ]7 k; {' |+ d$ q4 L
*\warning
7 `/ Q# Q2 M2 L- _) c* q *' r, t" M/ D t- p3 N1 `; c6 C5 C5 \: p
*\history \arg 30Jan12, Janson, Create the file
7 b0 \. ~1 `# o' }8 }, { * modify from VxWorks source% O W" w/ `) f8 V6 ]) Q! A
* Legal Declaration: it is for studying VxWorks only.1 r, j/ h% s" o& ?2 M( \) s; n
*/
~9 O: L3 z9 @- P' S9 K/ P+ p#include "includes.h"
: `9 ?+ C5 D. y0 S& d% j, z9 o5 V* B6 F* }, ]; E* f
/* The memParLib.h file is hear:
$ M7 L1 c( \4 C, Z1 f" o3 x8 u. ]https://code.google.com/p/vxwork ... rivate/memPartLib.h5 O" U {" p. e: T9 c
*/
0 M% ]% ]7 u" n/ v" V7 w- I
# r. ], ^0 t( w- Q/* optional check for bad blocks */
0 a2 ~8 b; X, V& x$ i6 M% j& O w! k
$ q" H- n, k* m0 N#define MEM_BLOCK_CHECK 0x10: N( O3 A8 F# n/ E/ V0 E
3 U4 e2 o0 z8 C* u- Y/ u
/* response to errors when allocating memory */4 F% W* V& r; w
* i% u' x. P1 Y# d2 L
#define MEM_ALLOC_ERROR_LOG_FLAG 0x201 |5 n6 q: z* R! `
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x405 R7 v# N! C. N
" {5 L" J: Z3 x1 b1 K
/* response to errors when freeing memory */. A2 g2 ]+ @% f' \# P: |$ R
/ l% _ S2 e. v# n+ ]7 M) m0 A#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
. G8 c. e D3 v#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100 p4 x. v) ~& }# ~0 V! Z3 V
5 h# H' N* B0 h#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
8 e3 t& z1 z+ {; _2 R4 Z/ u#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
! {( e D" }; Z
- X3 w; {$ U/ n7 N6 q' |#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))2 V) ?0 r; G% c) m7 X/ e
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
* | H2 B* s2 \. p5 C sizeof(BLOCK_HDR)))
: S1 O3 ?3 l, K7 Z; v
" i1 M; c/ F. j2 [#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)- @ c. l) n4 L$ P! G' G2 b
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \
6 x) X: c6 J+ k$ M& g' k5 d' T5 J OFFSET (FREE_BLOCK, node)))
2 _+ L- k6 X* Z% D( R% A2 L( R- J' R$ K/ O8 _& B, O) N
static BOOL memPartLibInstalled = FALSE;3 P) C2 r. B& C! w8 p, P, i! ]2 q0 L
# [/ Y3 E8 E# jstatic OBJ_CLASS memPartClass;
) p6 l7 P: F( x2 @; m0 D* H LCLASS_ID memPartClassId = &memPartClass;4 A& r. E/ [3 U
9 E! h' T4 s6 ~" [' [ u7 ]8 k& o' }
static PARTITION memSysPartition;5 l0 E2 Q: S& R) K# p- ]! W$ m
PART_ID memSysPartId = &memSysPartition;8 K V2 R. V: k. P% t) M( q
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
# f/ T1 e9 H% T( Z1 Q( e$ ~6 S1 y4 L& F2 q5 d5 @, y
static SEMAPHORE semMemSysPartition;
. M& B9 R+ a* Y8 T6 X: f9 @5 l2 |. u5 o7 ]) ^( G
static void memPartSemInit(PART_ID partId);6 r7 a; J" r% V7 o. @& {
( ?: Q& k4 W, {% l7 `7 `9 D" N7 t7 a3 a
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
% Z. b# L$ q$ X% }$ I, A% C5 ~/ p# h7 x! G: j7 W; y
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;/ M) u6 {2 F& d( d4 H* P! \
$ M( ^! m, }& X+ j zstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
( Q. ^+ D: p8 W0 {5 Cstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId8 A9 C- A' U1 d0 X( z/ M, y+ b
, FAST BLOCK_HDR* pHdr% T0 b/ J, B4 g+ D8 s
, FAST unsigned nWords
' E) y( O g% t$ p7 \% [ , unsigned minWords! |+ h/ ]2 l- L" q
, unsigned align);6 F& F# m1 D6 ?5 D: o9 ]# E
) H$ K' G$ Q% n; i. b6 q4 xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);1 N8 O& B. N) e4 N8 o& h! M
. E" j9 n; L! a6 r; A8 RSTATUS memPartLibInit(char* pPool, unsigned poolSize)3 n2 z3 c3 `) W* g* c f$ \8 @
{
3 p- h) H e- u( b0 M& N if((!memPartLibInstalled) &&
( S( P# ~7 q1 H3 V- V: d& G (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
7 b, p- l4 Y: ], p* u$ D- S2 R T , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))' _' q7 t0 E1 A3 D n7 O
{* m7 W6 i6 y7 q
memPartInit(&memSysPartition, pPool, poolSize);
4 v3 x, d9 M4 h$ R/ F8 h memPartLibInstalled = TRUE;" g( ^4 c* C2 Z, S: I
}
% h# n2 U4 B+ H5 t/ P
* q: I, T1 e) @+ s2 D9 ~7 w7 q- n return ((memPartLibInstalled)? OK : ERROR);
c+ L+ I. c+ K ?& |% ~1 I) A, A}
" A a+ o5 ?! n
4 z( L F& I' v: T1 h# V. ^PART_ID memPartCreate(char* pPool, unsigned poolSize)
0 l- c$ z6 X8 V3 {: z0 g{7 p5 v4 V7 x) V6 P9 g) e$ `
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);1 H2 h, w/ Y s7 s" r
3 g8 ?# m2 P; l( f$ _
if(NULL != pPart)8 L1 S9 S f2 ]: ]. r6 _( n/ |
{
4 n) o% d6 U5 k( V memPartInit(pPart, pPool, poolSize);
' _* ?- O' e; S/ k0 e3 s1 x* U }* O3 w& T8 C, @+ S
6 E4 r# m1 H8 K; j0 P9 ] return pPart;- A, C/ }6 e5 M' q5 R
}
+ s+ B( F8 ?( h) n
, c+ q6 p' z. X- hvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)7 g3 p+ j; C& `6 l( J- `; [
{. r, y0 w/ n* g5 l0 u
memset((void*)partId, 0, sizeof(*partId));& g2 T) l# e% j) W% p3 \0 ~
( P \. r8 P( q- o7 M. d$ B0 d
partId->options = memPartDefaultOption;
& k1 G1 M* r9 C partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */; i2 w: N8 n) b/ w3 d
% z3 X1 v- u5 l" p
(* memPartSemInitRtn) (partId);
4 X$ s/ U9 I8 ]4 I6 a" P% Z
3 {* A5 x) H3 i* W5 s dllInit(&partId->freeList);8 G$ R. [% E9 l5 _% S: T( @4 a
/ b" C# I, c2 [8 l4 W3 M objCoreInit(&partId->objCore, memPartClassId);
0 ?: I' a' b7 g+ n
7 e* L3 r \' U7 H, t0 D8 e- I2 a memPartAddToPool(partId, pPool, poolSize);# u3 l$ b( Y6 ~$ G$ J0 y* F O
}/ K9 q; S1 F6 a4 f$ V7 T, f
& Z1 M$ R- u3 T( T B8 k! n
STATUS memPartDestroy(PART_ID partId)
. {7 ?) Q$ M2 D5 x0 l; o1 _- t{
9 a; r+ \0 k4 d& i return (ERROR);
4 @: d2 l$ M/ _6 S' F* J/ N/ r} K" u! \: v) _9 z+ m) x4 V
6 {0 b* S% R1 X
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
) }8 k1 Y3 z5 W S `{
# O2 s" }1 @* c A' t3 y (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
" R1 n& J$ g* x* y}! U z% Z: Y/ m
) T+ ~% v1 J l* `
+ h& o1 X7 @* {) Astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
( s: A# Z- y \! ?{
+ Q1 P: h( I W5 T4 T BLOCK_HDR* pHdrStart;
3 i& O; B! v7 ^% L1 p; S1 V BLOCK_HDR* pHdrMid;" s6 p% `) f( w
BLOCK_HDR* pHdrEnd;/ d( r/ _: _/ |* b; |! M
char* tmp;
8 C% g! d- m, V0 p8 n( c int reducePool;/ s" U8 i! Q5 X
6 r( e M0 ^0 z2 }" S6 b! S- l- L
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */- S- F3 b- Z! i$ ^9 ^
{
6 ?% D4 X4 W$ ]0 F# r/ X) W" G! z return (ERROR);
. b5 U0 D4 f" Z& I0 C }; O. Z8 X" \& g- Y: s+ s0 C
% Q- i6 g0 a# q. Y8 J t
tmp = (char*) MEM_ROUND_UP(pPool);
]& g: a D7 P/ S3 B# V reducePool = tmp - pPool;5 l, J0 E3 i- Y- C
6 i! ^8 m4 k& P0 K7 w, M
/* adjust the lenght *// U) v8 x' X% h! d# l2 A
if(poolSize >= reducePool)
! A0 B8 Y/ C3 l+ d" M& T8 ~* c5 ? {% ?6 U0 p) `. v, Z- F3 p
poolSize -= reducePool;
3 _6 a& \2 I" V' H- X# ?- t }
2 H' U$ ~: ]7 x- N2 y* [% O) t, N, y else& p: F" z3 h: j6 h9 E
{
6 Z# d x8 x7 x1 e! p6 g5 S1 T- U poolSize = 0;
/ P9 B; `3 ?* |; ` }
- m0 U( j" d6 L0 i+ o pPool = tmp;; G" c2 I* N8 y k5 y+ u
- m- j% T- B' Y, p1 d1 v! I poolSize = MEM_ROUND_DOWN(poolSize);
( Y, b; A, e/ g5 T$ U+ v/ M - w/ ~5 A6 S/ f
/* at least one valid free block and three header blocks */( k5 F+ z: a! _- q
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
6 J6 n6 P! ]) c4 L. ^5 K { ~# x6 A4 \( r/ L7 L
return (ERROR);& N& V( t. ?* B9 C! Q- o
}
: A# f, W' @ c0 u" I5 G [- l* x" E8 t
- a" P2 }5 s9 j$ y+ Y /* initialize three blocks */2 Y. [8 ^) K2 r$ o1 Z! b$ M- F8 w
pHdrStart = (BLOCK_HDR*)pPool;
" c" ~3 J+ u' n2 ?2 r: T pHdrStart->prevHdr = NULL;
; h, j7 R+ m+ w pHdrStart->free = FALSE; /* never in use */
* L4 Q, \9 f" y3 y- K {- u2 q, u pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;" i& H) ?% s, f" a: N7 }& Y2 y& A
2 U$ `( x( D: [
pHdrMid = NEXT_HDR(pHdrStart);
$ `( d( R4 k) ? pHdrMid->prevHdr = pHdrStart;
. j2 j( }9 v$ b: m pHdrMid->free = TRUE; /* the main block */2 Z5 R, ?! p4 p! K
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;2 @ }. i& j {, b: G; r6 L
: A! W% R3 t/ [' u% q& |
pHdrEnd = NEXT_HDR(pHdrMid);( T6 \4 A" s, h1 ^& M' }6 s
pHdrEnd->prevHdr = pHdrMid;5 u1 ?9 y. ~- U$ l; I6 y: ^
pHdrEnd->free = FALSE;
9 z1 B: }1 o! D' k: f% F* P pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
, c. B; O5 N! h) P! N- D
& j* a8 q7 a! W, o0 J6 ^, M /* TODO take sem hear */
; t- T: r2 ?4 {; L( B semTake(partId->semPartId, WAIT_FOREVER);
, t: e. g2 H! W4 e" h 0 t! g* W ~- x6 S' Z
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid)); F. ]( h$ f) s! y" p s
partId->totalWords += (poolSize >> 1);
# w3 }" w" r, l8 D0 D: j1 d/ ?+ r2 }1 O0 b! m
/* TODO give sem hear */
& ~) a H: L# k3 Q" G3 u/ E" Z5 J9 |$ N semGive(partId->semPartId);% M' j; ?7 U2 D& g6 t7 t$ A3 M5 z
2 P0 [2 t$ G: S2 o' A
' @( ?) b# @! I9 n( ]- R- X( b4 _ return (OK);$ ?$ P& P+ s1 X. v
}
9 J" \" h ~) B6 S& c' ^( _ H' e/ _
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
& t9 j; j0 {! L c{
4 b( M* g8 ]/ @4 \# B. A: ] FAST unsigned nWords;2 E' q2 i: w1 E# I/ H
FAST unsigned nWordsExtra;: P+ T. ?) K1 J# Y. `) O
FAST DL_NODE* pNode;# J5 l/ Z) a( h/ A) q% v: ~
FAST BLOCK_HDR* pHdr;
( s0 u# Z( j/ N0 D BLOCK_HDR* pNewHdr;. f" t' s( [ p k. N
BLOCK_HDR* origpHdr;
2 ?: W* }. s% [- w) }7 Q
+ Q' {+ a+ G4 C" U/ ~4 V if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
: d5 [1 s1 A2 J+ S9 A7 X' ~ {* r/ O( o( h1 I8 w9 ~* E
return (NULL); I# |0 \* H7 {* M/ G) x
}- n% z1 ` S6 v3 x
# ~! U1 e* m* t o' B9 }) C8 z" p
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;9 m$ q! g5 u. K: B; G( T
2 ^0 s/ P4 ?) y. p% w0 o( V if((nWords<<1) < nBytes)4 l% _5 S# ~5 A3 Y& B
{" @" j: b! |* M; u) E
/* TODO suspend the task */
2 j+ F4 M+ J( q' v& m- e, k return (NULL);1 }( P$ b+ f% ^( ?' j2 ?& A" B4 w
}
/ o9 V' G6 M! I) m2 y) z( z- ]) z# T& h! y6 n9 R" b5 _" b
if(nWords < partId->minBlockWords)
) j0 f3 V& ^' F% \( n* h. T {
5 n6 _. F7 C9 F1 C# T! T nWords = partId->minBlockWords;
4 e* ?" s. v1 G! y+ Q/ m2 G; J! V }$ \2 T& W* ^2 q; X' U! T# P8 d
7 ^3 [3 S% B. o6 o
/* TODO task the semaphore hear */
x) |- T+ D% K' ]" j& n! G semTake(partId->semPartId, WAIT_FOREVER);
; X+ T# `- f2 Q* c pNode = DLL_FIRST(&partId->freeList);
) X+ q, C4 f C1 ]' x1 _ nWordsExtra = nWords + align/2; /* why? */
! r8 s& z& w3 y& Z1 g* K9 S& O2 d/ d; V# z4 H
for(;;)
0 |! x9 @# @, Z: a) ? {9 @% ^8 M/ C+ Q) h4 J! a! Z0 a S
while(NULL != pNode), T5 X8 }; ]* {! k. r7 ]
{
, _% _+ F9 q( z if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
* z4 D# y( L' x' D9 N# v ((NODE_TO_HDR(pNode)->nWords == nWords) && 7 ^. r7 c, r7 A
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
. p0 t j% {7 @ {
4 Z( J9 m/ B; I F: D break;
! f/ k$ z# [8 ~7 T }. g* p5 h1 A \$ e) j
& g( x( j2 |' U0 I! }, \9 P* [, C pNode = DLL_NEXT(pNode);& D: c$ T2 {8 @& W
} y( z# B* x- Q- [" K" o% n# _
; Q* P. s( ~% P$ `8 t& F7 S
if(NULL == pNode)! G$ h/ G# i; B/ @) I- L7 ? k
{9 q: @4 S& I8 {2 O. M" X `' W
/*TODO give the semaphore */0 O% r5 U; H/ P/ J4 Q; `8 p& q
semGive(partId->semPartId);
9 K5 X/ h0 L4 ^ `$ O0 z return NULL;0 S+ }+ \$ }; m# O5 J: F5 X$ q
}
& j4 w5 H& b+ |# x. x
5 H& j+ Z, m) H5 B1 e9 |: m pHdr = NODE_TO_HDR(pNode);' U8 j. ~3 j7 j6 ]3 m
origpHdr = pHdr;/ Y9 L; D/ \) O1 l) Z
. ?0 ^ T* k7 U pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
/ |. R6 f2 p. i+ e" n- `( ]% A( | if(NULL != pNewHdr), F6 T- @" L$ `# Y8 l% |% u* e
{5 r& h* q: F9 W( y
pHdr = pNewHdr;
+ v2 ]+ f6 _5 [ break;
4 H/ g3 P6 J' U }
( L6 _$ \8 R0 N( D* L1 m2 D3 H$ J2 Z S& d! h1 D) j
pNode = DLL_NEXT(pNode);
2 A& w" k2 W, s% _4 H: Q1 Z } U0 X1 a2 x: a5 a1 |3 S
) D. k; K" [( V1 b2 c
pHdr->free = FALSE;" [# [' {$ S' _" M) _6 p8 c
partId->allBlocksAlloc++;7 M* I3 H2 p% g% e; C' H
partId->allWordsAlloc += pHdr->nWords;
5 ^) `: E& L7 |2 f, }( Z partId->curBlocksAlloc++;; u2 _" p, M) R0 S
partId->curWordsAlloc += pHdr->nWords;. V# [( d$ {2 `5 o3 A2 _7 t
3 `3 [( V2 d" B9 k" @. A: y /*TODO give the semaphore hear */, q, S/ W0 c0 I9 x1 B. }
semGive(partId->semPartId);2 d; {) f0 V! T9 e/ B# t# f
return (HDR_TO_BLOCK(pHdr));
6 u& Y2 |) ?+ }# o0 }, D
( u, D5 c3 V% `7 }}
9 u/ s+ D& }/ N) R8 v, V
. p0 a" N1 c9 \0 M8 U. @ A' ovoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)2 w3 |; \6 b/ B/ a8 A3 A$ A% H
{
* }: q0 a* a1 C& }( B return memPartAllignedAlloc(partId, bytes, memDefaultAlign);# d( t" T, _2 ]
}2 X* { y9 F# A+ t$ v
3 m* w9 n7 N e3 ?
STATUS memPartFree(PART_ID partId, char* pBlock)
( a+ v0 A% Z. H% }0 i{. n- E# H9 s8 F$ s# N( c1 H
FAST BLOCK_HDR *pHdr;, p9 P8 M' o; [: m% Z
FAST unsigned nWords;
( K) c, K, h4 x# r3 ]; } n. F4 W FAST BLOCK_HDR *pNextHdr;4 X' ^7 {, m% ^) i% O( k0 D8 [
. w. w8 Y5 ]" S6 O: N# P3 r if(!IS_CLASS(partId, memPartClassId)), ?: U# O) ?$ Q! E" x! v
{
3 }' g$ K/ R& s# h; m return (ERROR);
) Y" O2 [8 G' P m5 q& w! c }1 b( G. [( [3 S: M1 C6 h7 n4 y2 Q
% m$ M9 f8 `: L6 o4 U
if(NULL == pBlock)( a; E- G: q* W. p# Q; i" f
{
! \0 s/ o- n& _2 v3 ^ return (OK);0 a4 f3 L7 P1 h2 N% e* [
}
! P1 K5 s7 k5 J, H8 o' Z( ~) k& b5 `3 D! F- p
pHdr = BLOCK_TO_HDR(pBlock);
* _/ Q [& `1 g1 C T
$ s, N4 R k* p4 Z/ S6 @1 o semTake(partId->semPartId, WAIT_FOREVER);
) B/ m: V* K6 F; e/ q
. b! e8 w% j; @9 y! o if((partId->options & MEM_BLOCK_CHECK)- {4 A$ b7 N& V4 m
&& !memPartBlockIsValid(partId, pHdr, FALSE))4 c k- `! ^ n. C
{
; y% y0 n4 q+ W& ^2 R, @6 B" V semGive(partId->semPartId);$ ^# h h. O2 o9 J
return (ERROR);
: V. K D% L: p }0 C- ?$ y$ M2 Q) H4 E. I4 ?
3 f" n C) b: y; {4 l h
nWords = pHdr->nWords;
+ n' A# h+ m. d* O3 I$ x if(PREV_HDR(pHdr)->free)
, m" c% u8 C5 ] {/* the prev hdr is free and than coalesce with it */
7 y# c4 A$ ]3 i$ I: \9 A& R3 S pHdr->free = FALSE;' e" _9 n% c- w' C" Y
pHdr = PREV_HDR(pHdr);
. t$ m2 [9 d6 \9 a% d( Z* H$ ? pHdr->nWords += nWords;' O( B4 D* K1 l: s7 F' E
}% f( R* v, w( b7 E' Y
else
/ u0 A' M: {1 {% }( {; [+ ] {2 I# n4 w! t* e# Y# }1 Z
pHdr->free = TRUE;
0 S& l7 r% t( T( t dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
# v5 K. v6 Z' q }
2 Y2 a3 N* t2 x8 ]
0 b, i- a: j2 ^3 l! Z: Q /* check to coalesce with the next */
/ { B+ A9 U1 i1 H8 |! t+ x pNextHdr = NEXT_HDR(pHdr);" r0 o2 @: U- l0 i* S) Z* D
if(pNextHdr->free)) R. M9 W' e% x8 e' u
{3 ], A k/ A6 @" }5 ~1 ]) ?. X
pHdr->nWords += pNextHdr->nWords;
" d, K! ~5 S, P0 I$ D# m dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
$ ]' w- Q/ c( O$ X/ S9 G6 A }5 [8 ^9 c2 z) @3 K/ n3 g5 k
3 T5 V* X' _/ A; D1 D* f
/* cannot use pNextHdr->prevHdr=pHdr hear */
+ g% v# A0 H( |' z: P! I- k NEXT_HDR(pHdr)->prevHdr = pHdr;
' R2 y' j6 [- N# H) h, d! h$ W' g& H( c+ p# k j$ J
partId->curBlocksAlloc--;% `+ G3 h! S6 u2 h2 E+ g
partId->curWordsAlloc -= nWords;3 k: P% N5 d5 V
8 `7 J/ x9 M+ F8 T3 M: L/ H1 Y
/* TODO give sem hear */+ {2 b7 Q+ a$ J( @
semGive(partId->semPartId);
. l3 R( q1 {1 x4 y
: g1 {9 Z# {% g6 ~* f9 ` return (OK);4 T+ O& y0 P0 s/ Q ]0 [
}
f2 c+ K/ l; c9 A; F
% u4 I9 K* e3 Q: H7 v5 h; Gstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)" k" Y3 ]1 s& ?" r+ H+ c( b2 ~
{8 o3 \1 c8 F# @5 i" g& \; D ~
BOOL valid;# I A* u8 ~7 D0 r
1 v' _9 s6 j* O9 P$ L" z1 t
TASK_LOCK();
" \, c* d6 W! `( s+ X semGive(partId->semPartId);
' z% |' {8 z/ ] K+ N
& M; p: B+ M4 |1 |& a valid = MEM_ALIGNED(pHdr): L- v, H3 C& q
&& MEM_ALIGNED(pHdr->nWords*2)
5 K% T# O& P" Q3 h && (pHdr->nWords < partId->totalWords)
4 x' U" z3 C; w) C5 g% @" |9 f7 a" E && (pHdr->free == isFree)6 ^) ]/ x# T6 W- t, h" C1 s
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
( I2 `4 R" n9 x5 n% r && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
* i$ {) ]6 j- P* ]# n9 t
; j; g5 P: {2 l! a- f2 O0 G semTake(partId->semPartId, WAIT_FOREVER);
2 K$ h$ B, I( i TASK_UNLOCK();
& }( O5 y& W# O: l k% H0 m" A
; |" G/ K1 I) i) f4 d5 j" Q. q' I return valid;
- J+ S: Y! E6 ?- s}
9 l% O D( X# E& g1 ^2 ?% n/ v6 ~: t# Q6 F- x
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
: B& w% z0 B1 B" |0 O# \; H# e$ x , FAST BLOCK_HDR* pHdr/ ]' g& C7 y; ~7 A7 o
, FAST unsigned nWords, n) @% K4 a l q
, unsigned minWords$ L( G! P( V2 u1 j* X! g2 w5 y* s
, unsigned align)
$ B) r+ q! e }% v- `, K* [: ]{, [# f; B, a# v& A+ x0 N" T' K1 {! P; \5 E
FAST BLOCK_HDR *pNewHdr;$ N/ D8 w. M* T4 e
FAST BLOCK_HDR *pNextHdr;
8 p8 i* r1 H, c% @7 h FAST char *endOfBlock;
6 [7 m& o1 K7 O7 l( S FAST char *pNewBlock;( }& {# q" s9 n+ D' ?0 j; G
int blockSize;
% j2 C5 W& n; y) a+ O& _& T0 b- ]: R; R+ |8 y+ t$ k8 f1 h
endOfBlock = (char*)pHdr + (pHdr->nWords*2);
$ P8 a$ j- b0 b3 l# S2 G1 a1 i7 h( [4 m
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
/ h v2 R6 L# e% s$ w
# j$ }# {. M/ @! B pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));: ~- z$ K( I. z/ y2 h9 q2 P- j
6 ]. k4 Z: ~6 A3 z pNewHdr = BLOCK_TO_HDR(pNewBlock);7 M8 h- ~' a( d6 u$ p+ S
: r' ?& Y6 v( a blockSize = ((char*)pNewHdr - (char*)pHdr)/2;4 G$ z v9 |9 T, O' r v" d) x! b
5 D) G- c6 D* ^5 @
if(blockSize < minWords)& G' u# a! l7 r
{
8 g2 n( Z: ?+ g* y3 H& U0 {+ R if(pNewHdr == pHdr)
, b; F! s: B2 K- }2 }( F5 ^ {
2 A) d5 O. v/ ?, g" Q dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
; `3 D2 d& _- b }9 h7 o1 b! l8 s5 o0 N
else
; r9 } X* N# j6 d" R {
% z4 R8 l) G; d0 I( a( a return NULL;4 f3 H8 i( ^# u
}2 t4 g* a( K4 S
}7 A$ x; q+ @. b( x
else
! U) ], S( T! O' v t { /* recaculate pHdr */% O6 H6 @' h9 ^' x# }7 _+ B
pNewHdr->prevHdr = pHdr;* ~4 ?: D9 q6 b( S
pHdr->nWords = blockSize;1 J* v. J) R j6 f, b
}
/ i8 O+ F* a9 }0 E1 _7 ]7 ^1 {0 y) i6 q* `3 F; ~; M( R: h" r0 x
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
* J% O) w: v8 m* K, B# p {& O# i; \0 v0 L' b5 X
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;5 e' w! O6 R8 W2 @) Z
pNewHdr->free = TRUE;7 K' t& L% l5 z5 d! ~
& e7 B7 F& C' Y% a* U' |
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
0 u4 |8 @# X8 G) Y- t. ^ }" K9 r/ B2 E8 M& |4 O6 f; u
else
- D2 `: G `" w {/* space left is enough to be a fragment on the free list then */- K; r M+ V8 \& F4 a4 \0 A
pNewHdr->nWords = nWords;! b! s+ o, l8 D: O8 B: b. X2 F0 n
pNewHdr->free = TRUE;1 v2 w- A- L7 g' J7 K
2 l' z+ o) F* |2 N" a; i. F pNextHdr = NEXT_HDR(pNewHdr);$ @. d/ r$ w. z: |
/* words 包括BlockHdr */
/ q# G5 M6 o0 Q/ j$ m8 C9 ^ pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;# B$ O3 W( O7 j9 {" S
pNextHdr->prevHdr = pNewHdr;
* w5 ?8 k/ W, G Y, ? pNextHdr->free = TRUE;
2 P- i" s2 m5 J8 m W( O! J9 }6 Z
1 @, E$ Y9 O. ]2 V/ L dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
1 Z; W! @! U7 P# J0 K& g" k' k7 c* A( s1 g6 r
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;8 r# S o- E& X
}4 ~+ ?. t, i. {
) T! O C, i2 O: i return (pNewHdr);, `! p- }/ b8 C% _
}3 e, v" s3 Q1 X& L" l$ k5 l
$ U2 e) C; g+ _4 b' u
static void memPartSemInit(PART_ID partId)
" Y6 x* G, S2 k$ `% U7 o/ n{2 ~; T9 B9 W( C2 b: S
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
8 p2 }6 Q- ?) s. f) J2 m1 f8 H& t) N$ d* E8 p, P0 S
partId->semPartId = &semMemSysPartition;
6 j, O" r+ J6 I7 v; Q" p}
; S, H+ N. ]1 @" t. k& P6 Z8 |+ i' Z. [1 }0 e! ]( F
void* malloc(unsigned bytes)
% M6 Y2 c& `: f* e1 R: D* \: |+ Y{
- M$ J. \5 K. k5 E% K4 R return memPartAlloc(memSysPartId, bytes);
) E6 }" c" H3 L}' m+ n: Z( a& u
" A+ G% F9 z v0 A4 q' t3 Z# Lvoid free(void* p)
. c* P# |4 L @/ L$ M{, l& ^- c2 q1 m5 V. Z4 l. a
memPartFree(memSysPartId, (char*)p);
" ^9 o- I0 [4 m. k+ B. R}
8 P7 G+ d7 H& S9 E- r8 f |
zan
|