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