- 在线时间
- 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++下的版本,更方便调试。有需要请留言
2 ^1 s2 v: I* E: V& |0 o0 F- E$ b' [! J3 }
+ r# n! l& R: b
* k: ~7 j' |, x *\file. b" s: O( f0 P0 N( ]' Q, L# e
*\brief
7 F2 v B4 _ Y& L) p. u) ? *\details
+ \* p' q2 B& @ *
' g; i9 E, n% a- q *\author Janson
, e& z: B+ ]" G6 F/ m: p2 J *\version * P( b- a z# _- F+ `
*\date 04Jan12
6 ]0 \9 Y$ D. { *
9 L9 n% l9 p. k( K *\warning 5 u j' T$ b4 o; o9 F
*" {, j6 Z3 Y$ f: z7 L& U
*\history \arg 30Jan12, Janson, Create the file8 h4 s3 o6 v" t! d( S# _
* modify from VxWorks source; T( r$ E; Z- c; o. v
* Legal Declaration: it is for studying VxWorks only.
) v3 W3 H8 q' _ */
% O0 T# f; D* _% q# U: ^- p1 k#include "includes.h"4 C- }) v$ \1 I5 R4 K
2 ?8 p( |% a, v; Y# A
/* The memParLib.h file is hear:5 F2 f; ]9 Y5 R7 c8 Q# g4 t
https://code.google.com/p/vxwork ... rivate/memPartLib.h1 B" {. H0 M( l+ W* i" x
*/6 c* K6 k8 a% s9 L3 L' x
3 J, q) N" m3 x- l8 Y3 M$ V0 h/ p/ v/* optional check for bad blocks */
( A3 Q6 l; Z8 |: ~4 m @
) V. L( t! W) y#define MEM_BLOCK_CHECK 0x10
) b3 N; \+ P+ F6 S
0 U+ f& d4 F2 ?/* response to errors when allocating memory */
0 C$ o2 U9 m. I1 J$ p" R
4 e1 R2 D7 `% F( a8 x#define MEM_ALLOC_ERROR_LOG_FLAG 0x20! K: |( W$ s1 D1 [# u1 Y! u) E# i
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40. l% c0 F$ @- J2 U2 R) z
! b) X# s: _% x; L7 J/* response to errors when freeing memory */
/ d! ~! J# e! A. Z7 u- a
" h4 s2 h, J& r" M* e P#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
2 s; E0 C; I! ]! e- h$ k' v#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
6 v$ X8 R+ E# C7 ~+ g7 J) m0 p \7 g) _9 n
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
( h. V0 H" q7 V- q2 R#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
3 O$ `; J0 t6 Q3 U" D
) h) q" `' X S4 P/ D#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))3 ]. ^" @2 u/ P6 x
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \7 I( Q" N8 R2 w Z
sizeof(BLOCK_HDR)))
# M4 T, f4 R! M/ v# P5 y# L1 t9 C7 \. y* O7 a8 f% V2 `) o& a
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
3 u1 B1 E9 y+ }6 h% V#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \4 T* L# V& w; T- F
OFFSET (FREE_BLOCK, node)))3 V' i9 B; ]7 a% c
. X) W, h$ E: ^( f% a
static BOOL memPartLibInstalled = FALSE;! O- f/ e) P" k$ l" s5 U" g
0 i% C/ k W8 {4 _
static OBJ_CLASS memPartClass;7 H5 D- n5 k8 q8 W
CLASS_ID memPartClassId = &memPartClass;
! y2 J3 Z1 U1 Y& E o
! o+ o, f( _+ r5 d3 H( I, h& M0 @8 l, |static PARTITION memSysPartition;
6 |6 }: E: m- g; _/ [PART_ID memSysPartId = &memSysPartition;
) j) V! U# V7 yU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;% r# Y1 O7 t5 g4 i3 r" l
. @+ K0 G. k8 v
static SEMAPHORE semMemSysPartition;
) u9 r9 Y% U9 p: L* D+ V( f; @2 g: s2 H) p) n
static void memPartSemInit(PART_ID partId);- w- ?, r6 a. _* z5 f
) q1 C3 l0 s" }/ }/ B* ]* ]1 g7 i- x) }FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
* f9 } m# y$ U6 C" i( M1 _" w* @7 {% v1 v5 R
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
! W: M- S4 A/ e5 N# n" z! X/ n( r$ S3 w
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
! W% I8 Y. K# h Bstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 A1 U9 ]2 E( D u% L j
, FAST BLOCK_HDR* pHdr
" K5 _' d* v B' d/ ? , FAST unsigned nWords
" l. N( n* C9 o/ g" X( @( O: n& i& _2 T , unsigned minWords
, g+ x1 W1 k; H% E& K , unsigned align);# o# \& K' W( D+ @
4 I5 B! c8 ]$ k+ ^: U& W4 X0 astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);& [. C. [5 U8 I$ O3 ~! {4 v
( q! F( I1 M8 t9 D) {
STATUS memPartLibInit(char* pPool, unsigned poolSize), d/ G$ w* t ~
{
" a* d- f6 J, i if((!memPartLibInstalled) &&
2 V, ]1 X8 J8 V# `9 S (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)$ ]) \# s, h, C Q& ?; M# v
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
4 y* c4 n* G7 K) o6 M. |4 G {
5 w" ?. R, z5 b$ Q memPartInit(&memSysPartition, pPool, poolSize); x% h6 h% V# u5 o) b
memPartLibInstalled = TRUE;+ f+ e& U" G% s/ f9 O
}
6 W2 D: a7 b6 ~ v3 A
, a5 i% D2 \. x( k( d2 f3 ?' J" A9 @$ u return ((memPartLibInstalled)? OK : ERROR);" n1 ]0 h1 S: F: C6 d: \' \
}* u4 r* S5 y3 b3 u
9 j, E/ F% s$ ]+ KPART_ID memPartCreate(char* pPool, unsigned poolSize)
7 E$ {8 h( F5 b0 Y, k9 R{6 S N j: G- V4 g8 u9 J0 T& m2 J
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);. f# d3 C& N _5 l9 i
1 o3 u, M ~. Q! g
if(NULL != pPart)# v0 _+ e: o! I/ N$ r
{
9 E8 w: x$ h/ V' [ memPartInit(pPart, pPool, poolSize);* l/ o' c3 X- {7 u
}
, x7 n& q% B- C4 p7 s7 C& f: i7 ^6 f: E9 f5 g% ~: M" P
return pPart;0 i" C4 G; ?$ X% s9 l: q
}# T* ?1 @9 P& D/ B, F
1 t3 k, M1 {. Mvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize) l g: K- x) H3 i3 M
{2 H- Q# u$ R$ o p2 Z8 t
memset((void*)partId, 0, sizeof(*partId));
. ^- b- O: A' \! q, X* l
! `; d( W6 j* P partId->options = memPartDefaultOption;
# I. t1 U4 R @, j partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */6 {( j5 g' `- n J' a7 o
w$ t! ?! z6 f8 r! y0 V: E+ Z5 o& D
(* memPartSemInitRtn) (partId);7 Z! E6 r9 ~9 V5 ?8 Q
& k4 p) |9 ~$ t" p, N) t( N4 [ dllInit(&partId->freeList);5 F" o: I5 l0 r* n
1 J; p" Q) _1 l1 G" ^8 A6 p
objCoreInit(&partId->objCore, memPartClassId);
' _6 `- W9 G$ C9 v. y7 o4 M 0 m& E( T+ H( k, b
memPartAddToPool(partId, pPool, poolSize);! d6 w1 L$ o `3 ]4 J* D% X- h- N
}
' e; f2 i+ j- ^7 t( ?" _( D9 ?: P- O, j* N0 l
STATUS memPartDestroy(PART_ID partId)1 X5 X& Y; R6 G) o5 w- t
{
, T+ ]7 r% ^ K. O# h6 j return (ERROR);
' K7 { P- ?7 a' ~9 T4 e}
# I' ^% ]; E6 u- u
. E1 G6 {2 Z% J# K, }( H# }void memAddToPool(FAST char *pPool, FAST unsigned poolSize)2 N% y" a$ w8 M, H/ s* w
{
( c% ~! }% d# e( m, S (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
, e: w4 C, k- r7 w0 s _2 i}
* g6 j9 L; K$ w
. r: E4 r, b( ]- a
; M) s K( H5 u, ~: vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
* d" N% v5 N% ?9 L) T9 l9 o{
" Z- e9 Z& |/ U: }9 ~' H7 ? BLOCK_HDR* pHdrStart;
( O- A3 d$ [7 v2 g8 I4 p, a; ` BLOCK_HDR* pHdrMid;
: J; a# w. ?) f7 d BLOCK_HDR* pHdrEnd;) J% k( o8 a2 n
char* tmp;$ ^2 I$ _3 x" ~6 C
int reducePool;8 f8 S9 [" G b! Z# A# `7 G
4 |1 {! t8 w; _
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */( a% W) g" ~1 x7 O9 U9 d
{
3 Q, P' p1 t2 _. ~8 L) B5 z1 A% O return (ERROR);
8 K* e. A& T5 x( a5 k5 @ }; T% ` Q _6 G. K/ g9 m1 g
& A& f7 w: Z. D6 i F0 Z
tmp = (char*) MEM_ROUND_UP(pPool);
) C* c: X; j/ K) P# ?" K reducePool = tmp - pPool;( @2 r* d4 I; T1 c; R# M! k6 N# X
: T, F% a) o: O& l3 h2 Q! r /* adjust the lenght */
6 y4 K% Z9 m% O5 C- y if(poolSize >= reducePool)
; ^" \8 s) V, W, C& x& u4 F6 e9 Z: V! t {0 |/ p0 L/ g( C# E# L! n" H0 Z
poolSize -= reducePool;
# N* u$ b1 y6 H. } }
# p# M- i, ~% y else
$ U5 L4 l) e; P) h3 _' J1 J$ N {
% n& | I, s. q poolSize = 0;; n! W6 J% E$ g2 v9 b% N
}
4 {5 n$ n. I8 _. k pPool = tmp;
1 b( B4 m# c8 ~" ]7 x
) c% z5 q% Z5 H {) i1 q3 }: `- e, @ poolSize = MEM_ROUND_DOWN(poolSize);) O1 W2 z' P$ Y
0 ~. l& q: Q9 F) v- e% G) h
/* at least one valid free block and three header blocks */) f3 [' E/ F( L% b8 U# n
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
! l8 F9 |( r- F" W1 U {( f- v5 r, ~5 i( s: |! f
return (ERROR);
! J) o" X4 k& I }
* O+ P" o- i h/ v6 J; q) O' D9 O8 R4 R% \
/* initialize three blocks */
) S# y8 |$ m) L$ W& `5 \ pHdrStart = (BLOCK_HDR*)pPool;' F7 D8 {9 {+ T
pHdrStart->prevHdr = NULL;
K g- d; X2 t* ^$ h) V pHdrStart->free = FALSE; /* never in use */
" C. y4 N* c% p! \8 l pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;, q& n2 }3 `/ E! }2 V# W; _
0 @5 N; w0 ^+ a; i# x
pHdrMid = NEXT_HDR(pHdrStart); M! ?) o. _( A
pHdrMid->prevHdr = pHdrStart;
5 l: r ?& w2 ?, g, J8 U d5 Y pHdrMid->free = TRUE; /* the main block */
7 q* r6 i( o6 b1 p o pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;" m h2 ^, ?) T: d9 W1 R
S% l& C7 U; z6 W
pHdrEnd = NEXT_HDR(pHdrMid);4 [+ L+ @* J0 F, `# a0 c
pHdrEnd->prevHdr = pHdrMid;! e( K1 o8 H) g0 u9 H9 e
pHdrEnd->free = FALSE;3 ^- Z2 ~0 j# N. g
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
( a+ {' \0 z. y' d% f6 [5 `0 L. K, w0 o) I
/* TODO take sem hear */
. w8 U3 H, L x0 w2 ? semTake(partId->semPartId, WAIT_FOREVER);+ B& a# v$ e7 q' e
, M8 B+ W& j0 Z5 q dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
' X6 O1 ~8 P: J3 Q' F) H partId->totalWords += (poolSize >> 1);2 G+ A8 o% f+ l8 b4 d8 ^" t
, t' b6 ?3 W- f- y: J6 V% \- Y( ^ /* TODO give sem hear */
: K" G' R/ H" b' ]6 y8 [( e semGive(partId->semPartId);* p/ ?9 Y0 Q: z" W
7 \8 M+ g: E6 M8 f
6 k X) @* t# Q" _3 c return (OK);; S" |5 M$ o% t7 M9 w. m0 q: D
}1 i0 i* k0 m4 e& y0 L B# _7 a
+ K2 C) g) K$ W2 S. p
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
% u& X: n5 M; A' \# Q{# [1 M" o- P1 b- h2 N2 B% @
FAST unsigned nWords;$ a. Y$ E5 _* ~
FAST unsigned nWordsExtra;, G) [5 ?0 h& }
FAST DL_NODE* pNode;, o- v K) f- F! H+ t4 i+ W
FAST BLOCK_HDR* pHdr;
% Q& E/ k# x, C8 ^6 D% x8 x BLOCK_HDR* pNewHdr;( r% w8 s1 O y7 C! c \
BLOCK_HDR* origpHdr;
) Y: B9 o, w$ X& p) q7 Y% ?5 ^' u# j
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ X- J5 }0 `' w5 g" P
{
0 `3 X% g/ N$ K- H5 K return (NULL);
3 r( |2 W" M6 ` n }
! ]+ s$ Y6 V5 _1 |0 }9 P- y
# x2 E8 S$ ~+ L2 M4 d# R nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
8 |$ D$ h' f% F& u% Q2 E( X4 \% v8 Q- ^ \* d. J
if((nWords<<1) < nBytes)
4 g' \& n3 e$ V! c( r {
3 g9 ?$ n& g3 [ o+ V) J6 x. K6 E /* TODO suspend the task */7 o/ W& L! @: \8 h5 w- @) H# T
return (NULL);
+ O' ~# I g$ w' }/ f }$ ]; W; [4 D! [6 ]# H0 o
- o4 {' j+ H8 L
if(nWords < partId->minBlockWords)
' B6 Q* e; e" o: i {
6 _# J5 D0 n. T nWords = partId->minBlockWords;& s) r4 K( w, @# z# a, R
}
# n d& t; v; `1 X* G; D
5 ?1 h) y) V0 X! K1 c4 c3 t /* TODO task the semaphore hear */
+ a c# X! a1 A6 O semTake(partId->semPartId, WAIT_FOREVER); ~- w! k: }! f( |% R
pNode = DLL_FIRST(&partId->freeList);, G+ s( G) k$ [5 f
nWordsExtra = nWords + align/2; /* why? */1 ~! P( k( I* _! E9 v, p" U7 f
* M7 n% o! v) _ for(;;) Z, c& R$ v0 h* U9 h4 i
{6 L9 d) ~7 q( B5 y4 b3 H
while(NULL != pNode)
3 C; ^5 \3 i5 u {
* f. c4 R: I9 I2 ]9 y if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
& }' S, M8 I3 O8 m1 A& [- Q7 T+ ]& R ((NODE_TO_HDR(pNode)->nWords == nWords) && S: V) k5 e% t+ G7 Y' ]
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
0 V' U& `! n, M* ]9 j {0 |: d' K8 R& ?- i: I1 o& N
break;
/ U+ Z4 v6 F* ^ }
+ P0 N+ f$ y! E4 S: ?, a& g+ p! U" x: P' K# ^
pNode = DLL_NEXT(pNode);
' O; P+ |) h( y! y0 Z( u }# f6 b ]# L3 `9 T; `) s
2 q8 z# R( p" M1 _/ E9 K9 h
if(NULL == pNode)
( {6 q* @8 o& T# U {2 T7 b. l0 o/ Z7 C
/*TODO give the semaphore */
% M7 O3 F2 N4 v% t9 V$ @1 }+ r6 s semGive(partId->semPartId);: j* i+ J& w$ k2 p+ n G# B
return NULL;
" F, t5 O7 b+ O: `( C }
$ `" J5 T3 Q) ~# h' S8 k. \% q
5 t3 {: A9 s2 ~* \6 K6 h* I pHdr = NODE_TO_HDR(pNode);
, x7 ^$ |; U; {+ o origpHdr = pHdr;9 o+ P! v3 N- M' U# ^
/ p" `" u/ N( {! v* R
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);& `" |6 a7 j/ J& B" U8 x
if(NULL != pNewHdr)
5 }$ ^9 M$ Q/ E$ z" \ {
+ Q/ x/ e2 E) D" w9 e pHdr = pNewHdr;4 y2 M. p7 g4 k ?8 {+ } Y+ W( |
break;
2 o5 V- u& B, L; u- p1 { }
6 J3 @/ i" H$ R% p
) a9 v3 Y% i. ]9 m5 b2 H. O, q pNode = DLL_NEXT(pNode);9 ]- p" Z" i5 T+ H
}$ p6 c3 j( |- y# \& d- x# y& x
: M% l* t/ f a: s
pHdr->free = FALSE;/ c8 D( Q- s- y+ s
partId->allBlocksAlloc++;4 m8 [- ?7 z! Z
partId->allWordsAlloc += pHdr->nWords;# z8 w! U* H$ A! E# ~) K0 r5 U/ N
partId->curBlocksAlloc++;6 F2 x* J! B3 C4 ~3 e, ?% F7 D6 q
partId->curWordsAlloc += pHdr->nWords;$ D h. p" y9 u1 J$ @
5 L0 j* P+ p" S /*TODO give the semaphore hear */
; [! k' l6 l5 R2 `# ^/ F semGive(partId->semPartId);
% |0 Y% Z: _+ b* t4 S0 _# c return (HDR_TO_BLOCK(pHdr));
: Z" e( x0 x& _
- Q& H! L* H) a0 Z: c! J}
- t T9 {4 A T5 Q: a, w0 \& ~) O# ]; f* g6 V5 \
void* memPartAlloc(FAST PART_ID partId, unsigned bytes). U! t3 j7 {2 t3 ?+ ?
{, k' v" H9 o8 A" X2 C
return memPartAllignedAlloc(partId, bytes, memDefaultAlign); i6 A( ^6 P1 [8 t4 Q
}
/ l* i# J- y6 @; w N% F, h) v
" ]( G _/ O {STATUS memPartFree(PART_ID partId, char* pBlock)2 o' K0 Z; ^ q, F( H/ \
{ I. {( x; ?& n" J* z# k. h; m; f% B
FAST BLOCK_HDR *pHdr;
; Y; g2 `. k- ^ FAST unsigned nWords;6 l" w3 w+ N6 v1 w' K! [
FAST BLOCK_HDR *pNextHdr;
4 T n1 G7 C0 p- |. Z ?1 j' X$ i! [& I
if(!IS_CLASS(partId, memPartClassId))
* m0 Z/ F* M, S8 J {
( b2 X$ M' M* b4 [ return (ERROR);$ C; ` q# ~. ?+ @& k
}
7 N; p4 r: n2 m$ Z& |' g9 r; Y& c4 L
if(NULL == pBlock)
& [! ?0 Q! q( [( Z {
3 Z' }! H% f3 F% g return (OK);1 R3 E" t5 Z* b ~, K
}
- R2 G( z6 P8 T ~+ T# Y
( } Z/ g4 i! E! Y4 e( x( C. A pHdr = BLOCK_TO_HDR(pBlock);
% N6 s: M7 _+ _% T% ?/ J! r/ P7 ^: L9 b$ g$ G7 H/ N! g
semTake(partId->semPartId, WAIT_FOREVER);, P$ d" ]. \/ ?6 T" m4 P5 T: f5 u
: P% L. \. S2 n4 g2 I if((partId->options & MEM_BLOCK_CHECK)9 {5 F+ ~2 o( F$ A) g3 a8 E
&& !memPartBlockIsValid(partId, pHdr, FALSE))
6 k' R! i4 c4 K0 I {
" b/ f7 c) \6 P0 a, s+ I) M1 R semGive(partId->semPartId);# B( o R( y/ ~% Q. ]
return (ERROR);
K1 ~+ t2 s; l4 n; J. d& Q# ]7 Y- | }& u4 d; W" e- b Z5 e
+ ?& A/ g4 G2 V l& a
nWords = pHdr->nWords;: p0 z9 ^% t& g0 Q4 u
if(PREV_HDR(pHdr)->free)* H0 w9 W6 a8 [0 T1 T# }
{/* the prev hdr is free and than coalesce with it */
/ e* v" M& y) t* o3 ` pHdr->free = FALSE;) {. z% D8 W- o0 H" t
pHdr = PREV_HDR(pHdr);
W! ^: @7 a/ ?5 K* N0 z pHdr->nWords += nWords;+ |$ f! }1 P. n
}
" U. C7 c. w3 z$ O+ F! S4 y9 v4 J else1 m! ^' O& S* u) C
{
0 k. `; g3 _- W! C) u! V pHdr->free = TRUE;0 |1 h: ~- z7 C) _1 [% v4 J
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));8 ^3 h' B4 _6 ]0 d: w! y+ l4 D
}
- H$ I7 C% X7 l$ ~* N
& F# V6 g; x% i; x0 t7 f { /* check to coalesce with the next */
9 _$ ^- |+ |+ V {8 m- t/ C; g pNextHdr = NEXT_HDR(pHdr);
. T& t& o9 V7 k if(pNextHdr->free) ~' t# c/ M$ h9 F4 ~
{
9 [1 j/ H: v! Q" [: R& _' W% W pHdr->nWords += pNextHdr->nWords;/ _- [- j B# U8 f! ]
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
3 ^6 k$ p5 p0 f0 [: [9 d }3 u3 o8 A6 N, Q: t* o D
1 Q9 S P9 ^1 \( J- { /* cannot use pNextHdr->prevHdr=pHdr hear */ f: ]- o4 S( h4 d4 @2 ~
NEXT_HDR(pHdr)->prevHdr = pHdr;) M. @; h9 ?& P8 K: b* c+ B# g; A
/ [% B* R1 m1 x. B" Q& c0 @, l/ S7 ] partId->curBlocksAlloc--;
6 U# j$ ~# r3 { partId->curWordsAlloc -= nWords;+ j3 Z( r* ]' \1 T2 P
) T, m# a1 W/ `8 q, [7 b3 O
/* TODO give sem hear */ t. I7 D h. i1 @+ W, J
semGive(partId->semPartId);
. E4 b |7 ]( D( E5 @) p* L5 S
4 ^/ z$ `7 x; w( y. P2 F return (OK);. D. Z% T+ o) L7 }& n
}
. ]- s& v, j2 S9 z0 e
5 A. S0 q( M: |" `$ L3 ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
( T, t. o; e1 k- n/ L/ r{
( Y- B( i- G- C5 t- H; Q BOOL valid;( E) j7 s- I& \7 `" R; N
2 _1 x4 r" n: l2 t: e% I4 a. f TASK_LOCK();" X. D) n( D' ?- \* h- @
semGive(partId->semPartId);
( g% @6 @9 k) {+ T) W 6 b) S+ X3 n/ [
valid = MEM_ALIGNED(pHdr)
' f3 k T8 B H3 ~9 }( I && MEM_ALIGNED(pHdr->nWords*2)
. I. P& ~! S _! t && (pHdr->nWords < partId->totalWords)
; @, |# h: W) G && (pHdr->free == isFree)8 Q# O- S7 f/ d- S# D
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))0 a; ^, d- ?- Q
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
1 p# I y4 ^% g . K7 [3 D, ~( S& O
semTake(partId->semPartId, WAIT_FOREVER);
% m5 B3 Z* I) J5 j' w$ \ TASK_UNLOCK();7 B" u3 E) \- ^& \# i: ~
5 r$ E) Y2 [4 a9 p" I
return valid;' B2 i) Z" w5 W9 K. U. b8 j
}) e2 i" ]( ~6 O
% } s9 L G1 w7 o
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: Y6 i% `( @, B) N
, FAST BLOCK_HDR* pHdr! u' f W$ d# V
, FAST unsigned nWords
M$ w# X- G+ ^0 N6 [7 c0 O , unsigned minWords
/ } h. `% f7 D) a7 y0 E , unsigned align). {% ]; i4 _7 Q2 C
{
6 ~$ I1 V0 ~+ W: M, l+ G+ y) K FAST BLOCK_HDR *pNewHdr;
7 u9 n5 q- `* A |( g; y3 Q FAST BLOCK_HDR *pNextHdr;2 t0 Y( V2 D! T' Z& L2 t H
FAST char *endOfBlock;
! `: v& v1 c5 u/ M% P# f6 R' E FAST char *pNewBlock;9 s; c/ u' j$ V+ c
int blockSize;) K! @) [& D w6 s. M* P4 G5 U) }
( J" [9 Q2 ^# l0 r0 u1 |
endOfBlock = (char*)pHdr + (pHdr->nWords*2);* h( k# I7 e( V) d) ~
1 }# F+ B+ M0 B, \ pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
) s8 H3 y3 B) s* Y4 K
- O2 _- |: g9 E# n- X pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
, w4 D: E% B" `9 k; C) W$ e4 H0 W0 C. J
pNewHdr = BLOCK_TO_HDR(pNewBlock);
3 r0 ?" `7 I! O$ k4 h! H. L2 k- V, w" w+ N* j% p5 B; Y
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;1 N( \) W! i4 s7 {9 [
. n/ t4 c" N S if(blockSize < minWords)* I2 s2 \- F* M. |# {
{
* x& I$ l8 S( q6 y# d; @& c if(pNewHdr == pHdr)
1 A9 v3 j9 \( Z3 {8 v" I! j( ~ {4 C& R9 w1 z( N( n
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
; d& g" [, T# p( i% l }
! S4 g$ L( G: K4 P' a else- {* E* C& k* P' j$ {( n
{3 v3 H2 n" D3 f
return NULL;
3 l7 }" ]- @- l1 `4 f0 \ }
% f- H5 `4 o/ S% \9 V0 p }9 i( E2 N* h$ u/ L8 b) V
else* Q" J }( ~" S
{ /* recaculate pHdr */
3 l1 Y3 x8 S/ u' n8 [ pNewHdr->prevHdr = pHdr;
. |3 m+ I- C; r6 l' V* k t! w9 t pHdr->nWords = blockSize;
- w2 B R B# k; D/ `4 e }
# d; S1 P4 w' i( w" w2 ]8 u& l w- q* I0 Y0 B7 O# t6 z
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)); f$ ?/ l0 \1 f! I8 y
{
2 p- ~, A" r4 p. j8 n% l+ | pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;3 O, D5 e. H$ D# M2 H
pNewHdr->free = TRUE;) t% l# X: p& ^0 M5 k' I' C' d
3 E: V9 s4 Q! b3 N0 V( T NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;% q2 i" v$ ^4 w& J; k( B9 R( ~# N
}% v6 r" ?+ U' K2 |6 d
else
* G: _0 H+ R- I; G1 K {/* space left is enough to be a fragment on the free list then */
7 Y4 y& O+ R: B# V* s: A pNewHdr->nWords = nWords;7 P7 s* q( U1 P9 o9 {
pNewHdr->free = TRUE;
! {( L+ o5 ?; l" m. k2 m6 f6 b9 A
* w1 ?3 z+ T# l pNextHdr = NEXT_HDR(pNewHdr);
1 W0 `1 X. w' o; q /* words 包括BlockHdr */( H9 C! F0 U7 I% L8 E5 W+ o8 [( Y
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 f* v% t, p0 T9 _0 N
pNextHdr->prevHdr = pNewHdr;; J4 R6 a+ }5 J7 D4 r
pNextHdr->free = TRUE;, b0 s) j9 y6 W" Q$ P: s1 c- i
7 Y2 ?8 j* Q& A2 T dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));, M& q) ?" ~# n3 t. Q2 v6 N7 ^- \
. v4 Y ^5 k, G5 k3 n/ q NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;& m6 v- C; U3 u* D' m% t: }
}
* z: o+ _ ]6 C# d( r& \2 D. o ^" Y7 P5 Y
return (pNewHdr);
0 F7 w6 A- {$ F3 E, m5 [3 k. ?}& E5 L& e2 P" {$ I& N u! |
# R- `4 P, v9 @8 O$ d% e1 O
static void memPartSemInit(PART_ID partId)
& t) G: U: v4 L& {* p{9 t+ q5 I, a6 @4 r( s: ]( L5 a
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);0 D; t/ D* S9 W$ D; c
7 c5 f9 J5 R& O5 s9 H8 w/ g partId->semPartId = &semMemSysPartition;
3 I w9 t2 b3 u* `! w}+ b; T! L8 }% ~, ^+ Q, L
! K; y0 ?" a5 E' g4 n
void* malloc(unsigned bytes)
/ \% C" ^& c+ Q/ p- R2 k. j{
4 R: O8 u6 g8 ^ return memPartAlloc(memSysPartId, bytes);
3 S$ h7 |5 Z& Y: Z}& Z2 u+ l- Z) w$ x2 K# B
9 O! t$ u+ T! B( vvoid free(void* p)1 V9 T B" f8 Q* d+ ]1 k% J6 c) g" l, j% i
{1 X, v$ c% a: D* l; H+ S
memPartFree(memSysPartId, (char*)p);
& N! _$ B" y% l" X}
& K0 F$ Q) C/ y% Y- b. c |
zan
|