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