- 在线时间
- 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++下的版本,更方便调试。有需要请留言 4 t$ @4 {1 h1 M* N
9 M5 B6 Z4 H- I! M% p! Q7 x& z. d; d3 d- }, N+ l" x" F0 E
) d" b* N2 g) W; ]; j; _ *\file
1 E0 c! { k/ V$ O! t4 m) [ *\brief
$ a* E& R! M! G7 M6 v *\details
; k% h( X x) X6 s+ J6 r9 B *% v$ Y* p; `4 T' }1 `4 u! R- {2 U. e
*\author Janson' z) S2 `6 A. I% L0 i
*\version
2 b& t7 k: n% g *\date 04Jan12: |7 ~, Z% r4 A7 M
*! T. A1 N6 N7 Q+ v ^1 G
*\warning / o+ G/ e3 x: f5 _
*' i* C/ L ]0 c+ a' b: q/ k
*\history \arg 30Jan12, Janson, Create the file0 l O' l! Z# ]; D0 e/ ^$ |% c
* modify from VxWorks source8 S, q. q6 T- `9 r4 Z0 A1 h9 r- Y& v
* Legal Declaration: it is for studying VxWorks only.
( Z$ E, E# I0 o5 x. q8 W* S */
4 G- P: ?8 |/ ~#include "includes.h") e z/ Z$ B, z D
- H' s& N# |( P- ]
/* The memParLib.h file is hear:' v8 g: M! ^! t/ Y, ~5 ~
https://code.google.com/p/vxwork ... rivate/memPartLib.h2 m, L$ q8 G7 `* n) W7 E' T
*/5 [* R- b) [* a/ t
3 _* S, j9 X k( h5 m% W
/* optional check for bad blocks */
" f( W. X9 O2 c) S2 m" h* N4 r* ]/ a- X
#define MEM_BLOCK_CHECK 0x10, G% ~. g+ X0 a5 `9 T) s# R
! ^( A; O, k9 t: M
/* response to errors when allocating memory */. N" c( K/ c/ w. L$ ~, M
# u& n# }- ]$ l$ F5 G: p' N
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20' k1 g# }2 Z( z' F& K$ S
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x407 f; p4 R( r" N+ ^/ G
D. c$ K2 X3 U5 m& e" _/* response to errors when freeing memory */
+ d. G0 D' F% U% i* ~& v& p$ ]" \' d) v$ s. F5 x( O
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
- q! `5 O7 b) f% Q#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
% ]. S4 h9 Y& t3 c8 X, d1 r- K- Z, v0 a7 s, c. `8 z* y
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
, n: I7 r" f' n6 }#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
7 z9 r) T' g# K5 q6 q3 D Y$ E- A! O& q3 A0 y- N
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
. M/ t: A- ]" a& {* A) N#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
8 {8 s7 u4 k6 h- c! O sizeof(BLOCK_HDR))) g( K& c2 s6 ?
% S. A4 o: u+ h* k# [/ i5 _#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
; m- T8 N% W' A1 b, h#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \* T' `* l; `8 H; y$ ^8 @( [: K
OFFSET (FREE_BLOCK, node)))
% O$ q; ~4 k9 y# l9 `2 M( A3 H2 ?/ O" i0 }% t& r" l8 _/ v. K
static BOOL memPartLibInstalled = FALSE;% p. R. {6 I w" z1 i2 B/ u
9 W5 j6 P' O) _, ]static OBJ_CLASS memPartClass;, t6 Q% T0 V7 q2 [6 H
CLASS_ID memPartClassId = &memPartClass;
7 J/ B% }% b1 Y, a
3 F: H- `( h& W6 u8 H" p; T9 ]static PARTITION memSysPartition;
, A. O5 _) ]" M1 NPART_ID memSysPartId = &memSysPartition;" ~$ v9 _0 C! e+ e# D+ e3 O
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;8 }0 z8 X" I. A* B2 J; ]) G; O5 @
0 r! V3 h% D& L' u: S% W* l/ L: N
static SEMAPHORE semMemSysPartition;4 o; [( Y$ J2 {" Q9 w0 h
, R% n1 T0 I# l) u1 i" i/ }static void memPartSemInit(PART_ID partId);4 l0 _; Q9 S! E0 B2 y4 M
& m" n7 j' p" x# z
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
3 P$ b& A, p* {
0 u# a2 s) z* X. o0 @! Iunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
$ A' n( }! X( H$ ^( F+ s
8 H9 R# X1 h4 m0 W9 k7 M7 s* Istatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
. b: M$ Z4 O( S \, Y/ R3 Y9 D" \static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
+ H' r' f1 Z: D; b , FAST BLOCK_HDR* pHdr
7 v( l1 o! r" |, F" R- I' O , FAST unsigned nWords9 L% B6 w; O; b2 |4 I
, unsigned minWords% x0 l0 N$ j9 T5 _+ a& j/ z R' J' V
, unsigned align);
6 x" z# |! A& j, J7 W- X$ {
; ]- n7 ]9 N1 k- l8 l) n, H- vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);# Y; b: {$ F! ]4 i3 T
5 H/ {! v6 A9 A! F
STATUS memPartLibInit(char* pPool, unsigned poolSize)/ b' J3 n/ Y) N; Z+ t
{0 H+ ?; q9 o- M( `7 s( {
if((!memPartLibInstalled) && 6 T: R" h3 @2 A- q: O
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)* ?& c7 x; i8 d8 _5 w7 R6 @
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
: T7 U6 l5 P9 ?9 [# i/ S {8 \" U( k% @$ H" h
memPartInit(&memSysPartition, pPool, poolSize);- j/ E! ^ E8 R. l% U( M
memPartLibInstalled = TRUE;0 S8 s0 F, `+ o& q3 ^7 ~1 M
}
3 Y; b/ L8 b; b7 Y% f: k+ Y" O9 Z0 U# F$ t+ b$ V
return ((memPartLibInstalled)? OK : ERROR);0 J+ `0 }, j8 @
}
* |* C7 v2 \* ~* [8 V" ~
- R; j O: ^' `' \PART_ID memPartCreate(char* pPool, unsigned poolSize)
- s$ H! E+ k. G b! }, N{
$ K/ O) J. Z, L1 f, C3 B7 D PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
5 }3 n; R9 V- Y8 ~+ w3 S* B) o9 H! Q8 X" h- d8 [
if(NULL != pPart)
u1 F0 t% R3 p! \* x" e7 u { q/ G/ | H6 I4 J& K
memPartInit(pPart, pPool, poolSize);. f: t: k5 P! I' V' _4 G4 D" M
}# B2 \$ X6 K6 M% c- c8 r
; ^, k& v/ {5 }6 c
return pPart;
5 X; \* N: n; u5 b* b/ N! G! k}
# d2 ^$ f( t, c) _' Q7 I" o0 D8 T
, e9 c! [& L X2 E; o pvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
$ y6 g: P( z! S- l{9 K7 O+ S2 w% _% Z2 Y h) \
memset((void*)partId, 0, sizeof(*partId));
; M0 W9 U3 |. R7 c8 D7 Q4 m1 i4 C
partId->options = memPartDefaultOption;
) T2 q1 x. G( G n partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */
: ~3 w5 o* d( Y1 d8 h8 {+ ]% K$ |7 |, z8 x! O8 K c3 {. u
(* memPartSemInitRtn) (partId);$ @3 D( K6 ^ P/ ~8 m! F
1 x& k* v( T" W, {$ R* U dllInit(&partId->freeList);
. m# z* `$ Z' g% x$ } $ f% E! ]# @; ^6 |
objCoreInit(&partId->objCore, memPartClassId);( b. ]/ G* P4 a8 W- ?
+ Y: S6 j3 C. d& c
memPartAddToPool(partId, pPool, poolSize);
5 i3 E, o4 z* K# ?, W}
- r+ c& S% P+ C& Y4 H q
% |/ u0 o# ?3 K; t, \% _1 t* ZSTATUS memPartDestroy(PART_ID partId)! f& r8 e+ @, ?, ?8 [7 z
{7 n O% @3 r, O% A. H4 b& D! N: T
return (ERROR);8 l( \: x) v) H
}$ t6 T* w5 j7 }5 W8 g
4 C/ Z$ u! R0 \void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
9 @8 P' |# Z5 Q% W4 o q" {# W{
% V- M) \6 T5 U (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
- u E( W) j9 [4 h}
0 S+ R/ F. X1 i3 j) K4 G7 L" `" J+ H) L( a' v3 D+ G- t( `
3 y3 ^9 L7 \3 A' B( ^' x6 astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize): r" [8 m/ ~" k& O+ Q' E3 v
{
# L! J- C/ A% X0 [; s BLOCK_HDR* pHdrStart;( L% z8 K# ?6 F
BLOCK_HDR* pHdrMid;
J5 G, ~' N" ^+ ]4 g BLOCK_HDR* pHdrEnd;
; ^2 o: G: }6 {/ p char* tmp;4 A7 g! i* V" E
int reducePool;. a G* N S% A y
9 c3 I* b u0 O$ b if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
6 C1 k/ S- R' p: Y' v1 f { q& |' V8 q- p& t" w" V, z4 H7 T
return (ERROR);
9 j, G" a( F9 C, w* H! ^7 c }" w: [' l) v9 u/ [, k
1 ]8 K% O0 R1 v% b/ ]1 k! L7 g2 ` tmp = (char*) MEM_ROUND_UP(pPool);8 Y& i2 N7 x9 `1 q
reducePool = tmp - pPool;
" L: I: p* u$ I& E d' D( Z$ \
3 E5 G Z, b% c3 L /* adjust the lenght */
: ?4 y5 w! a4 B% ] if(poolSize >= reducePool): z7 g/ O/ Q, M. l" g6 P
{3 o1 S: I% N% q* P( n. `$ r
poolSize -= reducePool;
9 G0 R5 U1 W5 Z5 Z: r8 }6 u }4 _5 `5 U4 `" s2 b: T: |
else
, N7 X/ Z/ Y6 D2 E+ L, E+ g {% z' J$ q2 S5 O) Z; S( ?
poolSize = 0;
, p2 C* `4 `7 z6 p }" I# H. a' ?5 f+ `1 X% Y
pPool = tmp;
6 Z; K! q& l" x" X% s% X b% B % b7 m: T$ v2 P. [. P' p5 O/ T$ z
poolSize = MEM_ROUND_DOWN(poolSize);. r' o- T1 {" a2 n1 q2 C
: a; [1 B& M' h+ w2 P /* at least one valid free block and three header blocks */
* d; O8 v. X6 p" E$ ? K# E if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
; S; V& H! d% w5 o2 m, U { p- v* f; m3 H5 i
return (ERROR);& \% ?! I9 }' X: e/ x7 e+ A* }" j; c
}
0 s7 O/ Q3 v2 D6 E/ b" e9 S: `2 [
# _1 z9 p, R: L& n/ B6 R7 ~. v /* initialize three blocks */
5 {" v* W5 e. `% M2 ?; v! U$ N' d pHdrStart = (BLOCK_HDR*)pPool;
2 C) [ K" t% O: c5 B { pHdrStart->prevHdr = NULL;# l8 z0 P7 W H5 q0 ^
pHdrStart->free = FALSE; /* never in use */) h0 j4 t5 J0 _+ C3 d7 }6 x* I( i0 o
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;' A6 K9 H) @4 g {$ }. O, _
$ M% D! t' O r' k! c6 A/ [; {
pHdrMid = NEXT_HDR(pHdrStart);
# v0 G6 E2 I, A4 Z4 ]. Z) z; h' B pHdrMid->prevHdr = pHdrStart;0 C* e, T0 X- |) }' B1 j4 a# w$ `
pHdrMid->free = TRUE; /* the main block */" ^3 _# D$ Y# F6 I% g+ \3 I
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
# H2 y; s( v$ b" L, I
$ {# Z1 f: ]- a# p" z3 Q4 z7 O pHdrEnd = NEXT_HDR(pHdrMid);
8 C3 }( j8 ~8 M" ]$ q ^ pHdrEnd->prevHdr = pHdrMid;
; v/ ]7 l4 r( F+ Q P+ w5 O5 H pHdrEnd->free = FALSE;7 C7 P) j$ \6 p* E+ V
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;2 m; i, _- q. |2 P9 }8 P$ T
4 W) F0 b5 D- B4 k& Z. N
/* TODO take sem hear */% j: a2 B4 @) [& S6 P P! a
semTake(partId->semPartId, WAIT_FOREVER);/ t* o9 A( I+ Q) ]# O+ V/ p t; d
/ u( ?0 K! y r6 K
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
7 e: h0 K3 U/ [ partId->totalWords += (poolSize >> 1);5 ?# ^) ^: t V: H( Q+ ]. c
" p/ z, A/ Y5 B; _% I3 C6 l /* TODO give sem hear */
- p. g' m% p( [8 e' C# Y semGive(partId->semPartId);- F& l& K4 s6 p. |2 s
: d5 t) S9 z4 F' z
2 s& B7 t, a0 I T1 U f' L, `. s' Z return (OK);
* k R" G. ?. @# M% C}+ J5 f4 K& S8 L% l; m
! X. \1 }; d$ L. v1 c. G& A
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
! a. t1 C$ k7 K+ h' G- u! z{
/ {$ r6 x. q2 V" o+ s FAST unsigned nWords;7 I0 H, o) E4 @6 E
FAST unsigned nWordsExtra;
' h6 G$ b* i+ h$ y; y% S5 k3 i- g FAST DL_NODE* pNode;
/ D& u% p8 l# E% R8 B& J9 n9 [ FAST BLOCK_HDR* pHdr;
1 \7 s3 m- ?9 A2 q4 ]8 i c BLOCK_HDR* pNewHdr;9 c9 X( U- w" N* o# H6 x! X
BLOCK_HDR* origpHdr; v) u5 `* r( h7 w
( ~3 T" ^# |" r6 m if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */: A, f5 x2 ? T( r' o2 F
{- `: @4 B4 Z4 z
return (NULL);* x- C6 w% I% ?0 T+ B
}
/ u* e, c9 p" U8 p7 V, P7 x% v* V( [3 ~. L0 W" ]
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
7 A3 M9 p; @% }" c1 U6 v7 v0 g3 f
% J# c a7 \9 s: ^" e* C5 G if((nWords<<1) < nBytes)
4 y I M1 X) ~" ^' H {
, T% n3 z9 u% z9 a+ B /* TODO suspend the task */
$ ?2 E4 t9 `" w% F return (NULL);/ P9 y7 x- t; K+ Y
}, `, P( K( |( A0 ~% i
0 z% G+ A8 f4 F W. y if(nWords < partId->minBlockWords)
/ \# t( f0 D ~. D/ s {+ L) r' q/ y" `6 W+ @& {1 b5 F8 d
nWords = partId->minBlockWords;
, o9 l! ~) B( N' } b }
5 B; U; e% w1 b5 B* n$ D. I& n, v$ n# T9 f* p5 h% W
/* TODO task the semaphore hear */; ]% `9 w$ I8 j/ x, _: l
semTake(partId->semPartId, WAIT_FOREVER);
# S3 e0 x1 Y% \# k8 P7 } pNode = DLL_FIRST(&partId->freeList);
) f' Y) o8 E3 w o nWordsExtra = nWords + align/2; /* why? */8 a$ k) K" N) J: r' A7 X
/ g8 q; D6 p u9 e5 ^% K
for(;;)1 Q1 \7 W9 G# B
{
: S1 m; w! @8 l while(NULL != pNode)/ ~9 v/ I9 r" F, j; q0 t7 P
{
?+ o" b$ @ d if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
6 x, n) u/ Y1 m: y* o; U ((NODE_TO_HDR(pNode)->nWords == nWords) && 9 ] _& V% x. P: Q2 v
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
) K; p. k! y9 C$ G q {4 ?7 c5 `: \7 S1 m: @- L* p
break;2 }" ^) P# M. f# z/ y$ @
}3 A/ D! [' g" j& V, R6 @
2 E% L; `/ P$ a
pNode = DLL_NEXT(pNode);+ Q2 r' O5 x1 w1 W0 g
}$ v+ ^% r2 _7 ]( u1 b
; o7 E* Z$ i3 g. h& o7 m
if(NULL == pNode)
" R! J( l) N# b! }: A0 l" { {6 a2 G1 Q6 M4 V% ~- ~% q
/*TODO give the semaphore */
+ P& _( f7 `7 J( l# |5 ^ Q semGive(partId->semPartId);
) X; ]& L6 O$ h9 Y, g# p" I return NULL;' ]# r f: G! x# {
}' m. O2 N% O+ y4 x) F
/ u( l0 [& Q. ` pHdr = NODE_TO_HDR(pNode);1 R" c2 g5 E5 J: }' ^
origpHdr = pHdr;
! u4 ]" |* {$ S$ y
o4 s2 U+ E: ^$ v: q j pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
+ f/ K& q! N/ \; e; m if(NULL != pNewHdr)
9 M& a+ q2 |3 ~- e0 [/ w3 }# y {
_- R# M$ v' n; W/ t pHdr = pNewHdr;
A: f; d+ {$ @ X& i* C6 y' f2 l2 c break;; ^! Y) q& i: L" K* I8 H
}
" P' Z# i# ?7 [' T; Y0 _* _3 r" s5 `- M; Z }/ E
pNode = DLL_NEXT(pNode);
# [' x! x8 `# m0 a' L0 N- ` }
# n, m9 d- `3 q6 O- q
3 F, A+ g1 ?8 Y7 d9 G' a pHdr->free = FALSE;
! h3 u1 }$ X& R! z partId->allBlocksAlloc++;% B4 C1 q" t9 h
partId->allWordsAlloc += pHdr->nWords;
! h9 s: z* z# v/ h! c partId->curBlocksAlloc++;2 o* `2 O% _) P1 a! R
partId->curWordsAlloc += pHdr->nWords;
( a1 u- g1 ~+ U( }' h/ H1 {1 V
' \& j& j! ~) w* ?5 ~ /*TODO give the semaphore hear */
( q9 D6 m# |/ m. M: H3 T semGive(partId->semPartId);
# |0 v$ j9 E" p9 Q' Z+ b return (HDR_TO_BLOCK(pHdr));
, \1 E2 I7 g% ~ + {) }( {& A' r
}- H+ \3 ~, @5 V
9 r! `8 j6 s( |+ h3 m- Cvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)" ^( u6 _9 Z* |8 f6 t- o1 K. Z
{3 q# `. K% R0 n# A f7 P
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
! f S) y+ Q$ e% s( p7 C: Z}' ?, o' q, L Z4 {7 w% |
5 k3 |+ g1 H y% M8 A+ D
STATUS memPartFree(PART_ID partId, char* pBlock)" F1 z/ b9 M) O5 E7 y" |' C
{
' f. U4 W$ C- @" M3 m! m5 ?+ \$ z FAST BLOCK_HDR *pHdr;
8 ]* R" ]1 b4 e+ D FAST unsigned nWords;
& R* S4 h/ H/ x FAST BLOCK_HDR *pNextHdr;
+ J; R* V0 V/ a# E1 ?3 m) H% d1 P, Y+ J9 ?9 a7 r0 ?1 B
if(!IS_CLASS(partId, memPartClassId))
- _! Y7 l, N/ o {+ H0 l( O" L; \. C6 Y) w
return (ERROR);
# S' B, K& K6 R& R: v& M( j) j8 f }
( t; m, \7 i$ @0 K) B- d z7 [3 K& F
if(NULL == pBlock)
) p. v7 _2 ]% N8 M# y! u7 N {1 y w7 w, e4 e7 w
return (OK);
, P* c6 p# r7 j, @1 Q3 t$ J }4 a {- r- p5 M
8 \" x" y6 Q6 d: t
pHdr = BLOCK_TO_HDR(pBlock);
; X5 O6 d0 Q! w' F4 R4 r" Y" A" `) n1 w* V
semTake(partId->semPartId, WAIT_FOREVER);
2 O$ H# W, f5 D# t2 m. F: W! r! v: |2 W7 w
if((partId->options & MEM_BLOCK_CHECK)& ]/ G" V8 r4 j7 Q6 T0 F
&& !memPartBlockIsValid(partId, pHdr, FALSE))' Y; B5 D0 r" T# j* v& t! e
{
" h# P$ d1 H4 m* @$ o+ t semGive(partId->semPartId);1 j$ L8 k7 N5 g8 x& C
return (ERROR);
7 b( b7 k& t# K9 l }, R- L, s$ z0 h
5 i, x+ {! Q: |* A {8 y3 N: j nWords = pHdr->nWords;
- D9 c) D3 p/ P3 s& H# d( `; I, W if(PREV_HDR(pHdr)->free)2 I& D- f2 h5 F" i
{/* the prev hdr is free and than coalesce with it */
+ \; B9 H( z. T! k7 y% T$ h pHdr->free = FALSE;
9 @# [7 r5 y+ L) G W pHdr = PREV_HDR(pHdr);4 w3 }0 U) i# G
pHdr->nWords += nWords;
. }) t0 J6 {, I( U/ X( q- Y3 z }6 s- S& B, _$ M8 T, Z, J+ ^
else( `- ~5 [% l# P7 @9 B
{& S4 C- `6 c% T% C+ O9 S
pHdr->free = TRUE;
' g# v; M7 J; N) a: y5 X dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));3 F8 d. w$ Z- L' Z
}
6 q5 {0 A, ~4 o" C5 q @" h* L! o$ o% V
/* check to coalesce with the next */
2 j; [- b5 z# G; l: ] pNextHdr = NEXT_HDR(pHdr);8 O# C' L u! Q# ]$ \* A* L7 ]
if(pNextHdr->free)
0 \( V# z) s6 T9 f- e# b& n( { {
; [& l4 K4 D/ A8 l7 Q! R pHdr->nWords += pNextHdr->nWords;
# X+ j8 U. ~2 b* D: Q+ T3 O& J' e dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
' Z4 F: P8 |) d' c+ \& g0 m }
& t! O; _$ N% r6 T; _
, X, O) p P8 Q* z t" K. K4 Q0 f /* cannot use pNextHdr->prevHdr=pHdr hear */0 ?( S! o. O* E. W$ V8 a4 _
NEXT_HDR(pHdr)->prevHdr = pHdr;
( q& ~8 A/ T' K
/ i2 T& z1 `+ L- b* M partId->curBlocksAlloc--;. s, v i {9 Z, v. a
partId->curWordsAlloc -= nWords;) z( B* I, G4 A- L- _ x
" x" E! }' ~6 e6 i /* TODO give sem hear */( g2 E4 t c2 u+ ~+ D T' X5 u
semGive(partId->semPartId);
. n# O y, `& M6 V' @9 D, | 5 T) O2 s; `2 q }9 v+ C; Q# }
return (OK);
7 o" t; \0 Z9 f2 {) f b- G- E4 ^}6 S+ P: Y1 h" |, E" K4 o8 @
$ v7 s. m% w6 s$ T# v( q& b% i% i
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
8 G( S# x: U! Z, L: {{, h' h6 X* I. F& M
BOOL valid;
( m1 X9 u3 N7 m+ B$ V T: s4 @
TASK_LOCK();& j6 c5 A: ?7 ^# n7 m
semGive(partId->semPartId);
- ^) h4 L8 p: Z/ A1 c
0 t% n# |3 k h0 `* b+ L. s) z valid = MEM_ALIGNED(pHdr)7 O: `+ ]7 ^6 _0 z j
&& MEM_ALIGNED(pHdr->nWords*2)$ X, ]1 n: A" U5 g
&& (pHdr->nWords < partId->totalWords) 5 V9 v) X5 b, I
&& (pHdr->free == isFree)
7 u% a% u W3 n4 t# E && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))4 Y5 \# r! w6 [, o' ~# l
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
/ ]- F% l5 e* y* W: V8 E) u
2 R0 |0 M9 X. m/ W" W semTake(partId->semPartId, WAIT_FOREVER);
8 L8 _( l9 R' a) o" q! ^: H TASK_UNLOCK();
2 o! J3 Q$ B1 H, V }. f5 c' y, _" b) l
return valid;/ {- m- G+ ?6 O- M
}/ p/ _' j/ M6 r- H
% x2 @- f1 b0 S& {( f
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
% s1 Y" t# G7 \" _3 ?/ u! e , FAST BLOCK_HDR* pHdr, p. e5 J; n7 T! o6 t) f2 j
, FAST unsigned nWords
, H! `' s8 }# K$ ]# `+ t( i7 g' b , unsigned minWords: r+ K: ]* G. a
, unsigned align)
$ \8 z+ k4 y& ~& B' B{: V: J8 Y# Z* U! s j" V! Z
FAST BLOCK_HDR *pNewHdr;+ q* r( }7 P7 r6 C$ }' I! K o. w
FAST BLOCK_HDR *pNextHdr;
! D' P2 w; \, i+ U% M FAST char *endOfBlock;* j# c2 y2 k- M
FAST char *pNewBlock;9 k; Q( @9 b: r0 N: }
int blockSize;
7 M/ C( \: o5 S4 Y. X( Y& |2 Q4 T9 I
endOfBlock = (char*)pHdr + (pHdr->nWords*2);
9 {$ I, U% b0 K; G# v' f# a6 m- j4 m2 F2 w" H# r! s! q
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));) O5 Z+ E3 U" b# ^$ Q" N
3 Q w8 X5 O# |' W- L
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));6 C' t" j% |- ?. T- \4 K; N
) t) k: Y3 q* a' ?" J/ I pNewHdr = BLOCK_TO_HDR(pNewBlock);
1 E" @, Y* L u* \# @
7 B" f8 W; G( J blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
9 \6 k3 j8 S" p' m/ E+ F+ `% M8 B# K. N
if(blockSize < minWords)) R7 Q2 W3 \' U* G' k/ G E6 A( R Z2 x
{/ @. \- t( k* _" W# [/ }
if(pNewHdr == pHdr)
! K7 i+ j. K! B9 J* I! [% O0 N+ T' ^ {8 ]& e% s; {$ I; a7 g0 n& a3 G
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
; M( l- b1 \9 c3 M: P! B }! I" F0 W& U- u* ~6 O5 t
else
' s l. l$ }: e1 k1 M {
4 K2 e& a0 q3 d$ N% Z return NULL;
0 w1 n+ \& f. x6 i9 W }
2 k. i) u! w* R F: a* X) E( ` }% |: \+ n4 V2 z. H0 g+ G4 u
else
6 k3 |+ ?! t7 \- R) H2 J { /* recaculate pHdr */
3 p' Z5 f7 n, m4 | pNewHdr->prevHdr = pHdr;
+ {8 u$ G' Q G/ e pHdr->nWords = blockSize; F z$ T7 X3 {
}
, m y+ \5 C: ?. A
" }4 A8 R9 h# n" T if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))5 v! d0 N/ U7 e0 S$ I9 o8 I
{4 i7 [4 O! [1 q Q a1 ^- t: i
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
. U- O1 @: F% t3 S# b9 H pNewHdr->free = TRUE;
- F3 C a6 `) j) w- H
. D7 q! z% Y5 b* o& o NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;! O+ y* K9 R5 |4 g# R
}
) n$ H; ]" v3 u; a( w else9 C/ J# Q7 m$ b3 R9 A4 ^! Q
{/* space left is enough to be a fragment on the free list then */
: k$ m& G3 {8 w T: _8 a pNewHdr->nWords = nWords; m: c( [; B; n5 A4 S
pNewHdr->free = TRUE;
3 o; V+ b! Q% h$ h
9 m3 ]6 q2 A+ w5 ]& P pNextHdr = NEXT_HDR(pNewHdr);; W6 j5 d0 K$ z4 L3 g- }
/* words 包括BlockHdr */ E$ @% ]) d8 _# ]% V) | M7 y S
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
* U' W' X! i/ h: p- q' M pNextHdr->prevHdr = pNewHdr;
, ?- i1 @# w* v/ c. Z5 H pNextHdr->free = TRUE;% O3 ~5 r% `, T' D
- x/ z' ]1 W5 O9 _7 L2 J6 A dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
3 R" P' q! x7 G4 c, q
4 H# D/ n* A; \( S; G" {! h5 t( r& o NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
1 J0 A/ W: }1 s* J! X( S }
) M' F& R& b( g
' J1 b, M+ c6 E$ u4 W2 W0 G% X return (pNewHdr);
' X8 C0 ?0 K1 H1 }}; @1 x+ M% g9 t* A! }& Z0 e' k- U
# u1 M# W/ d$ {1 A8 [1 R5 fstatic void memPartSemInit(PART_ID partId)
- O0 i% K. Q% ?! i- X n4 ^- z& l{
! L9 g* Q3 I7 T* ~' F semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
* C: O( Y |+ M: }, x, ?- W! u
: Z6 G0 H: n8 `$ G! i2 l) T& S* j partId->semPartId = &semMemSysPartition;
+ ? V; J3 [( s0 T}
- n9 _' W; c& k% {( ]0 t, A1 U0 P* z/ F' u9 ^2 q+ ]6 N0 {+ q
void* malloc(unsigned bytes)
( ~; V9 w0 E4 `- r{
D/ Q4 Y4 V. t3 m& ^$ L- G return memPartAlloc(memSysPartId, bytes);
* ]9 |% A5 B: O/ D* s% R}( T5 [3 C4 \4 {' b
3 S, }2 b$ G' B' c7 T8 Tvoid free(void* p)& U$ Z. b b1 ~: ?9 b- c
{
" g0 ? H) ~/ @' w0 N( |6 m# R3 R memPartFree(memSysPartId, (char*)p);
# W4 _3 p( p9 ?5 t; ]}' z0 d2 d& y# e/ J" a- p7 w7 b
|
zan
|