- 在线时间
- 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++下的版本,更方便调试。有需要请留言
% ~- L" s" n$ j( l# e' q' m+ w! Q; v7 e. H( N0 A8 M0 n) [) f
/ i3 @, Q% a6 e" @! D1 s9 ]
0 e3 d1 @+ z$ K *\file2 v& v" A! T0 Q9 x4 \6 @& u' ~
*\brief 6 k5 N$ v( K1 E( Y
*\details
; B" C* \2 W! V* U& n$ J! R *
- |- V8 _5 y0 R. k E+ D) [ *\author Janson
$ J/ J$ j. J; Z/ n0 V8 o; z *\version ) z8 }* m& \5 i: `0 e2 k! v o
*\date 04Jan126 ^5 d& i) x) |
*
( ^6 D5 K3 A4 F$ V# K/ y( X% T9 D( P *\warning ) A' [3 p$ S8 I0 d7 M" R; M- r# l
*/ b; f& Y- k- P& U b2 u" N
*\history \arg 30Jan12, Janson, Create the file
7 g: ^! |0 Q# i F: k; f# J * modify from VxWorks source% `" }2 Y3 }/ z
* Legal Declaration: it is for studying VxWorks only.. V/ k8 Y$ P# k9 ?* Y ?, f- J) c+ }
*/7 b& P# L- O6 b8 N8 y+ b5 Q
#include "includes.h"6 \+ K6 O9 E8 y
5 k m3 {' x2 K" A* q' e
/* The memParLib.h file is hear:
% t5 m4 [/ W" d, mhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
, x F2 V" R3 [9 L* M0 t*/
) I. ]; A$ [% S8 ~- D! H
0 `+ l( d5 h$ V( _/* optional check for bad blocks */
5 S7 @& R& e% Q n& A: E0 o& w' z; H1 m/ y7 S
#define MEM_BLOCK_CHECK 0x10
8 {4 y( ^$ r- {3 d& q# Y# A/ m" W4 Y+ G" c
/* response to errors when allocating memory */6 ^0 p/ d, _9 D9 Y- I4 U" f5 m
% T: q# y; I, v" N$ P s#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
' s, n/ f9 ~5 g) m3 \8 X; X- J0 y% n#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40) |" u I6 G3 \# b. \
+ D! D( }1 ?/ Z7 F5 b# [# a
/* response to errors when freeing memory */! h5 |! z- i8 |
5 s. ~7 ~; m) G; `
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
) H$ C& }7 z2 U6 S! }( M% f8 ^#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
C1 R5 M7 Z( W }) k( ~: K1 W$ Z; L6 q' z
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
# [5 t$ C+ m8 j* g- \#define PREV_HDR(pHdr) ((pHdr)->prevHdr)7 u+ P' W$ q' g) V
) g/ J6 B# Z3 b8 Y: V+ W$ w#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))( k, `0 Z& |9 I f- i, a4 _
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \* _/ J+ i* J! |. Y3 ?; @$ e8 d
sizeof(BLOCK_HDR)))3 p/ c7 T; L2 {& W; m" I
* {5 [1 \9 |/ e& ?& |, L$ p#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
4 k8 L" H, c# a( k1 T% D6 W#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \0 j4 ^# g9 ^5 g. r6 B7 [; k
OFFSET (FREE_BLOCK, node)))
4 z; f1 L! l) {" |0 g! n5 J( w* a
: A; ~1 A# N( E0 Estatic BOOL memPartLibInstalled = FALSE;) Q. L! `$ f8 X! M, s
( g9 }' I/ R! ~4 k: L0 @8 Pstatic OBJ_CLASS memPartClass;. z2 {. m5 l! u
CLASS_ID memPartClassId = &memPartClass;
8 V3 h. T ?. `. U* m I1 M$ l; i% |) v0 ~4 D
static PARTITION memSysPartition;& z5 f1 _% B8 P: W! H9 v0 G. b$ F
PART_ID memSysPartId = &memSysPartition;
5 Z0 Z4 p# `2 v' Z1 S q$ _U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;: d3 P6 @ v* b
+ W0 H! I9 d5 H( K0 G1 _% mstatic SEMAPHORE semMemSysPartition;4 p. _, x: Q& I, o- `3 s+ n3 f& D
7 q& B2 D: T+ o% l
static void memPartSemInit(PART_ID partId);
5 j( z8 C$ x3 I8 c8 M R3 i( W5 H
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;1 w0 T' y' D( u, Z3 D% N; v; J6 _' r
; Z6 }% R/ S9 r
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;- A- Y* `* j2 h; G
; [7 J# e$ |* V, Hstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);$ ~' w9 t8 l3 @% `% `5 D
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
9 ~. Q6 p! B" q7 b , FAST BLOCK_HDR* pHdr. T% Z% A6 j5 Q0 {
, FAST unsigned nWords
; o+ ~* h3 L+ V! r , unsigned minWords
/ t. v& |% {- b, B0 q , unsigned align);
- q/ ^/ p& D) _; G* W% i6 g
( }! R( R7 l$ | s$ g, fstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
3 C# P, v9 |9 _5 e2 F: ~- ?! U; m( Q3 _
STATUS memPartLibInit(char* pPool, unsigned poolSize)- m. d1 o; h" ~% x4 R( T
{ L. B9 X/ k6 I& I6 _
if((!memPartLibInstalled) &&
7 h5 B3 ~ u+ ` (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
5 G2 V7 }" g, k* [$ x5 }# i , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
" }3 v+ n* w; {& l6 d7 [" K) i {/ d% C: Q: p! B0 e" _
memPartInit(&memSysPartition, pPool, poolSize);3 B6 n5 N9 ~3 r) k
memPartLibInstalled = TRUE; B/ K# Z) A6 _ M+ ?
}
6 ]) e2 g- K, j" m3 i, \+ n8 q |
+ c& a5 P+ s8 v- a! G# w return ((memPartLibInstalled)? OK : ERROR);
, ?$ o. ?% d0 i' w4 `}4 k1 \7 E- A% O7 {( J/ m# l
4 L! M( u$ }$ e G' d7 a1 g
PART_ID memPartCreate(char* pPool, unsigned poolSize)" f! K5 N+ T% m8 I; b( e
{
! Q6 R `9 Z% e4 N3 G s PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
/ x* c% V8 m: v* h4 F6 ?
l) V3 l5 R4 D% n$ ], W$ N if(NULL != pPart)5 W. g8 `2 B! q* v- S/ E6 l
{ d% j+ {$ s, S2 A! X
memPartInit(pPart, pPool, poolSize);
- Q2 O! t! n& [5 C/ X, E }. v, S, P7 }% i( D
6 A( }1 S% i# U' b0 _9 h' K return pPart;
, c; I& R* A: O; U( @$ ~+ v- P}
/ z) k$ _4 [% a1 T, k" J% {
s& h% u8 U4 z: a. |% Vvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
1 h( k1 a3 V+ ], \2 Z{' v* L A9 N& ] M4 c! j! \3 L$ p
memset((void*)partId, 0, sizeof(*partId));% X7 e5 u$ S% g# Q
# U% Y/ C2 r5 J# F9 J& m partId->options = memPartDefaultOption;
6 ?& w( H2 @, }1 E% a4 X partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */
. _1 X5 f& k) f# Q0 X/ W: N, L6 ?. `! j, j8 j% ~
(* memPartSemInitRtn) (partId);# ^6 G4 \' X' p. U w4 r
( P4 |$ U- C; t, u dllInit(&partId->freeList);/ t9 H3 m( l; U0 e
]% o4 V1 c: |: u$ X
objCoreInit(&partId->objCore, memPartClassId);) O8 w' F/ `9 q3 M9 [
/ V% N* \7 X$ n1 F+ t
memPartAddToPool(partId, pPool, poolSize);
& n8 f( O \1 C; {9 [ {6 a, n; U}
! Q; x( |( M5 s2 O9 q% I9 l
9 P" j1 q, U0 k1 v' mSTATUS memPartDestroy(PART_ID partId): `: W" o% j+ B
{9 y/ h& n( F' y
return (ERROR);; Z3 K( }' B* S7 Z. l. d
}" o6 O, c" s8 W7 @ L
! E# R* f* [0 V9 l) R( E
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)* h' f0 y, C+ h M0 m4 g
{6 }2 w9 D# S! v, `' |/ B, h* H
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);
$ V% X3 d4 w1 Z& r& ]" x}
9 i, v1 K2 i$ P, d# b' ]' g- D5 x* V6 P. Q% J
/ a3 C2 {6 i! K% b
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) L2 b; T( ]0 B. [! _
{4 Y* O$ c; A+ E3 \, ~. t
BLOCK_HDR* pHdrStart;
0 C+ a/ |; t" C/ a! u( U3 F" Z% d* l. F' T BLOCK_HDR* pHdrMid;
8 D: c2 I+ u; b7 c BLOCK_HDR* pHdrEnd;
4 j1 i9 ?6 |/ F4 J( W2 v$ b char* tmp;; H# `9 R( k5 x' @
int reducePool;
; o4 ` t0 K* e8 I! b# O2 w) M( T8 x. X0 D+ t+ f
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
' E+ F- ~2 T" p( m, V {
. I; |( D; G# K$ I. N( Z( j5 L return (ERROR);
: E7 D6 t5 ~2 A2 s$ N }
( n" k. z/ V; ^) K1 e
8 g6 k4 W. ]. d tmp = (char*) MEM_ROUND_UP(pPool);
! S( I; k8 ?4 h6 M3 K" k; k reducePool = tmp - pPool;
' T( E6 x3 U2 z7 o$ T$ f; {' v) i6 C. S# X6 U# U
/* adjust the lenght */
0 d3 K& L8 A* {/ S2 ? ? if(poolSize >= reducePool)
3 t# J6 I& Z* j2 o( ~ {
; k. C. J' ~& e; S! Z% h) J poolSize -= reducePool;
4 \* s- l Q" b) G0 r x3 | }
9 x4 x: I' I2 a2 a6 T/ z else
2 m) o$ l8 F# L6 U* ^5 I+ {% c {
9 L( G" f: {" H! [/ F3 i1 Y poolSize = 0;
. T2 V5 {& @9 B }
. y; [, x, p3 J ~* q- M# @ pPool = tmp;) A1 v, D, e% A$ n/ H1 e% f
/ y" h- Y) J: T6 \ v5 y C% V3 \0 D
poolSize = MEM_ROUND_DOWN(poolSize);
( h. J% s& v- {# L$ P " C+ u @/ |9 M
/* at least one valid free block and three header blocks */6 {" R+ ~, {% V! O8 m3 o% s" [
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)6 ]3 D8 m- j% V% ^8 J
{: e4 h8 G N2 H O: }2 _
return (ERROR);; h6 V5 k4 ?6 r9 O! b( W
} y. R! v1 c( Z7 T1 s. e( v4 O& o
$ _5 D$ Z( K1 N3 m# n7 v
/* initialize three blocks */
+ G6 e/ q/ `+ H pHdrStart = (BLOCK_HDR*)pPool;2 Z2 Y, E6 H* m' z. y; U
pHdrStart->prevHdr = NULL;- b4 R$ a. V! I1 j& s
pHdrStart->free = FALSE; /* never in use */, ]) ~& `' P \8 H; [! W
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;) T% h( h) R4 l/ B# b% c* \2 ~9 _
& e. Z6 m% W! c9 l" J
pHdrMid = NEXT_HDR(pHdrStart);* v1 a4 D5 Q! t
pHdrMid->prevHdr = pHdrStart;
) `( h8 j, }* ~& P# V pHdrMid->free = TRUE; /* the main block */
: s1 ~0 r. F; h# J# U pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;/ }; H" M. [( r% C% u+ Q
. h. q4 a5 R& ]( ]5 Z; K. N
pHdrEnd = NEXT_HDR(pHdrMid);
# L0 U* w3 B- f9 t pHdrEnd->prevHdr = pHdrMid;# d& p$ A1 i+ F3 ^* Y1 Y
pHdrEnd->free = FALSE;" j7 X( h+ c" M2 c3 N
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;# g& \3 U4 w# W5 J# N" ^
5 x' t( y8 C- S9 t /* TODO take sem hear */, p ~% F- f6 z$ e/ K; b
semTake(partId->semPartId, WAIT_FOREVER);
3 | t+ C9 q: N. `( T 2 h- V9 }; a) E. f: i' d* V
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
: u1 r# Q' s7 w/ U0 H9 [7 [ partId->totalWords += (poolSize >> 1);
5 |, x( L7 M4 t4 d6 N" f& z$ ~' D. y$ k4 Y4 O; a6 i' \
/* TODO give sem hear */
% X% R1 Z+ V0 k semGive(partId->semPartId);
9 ]" b4 b. B" T3 n' B+ N' T
& {. r$ d A' N+ i9 _
9 d! q- I. r ?! b! j: O* @8 q return (OK);
+ E% Y8 K' |: f0 r6 [7 D# l) s}
* m) D# w- e0 t6 S$ y: m( f0 [, g# w8 k, u% d
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)( V# ]% { Z: w0 X
{
q: A1 c& t& `4 F0 v* i FAST unsigned nWords;* E6 H+ e( Y9 H* _0 t8 V7 g
FAST unsigned nWordsExtra;) i ^8 X' B* ~: e7 A8 \7 t( J* }: C
FAST DL_NODE* pNode;, J: S# ^* y, T2 J. b3 n/ b
FAST BLOCK_HDR* pHdr;
9 ]7 o/ Q: t5 f8 l8 Y BLOCK_HDR* pNewHdr;$ C0 ~ O6 G, i4 z8 D7 ]
BLOCK_HDR* origpHdr;
, M! I: Q5 }8 [
, \1 G' b ~" t: ?' s) I if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
) K! m& h( h. G( `" t {& t4 v3 u& ?& Y) [: V% Y. _
return (NULL);
- y4 G' S; i( A! J: |; ] }
* t) N* f: Y! Z) s" x$ r; Q( z; y) v2 `+ d
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
; j( g2 X% R* \2 @3 ?$ Q+ J
# R+ F4 \. `$ c: V if((nWords<<1) < nBytes)$ L! C; J+ b2 R0 h
{( b9 k. c) w3 C3 c1 w$ K
/* TODO suspend the task */
- k# ? A0 x) G/ v return (NULL);9 F3 m% p" U! E b: z
}$ B6 ~, ]8 Q, G7 |' a$ q8 z3 I
- n ]7 l( D a6 d! B- p if(nWords < partId->minBlockWords)
: a/ y8 L2 ~/ P { m: m4 X/ m: a# q/ q0 x4 x6 F
nWords = partId->minBlockWords;
0 Z8 L# m/ w0 i: e/ k( u& h- K }
6 w5 C9 b) G& O/ @8 L
% K. U: r4 A* B% C F3 ^ /* TODO task the semaphore hear */
{1 j. D( O, j semTake(partId->semPartId, WAIT_FOREVER);7 Q5 v1 g- i# u& h7 ~
pNode = DLL_FIRST(&partId->freeList);" M: ?; @' s/ V* \7 y* C
nWordsExtra = nWords + align/2; /* why? */
- T" w' a u$ C _3 v( }8 [5 \1 W. s- e% E3 n# ^
for(;;)- C* {+ G/ X5 d; i. E; ^
{9 F9 p4 f& N5 r4 p
while(NULL != pNode)3 k2 @$ ^4 t+ W6 }1 I k" v
{
! ?9 \1 a m3 N- R+ A if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
: |9 F: |! ^" `% o7 J2 ` ((NODE_TO_HDR(pNode)->nWords == nWords) && # K+ q) ~6 s; [, d
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))6 t4 f) } c9 _$ @
{
- q' S4 @% i7 _9 v' A4 Z# l$ Q) E$ o break;
1 N9 s# E U8 x+ P- m0 G& Y d }3 E# y# z/ i O q8 I1 K
. K2 W1 s% J+ p# g! F
pNode = DLL_NEXT(pNode);
6 A8 }# e7 g- B+ N: K* l6 x# n }. y+ K2 v: k! R; ^; [5 H
. I$ {6 H$ ]7 n6 u6 R1 Z+ |2 { if(NULL == pNode)9 s: i0 j( E, J
{ _6 p: ?" _4 C7 N9 c; \% p
/*TODO give the semaphore */
1 i$ J8 P7 h0 ]' o! g semGive(partId->semPartId);
2 J$ f; ?+ f: C- @8 A' E0 U) M. F return NULL;: H% d# ]& ?$ m5 B: ?! i/ C
}: w7 n0 K' ]% G
. d* Y( O" Q6 y pHdr = NODE_TO_HDR(pNode);
2 X m7 \' a4 `$ G* @ n) z origpHdr = pHdr;7 w/ A8 A) n# K& b
% R" m2 n8 c6 [9 y! B8 ^# z pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
2 ^! Y6 E+ G% K4 J) N if(NULL != pNewHdr)
5 }& Y, e) Z8 t1 |$ \; i/ s {
, D7 t! r! m8 N1 n1 p0 ~1 s- v pHdr = pNewHdr;. ?6 x6 r: W' Y& T; q
break;
; H) U! }/ A/ c: P3 b/ \. c& m }0 K2 e9 V- E# D: y
: x9 f' s$ S' U6 N8 {/ U, ~
pNode = DLL_NEXT(pNode);: T9 q" [/ U1 R% U
}1 t% c2 e! l( q" g- o8 t: n
" i$ J9 `+ R$ }9 L. b: q
pHdr->free = FALSE;
/ s& h% v# N% a% {# i" \ partId->allBlocksAlloc++;
o% V+ R. U. L* X partId->allWordsAlloc += pHdr->nWords;1 F# n( w7 Q; R+ Z* P8 }; y: u3 c
partId->curBlocksAlloc++;
& Z' A& t4 X% }8 Y) g; } partId->curWordsAlloc += pHdr->nWords;
: s' C2 i0 |! \% v+ r9 ]; `, J; K# U. Z# T* K3 h X- c" J$ }4 @
/*TODO give the semaphore hear */
: y# b8 M( O' ~4 Y semGive(partId->semPartId);
& o' d O/ m' L4 v7 v return (HDR_TO_BLOCK(pHdr));
* F+ p: k# l) l; `- s) h( L ( u1 j9 ?* e$ s1 o, _
}) ?6 Q3 M4 z2 l3 e1 \9 O
w9 j- r1 B) c" B
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
6 X' U* u0 k' u' w9 z1 s{
# ^- d5 V% }! y% { return memPartAllignedAlloc(partId, bytes, memDefaultAlign);" q* _( y# Q2 j
}
/ [1 J0 a3 z, R" _2 M4 h/ v% t' ]' M! q. r
STATUS memPartFree(PART_ID partId, char* pBlock)& K W) O x. |8 S" I$ C/ d
{2 P7 U# ^' L+ P) D& E7 b8 c
FAST BLOCK_HDR *pHdr;
5 ~! N* S4 L* ?. z3 j FAST unsigned nWords;8 E2 Y( }9 U$ W6 j3 D
FAST BLOCK_HDR *pNextHdr;
" A% A2 y# J& X/ }$ S2 s0 n! ~! E' N, R$ n5 \7 A$ ^ k
if(!IS_CLASS(partId, memPartClassId))9 D$ D* A8 `# H* X, g/ s
{
2 S- s# g6 E+ H; e" _! w: P0 G return (ERROR);& r% R( X4 s6 S3 F1 w. M; E( a7 u
}& Q! ` d( B! M& c3 W
2 D0 b( j. o. ?2 i4 ]+ |
if(NULL == pBlock)0 t" a* T3 Y+ H3 {* l- t
{. S3 @, T5 r3 v% C. r% P
return (OK);
% ~8 d5 [3 S9 `8 w: }6 e }
8 T, _% F* Z r- Q' x1 y- l
$ N7 A7 o8 K- |5 W/ Z2 B pHdr = BLOCK_TO_HDR(pBlock);
% \( m% k' V7 j( I) P; K
; e5 T% A* g! v semTake(partId->semPartId, WAIT_FOREVER);) t0 T, P7 U) F
1 J" L# i+ c- U+ J
if((partId->options & MEM_BLOCK_CHECK)
- R/ Y3 J! k8 t6 T && !memPartBlockIsValid(partId, pHdr, FALSE))
7 _/ }9 ~7 U7 u4 T+ f2 _- q {
% P6 U+ K+ R# d. J semGive(partId->semPartId);# V6 ~7 m5 G" w! k& |2 F
return (ERROR);1 U& F6 G7 g: l1 ^
}" O+ d$ Q- y% B( _
2 ]% L. d2 m ?/ A6 i9 l
nWords = pHdr->nWords;. A9 ~, z- l: ^! c
if(PREV_HDR(pHdr)->free)& l$ E: `5 m9 \: Y& ^& d
{/* the prev hdr is free and than coalesce with it */6 K' Q: g) n- w% j) n4 j, @
pHdr->free = FALSE;1 Z7 d& Q3 ?5 h& N/ v
pHdr = PREV_HDR(pHdr);
1 V+ d' W1 }! Z% l pHdr->nWords += nWords;
* N3 ^1 _# i9 B+ A- y }
3 ?1 y# o+ u9 w( m3 K else. {& F9 ~* F. K1 V) h9 p
{
3 v( g' D+ Q1 Z" @! l# e6 z4 I# E5 l pHdr->free = TRUE;+ R1 Y& x) @- I. T6 |2 H% ?
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));! O7 B: ?, G8 y5 p) J2 n" r- @
}/ E* p( I; R2 [7 s4 P, P
4 D. l7 c# S W0 t1 x
/* check to coalesce with the next */$ ^" t* }) ^$ ]
pNextHdr = NEXT_HDR(pHdr);( n, \ U( z1 Z: C0 e5 f/ z( c
if(pNextHdr->free)1 H1 \2 p+ l) V2 h1 t1 J
{
2 x2 B8 q" O; J9 E9 M+ E5 C# o pHdr->nWords += pNextHdr->nWords;3 S" Y i; ^' Q6 j7 }( V6 v
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));. B5 I ]) I3 G, k2 l
}/ i" _' Y; X4 H. f; c# t! a$ ?
( j' u0 O! H. p/ g% z2 v; w/ ?
/* cannot use pNextHdr->prevHdr=pHdr hear */
( N2 E+ }9 S8 x8 f) e NEXT_HDR(pHdr)->prevHdr = pHdr;9 N" X* V y; [2 q4 M
' L7 }/ b. x( ] partId->curBlocksAlloc--;! l1 a3 Y k: B2 [. |$ f
partId->curWordsAlloc -= nWords;; k. K2 R2 Y0 f8 B/ O1 i# _( f
3 K" s/ Y- s) u5 p5 K( ~( [
/* TODO give sem hear */
+ |4 _* P( X6 f: V3 h4 F" X semGive(partId->semPartId);
6 q" y% q! z1 d- t% B R 3 A% X' u" \$ {* k
return (OK);
! J0 ]2 ?3 o2 b$ |' {9 c/ i}, G$ @9 E+ h/ V! _8 I
( N: X! y3 V; W( sstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)0 ^( k# ]% C" p: F5 H' B1 w
{/ Q/ s) C3 B$ g) ~
BOOL valid;/ c/ R X+ z! f( ]. J9 `0 T! a
5 B4 T6 H9 L5 _1 P* O
TASK_LOCK();' W; |5 S% ?5 }- V# x+ Z
semGive(partId->semPartId);! ~, M! {6 f/ b5 ^- S' F
2 L; D; B. ^! {
valid = MEM_ALIGNED(pHdr)& s4 M& j D0 S! ?7 {
&& MEM_ALIGNED(pHdr->nWords*2)2 [5 y6 Y5 s4 W/ m: Q: i
&& (pHdr->nWords < partId->totalWords)
6 O; k6 ^& r) l && (pHdr->free == isFree)& S$ m, ^9 Z( ?" |$ x% D% F
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))( `) N9 p h& E! }/ E
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
/ m2 ~0 [/ d3 ?+ s& v* w
4 P! f, b6 F' X v/ s- n semTake(partId->semPartId, WAIT_FOREVER);$ {* ~" |; d* D. a
TASK_UNLOCK();
. E7 C# w! c6 O: X3 z3 S3 C
- Y% l F8 u' K return valid;
& ^0 M7 B5 d5 m, p}
$ V/ ^- y3 o1 x& n! w2 k
5 z1 x" R* s- Y% o& Fstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
% {2 p% u2 f5 M. r6 N , FAST BLOCK_HDR* pHdr
# g" E$ K8 ~; G6 f( e3 f , FAST unsigned nWords( k% o+ d! n& a3 i! P
, unsigned minWords
7 F! s7 }0 b" [ I0 W z7 g , unsigned align)+ u2 F6 h5 O( W& e" W
{
* L3 J& x# x* i" _. |2 f& Z FAST BLOCK_HDR *pNewHdr;/ d4 B3 }1 ]/ t. k
FAST BLOCK_HDR *pNextHdr;. ]1 z/ `+ J0 W8 i
FAST char *endOfBlock;
: `0 F! ~! E" K& s1 ^& U9 z( q FAST char *pNewBlock;
& V M8 J2 Y6 N3 c* ^ int blockSize;
9 L7 D3 N, P, j, \; N! U; I# R; A, T% h
endOfBlock = (char*)pHdr + (pHdr->nWords*2);
% ]6 @: H ]. j7 F* H. k" R6 ^$ C7 `) i& n/ n
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));3 G% r: {; h$ B4 I- Q, j3 |
/ c8 `3 M: N& G' [2 C1 b8 ?$ ] pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));- m: m, q* g$ @- e& d
( P; f# r! Y$ }, G: L; Q
pNewHdr = BLOCK_TO_HDR(pNewBlock);6 _0 a4 R! w3 i: P7 [- Z
; a" e' ^3 H0 O# g$ ?5 Y blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
& Y: n) J. L, D' v+ h# r3 }
6 G" M& C# w# k7 n' u3 L$ ]6 n if(blockSize < minWords)7 O: B) d. b+ c
{
" E/ ?! C2 X1 w! h2 H if(pNewHdr == pHdr)
3 [+ ]/ o; K1 q6 q5 ~# n {' w% V" ]: r1 ^% T; A7 i- i
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
4 e0 g$ A0 w* ]6 c& J# {$ d& A( w }5 {7 `1 t$ {1 N0 p$ \' p. O
else
; L- Y7 L! f9 {& h9 y {
9 C3 Z% p( C# {; ` return NULL;4 E- g. z7 S b% K7 o
}
3 Y/ n% H0 |7 T$ h ? o }! {" B- S' I6 l2 h) q5 i) m! S$ v
else
9 t+ _8 _$ p) R( l6 K- O { /* recaculate pHdr */. {; W$ h" \$ U$ _4 i; ^9 M0 V
pNewHdr->prevHdr = pHdr;
8 M! L9 ~/ d" I; I+ a7 Z; j pHdr->nWords = blockSize;
9 n# d/ H. _ x1 s0 Y }; q9 G8 n1 O9 E0 D, D
0 h6 M* p. S/ E( a; X if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
: s3 ^& Q; t! i4 [+ e {
: k) v+ O( X) I$ b; p pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;. F' x# o2 x8 U3 H6 D
pNewHdr->free = TRUE;
6 f' p( I! t/ g8 N# x. U+ G
6 j3 @1 z8 J; U# X% c3 z1 a NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;( e2 b! L4 }' O. @
}( L3 {1 w3 d5 R5 x
else4 ~3 Z0 t1 a4 c+ p/ {
{/* space left is enough to be a fragment on the free list then */
, b* }5 O9 K# M$ e pNewHdr->nWords = nWords;7 @& u& I6 S* A; D: x% u4 c
pNewHdr->free = TRUE;
5 A8 k8 N7 c1 l: g5 [! z5 V( `- S3 ^5 v5 ]5 V' C. x P' E
pNextHdr = NEXT_HDR(pNewHdr);
1 n. |8 I4 }: L5 ]7 \, S, H: O /* words 包括BlockHdr */
7 S2 h9 W% O' s% |* D- M pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;1 T, \5 [/ S& K9 s% h8 m1 N5 ^
pNextHdr->prevHdr = pNewHdr;1 W6 h o% z& W3 t" H w r9 V2 x
pNextHdr->free = TRUE;
* @% k2 W$ M* C5 w% Z# i
$ f/ ]8 Z: @, n, D) l dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));4 o" `6 B: H3 B, k
3 w4 t* D9 ^4 f NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
* R: Y4 n; f7 p( i5 }6 S- C3 W( x1 G }
% [- k. Z0 E" ]% J
, j- |9 M+ ^+ ^1 L return (pNewHdr);
7 X9 L5 S' @+ a3 M! ?, K}
; w8 x1 i: d; Z4 L$ T5 h) @- ]! M9 A5 [* q5 H
static void memPartSemInit(PART_ID partId)
4 V( r9 Z, q" A, H/ _- x5 Z{/ c O+ V1 W. y4 L! t/ B
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
# A V0 L9 G' I( @1 i A+ Z+ m; v, d5 K2 F6 [
partId->semPartId = &semMemSysPartition;! ~5 M* y* p5 |% o( e7 U+ G( j
}
2 ]0 P. N# A! h, n" x4 N) S: Q# w/ i" g$ P W0 i
void* malloc(unsigned bytes)# p6 B% F! I8 ~7 C* k7 D: |
{
; L0 q5 M5 d [& D0 ] return memPartAlloc(memSysPartId, bytes);6 ~5 H3 L7 O$ x! }& q' `
} C% p5 V$ O0 t# e6 t; R. O1 ]( R
4 t9 p) Q# ~/ Y3 s$ d* q. u6 v2 _void free(void* p)
b- Z. G2 O$ ^# a{
8 U! M/ E% l1 G memPartFree(memSysPartId, (char*)p);
* z$ i8 u; x+ V; y( {}
0 Q1 ]) q, H% t0 t4 ` |
zan
|