- 在线时间
- 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 b2 g# I! Z* F$ [! L5 }$ q- O) Y$ z e- @' p
8 ]- `; {+ h% Y: A- Q3 L
) _2 ]0 @# b5 L* L: }8 R *\file! e; k- w: a$ K+ K( `6 u- m
*\brief . r, ]9 R8 g* D- O* a
*\details
2 f, N! ?# ]% U; y6 k/ m* F* k! T% N0 B *
0 `3 @# v- j) u) ] *\author Janson
7 h2 G4 S% B4 k *\version Z* @8 i/ f/ G* q
*\date 04Jan12
9 s! r7 ^$ G* r/ d *
3 F; v. `9 \% F1 P7 _* w *\warning
+ ?+ R. F. Z9 N% K% { *
" d, m1 v* [$ H& X9 a: g9 x+ e *\history \arg 30Jan12, Janson, Create the file
( S& }4 X! i8 ~! Q- b( i * modify from VxWorks source
) B$ @+ b h5 k1 A8 H+ b( t2 Y * Legal Declaration: it is for studying VxWorks only.- I, S& g' ?6 B2 `
*/
2 T& R3 X7 s O" T4 I9 O% B9 z5 ~#include "includes.h"
# P @% o! g' z) {& b' i! ^! \7 j; l7 o& w# |
/* The memParLib.h file is hear: } t; N8 w' ]5 X) P
https://code.google.com/p/vxwork ... rivate/memPartLib.h
( d4 o" r E$ ~% \5 w" d1 e*/; {5 m6 J) t. s: `$ s% a
" i( I* F: g, \: n* {7 s3 p/* optional check for bad blocks */
- b* O$ z/ ]& G. s# ]+ s
$ p1 m; d+ }% M+ T+ ]6 e+ c#define MEM_BLOCK_CHECK 0x10; T, e' g. I* |5 O
3 Z j/ f% y* U2 v$ P+ t/* response to errors when allocating memory */5 w5 V- `% ]8 {; E8 X2 F
% i3 l- L3 f$ V1 w' e2 a
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
% u# o4 A0 {& J* p/ H0 H9 d#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40$ o9 @! m; q% r$ L; g
P: w: V9 e' w3 y) g' r- L% C( ^
/* response to errors when freeing memory */. p/ Y5 P) S( P+ O
4 E9 ]! ~1 y. d2 ~5 ^2 k0 _" l#define MEM_BLOCK_ERROR_LOG_FLAG 0x809 Z$ R( l+ E$ N! ]& b3 O9 H, ~
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100- Z: u% X6 y! T' n
; k Z* e5 C0 y. V2 Z G& v
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))" I- \& J7 r( `$ a$ v# a1 u1 {
#define PREV_HDR(pHdr) ((pHdr)->prevHdr)# e- u# k: }, v& ?( x
/ c% M6 l4 x6 ]8 X y! ^3 L
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
; g6 X+ O' A Q% H#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \+ o, q4 a$ Q2 P- M' V% y G' }
sizeof(BLOCK_HDR)))
& C3 y* z2 T7 P ?! K
2 Y# @4 W0 J! ?0 l#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node): Q* i- H! f+ e
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \ z" {$ P, A: s7 E% p) \) z
OFFSET (FREE_BLOCK, node)))
5 {7 j* U0 a& P+ V
+ `9 z6 b. t8 J# j1 Sstatic BOOL memPartLibInstalled = FALSE;0 p6 |4 |2 { V* L
% N5 V. L, f, H, f o. n2 q
static OBJ_CLASS memPartClass;
9 \/ [: f# s6 ^! x% c" q/ fCLASS_ID memPartClassId = &memPartClass;2 y ?2 |; P5 V
1 u1 d! o) \$ r# h$ O8 w- I6 `
static PARTITION memSysPartition;. e W" V' J) w8 S
PART_ID memSysPartId = &memSysPartition;% A" j2 s' m7 S G# p4 ]9 ?
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
& [1 a/ e& w+ [, z9 J2 X4 W4 Z) F& e, x
static SEMAPHORE semMemSysPartition;: p( F: X& I5 Q$ T7 e G! j L4 q
! d& B# W; L' {: z7 r
static void memPartSemInit(PART_ID partId);
1 ^' e! J/ l- `: h& y- y
: c1 f- O A0 b! u: {$ S( B9 e& cFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;+ k. a' ^2 i: _
7 B$ }/ D+ L3 ^
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;8 L8 }& Z+ ~) d4 [
# x" e8 i+ h! S! Kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
4 e* n5 x4 e/ J7 d3 g/ x8 [- istatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
9 ~" Z3 m! k# L8 B m , FAST BLOCK_HDR* pHdr
7 @5 o' T6 O( n4 K , FAST unsigned nWords4 X7 E2 D: ]3 H. }: q" [) }
, unsigned minWords- I0 Z5 ]6 p3 ?4 a
, unsigned align);) y+ `; y# m, m- l- d; o
3 v! M. k% [& }static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
9 ^, T% ^ g$ I* l2 X2 t. P1 I0 W8 g! ~$ a+ F5 U
STATUS memPartLibInit(char* pPool, unsigned poolSize)! U8 q2 ^* K; d N, X9 k, O
{
n9 @5 O. ^- n% N if((!memPartLibInstalled) && & ~0 v; ]) j* k8 D6 j. [: l# ?. D4 m
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)0 `# `! P- K. y5 H
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))( M1 D, E& Z/ M+ b7 }& V
{! q- A/ i3 z7 Y0 G `% d
memPartInit(&memSysPartition, pPool, poolSize); \6 _" u) T3 N9 ?4 _! ~# }
memPartLibInstalled = TRUE;
7 y" f! t5 Q( E: f* v: F' d }
; _1 ]4 [5 Y0 N- o5 X: j+ E0 l& p6 d/ |7 d
return ((memPartLibInstalled)? OK : ERROR);: {1 r" Z$ a" u# a
}& C/ w4 h9 h- h7 s$ B
1 D( \7 y/ A0 Y# wPART_ID memPartCreate(char* pPool, unsigned poolSize); Q1 M" @/ B. Y: k6 W6 }& D; c
{
8 e$ s0 C" M4 h; o5 @/ T; \# T PART_ID pPart = (PART_ID)objAlloc(memPartClassId);! V. ] I* ]6 P, f( A( [# N7 M
8 ~' y8 `4 J: N if(NULL != pPart)6 `& u) H6 F5 y' w, P( h; B% y
{" L7 j' L& @6 Z/ M7 ]5 J
memPartInit(pPart, pPool, poolSize);
" ^! Z, L0 U& Z }5 `/ A- ?" R* z: d m
, ?' y) m$ G; s; p6 ]% @2 y) _" v. ~
return pPart;' g! _! Z) |$ `# M5 d
}. P. ? A& j5 N. ]5 v) y9 }6 x! a
% B7 o% M$ e. ~. u4 B6 \
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
# ~- b' B* @% s. Y{( }2 z8 a6 N$ L7 y! |
memset((void*)partId, 0, sizeof(*partId));
3 M/ j0 y4 {$ T) F3 ?$ Q% f8 j( {+ ?
partId->options = memPartDefaultOption;7 b( X$ r2 [8 s8 U/ L4 P. j9 `- v# T
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */
4 I/ v7 D+ O7 R9 G/ l
( N8 C. h d: Q& U (* memPartSemInitRtn) (partId);/ _0 Q$ k4 N3 [1 ]( n k
; o* t4 ]. a4 C1 u
dllInit(&partId->freeList);
& B3 }3 p# s( B1 P
; a9 c z* l' U7 h- ]# @$ e objCoreInit(&partId->objCore, memPartClassId);+ l P) f) B: ]0 O1 p
4 w5 ]2 L. R: W6 E
memPartAddToPool(partId, pPool, poolSize);9 r2 W) ?1 q' s3 Y3 `
}
$ e' Q0 d# l: l6 t# C6 J2 R6 _& I7 g1 h8 }/ H2 w- K- [
STATUS memPartDestroy(PART_ID partId); k/ \: W! k7 a
{
0 _- ]$ w/ ^! U. U6 D return (ERROR);$ t1 j( f' @9 X9 [) F
}
: v; a7 r# n- R* n, L; e
0 ?1 w" Y, H4 w( o. S' n1 |void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
; c* \; z% C8 ?4 v' x" n( C{" `$ ~( r: `0 s
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);4 r# o7 {1 C4 W7 \& F
}
4 Y4 E& H3 h5 F. _7 i3 {! N1 c& h4 y7 L0 @2 g* w
& S% ?6 h. y0 i. r9 o: F' Vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
, G; K( a8 j! ?% }: N9 n) v{
7 |. L, i" v$ n+ A& ]" ]% O2 k$ x* V BLOCK_HDR* pHdrStart;
, L5 |$ X/ s0 z4 W1 n/ r- {8 ^$ o BLOCK_HDR* pHdrMid;4 h6 w/ n+ {5 b/ @
BLOCK_HDR* pHdrEnd;9 G' ?6 P3 ?' K- f1 I7 @$ w, E
char* tmp;. q# ]* W( v( o
int reducePool;
& U& V" d$ i% D" s( c& Q( I* A* V% ^
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */) b& G& q* `1 E' ^
{
3 I1 G; q6 F# g& t: ^# { return (ERROR);" ^6 z+ n: T! Q7 Q/ e7 K
}
2 @2 Q7 p( d3 N0 B: M% ^/ i( Z$ n- g' J- u g4 m# \' ]! y3 D- {1 u5 w
tmp = (char*) MEM_ROUND_UP(pPool);1 X5 M4 p ~4 e$ C7 n3 J$ s
reducePool = tmp - pPool;
" T5 Y7 q, { {5 a1 ]1 Q. m2 f5 E/ Q' j6 D- n
/* adjust the lenght */
" l) l7 {3 t }( n @ if(poolSize >= reducePool)5 w! f% e6 J$ O
{6 [8 A1 P% P; L9 X* j2 d/ `% v3 d
poolSize -= reducePool;/ B1 m' m: W, A/ i6 T& g
}6 ?7 K) Y" I$ l3 r# u
else
4 q7 L, [/ r1 q- H& F {! b- y: g2 K- l. N
poolSize = 0;, R+ F% q: z2 V w8 {7 M# L9 n
}- `5 G& Z0 U9 {! Y
pPool = tmp;
\, F* y4 L- D
. j" W7 I. q8 f! \( \. p, I poolSize = MEM_ROUND_DOWN(poolSize);
* y3 q) O1 H8 ] e6 _" i
" C9 {! D) e/ ?5 i- i /* at least one valid free block and three header blocks */. a! |5 f" z$ p5 G
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)0 M L" w5 h( k$ M% n
{
7 K" Y7 \; b% g* i5 K9 o return (ERROR);! H: y6 u9 t. y+ S5 T( z
}
9 d G# b4 G: T4 n
5 } M" W) [$ [- {! \ /* initialize three blocks */: Q3 e7 H1 k% x& [( _. N
pHdrStart = (BLOCK_HDR*)pPool;
; L" g: x6 s2 q$ ? pHdrStart->prevHdr = NULL;+ d" S3 R Z. j! T
pHdrStart->free = FALSE; /* never in use */+ x5 {. V2 w4 `% t
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
& C7 f1 I6 W( R" q6 _0 }8 s) S" n) I; Y7 Y V9 u
pHdrMid = NEXT_HDR(pHdrStart);
: n8 A& h3 O3 c+ ^6 l pHdrMid->prevHdr = pHdrStart;& y) d1 w- N. a6 b) G
pHdrMid->free = TRUE; /* the main block */7 {# A8 \: y0 I( V+ U: D- J0 A
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
; M2 b5 B5 |% g4 I
4 n1 n8 d' d( F, a: K8 J' E$ F pHdrEnd = NEXT_HDR(pHdrMid);
! d) g9 N" a* _ pHdrEnd->prevHdr = pHdrMid;
2 g9 v! H1 \# ~! l pHdrEnd->free = FALSE;; F6 |# i7 K% Y- w0 w0 a
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;. b& b( ]6 K2 h5 ^# w; d8 W' u9 x
" ]) w, D% a) h6 F2 Q; V
/* TODO take sem hear */
! ]" G* `# a: p. b- d- a, B9 h semTake(partId->semPartId, WAIT_FOREVER);' {2 v9 U$ }6 o0 q& _- U* ?
f% B( ^1 k* R# u- k
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));! Z1 e, y+ ]8 N/ _# ]
partId->totalWords += (poolSize >> 1);: y# z; @8 |6 r; [$ z$ R6 e- p- I
4 z V; c" L3 m /* TODO give sem hear *// I% A' N& }' U. s$ ]
semGive(partId->semPartId);# ~3 q9 k; A/ n2 u7 E- E
1 q- }) G+ f1 u* M, R5 {, e$ d' P2 n
return (OK);: m p' V3 k7 X# X8 Q7 q4 G
}8 e, l ~) E) s& w# Y
# {& _2 l. Q" N/ V% Mvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
8 ^5 s& O9 o* u{. J7 c+ v- p3 }' c! d+ g* A
FAST unsigned nWords;! v4 z( o! S) E* `6 A. n, b/ Q! `+ i5 u
FAST unsigned nWordsExtra;
# x4 t2 L& _/ O3 H FAST DL_NODE* pNode;) l. P2 }8 F+ N j! x5 D5 t
FAST BLOCK_HDR* pHdr;
- q& R; E1 P; L+ |8 x BLOCK_HDR* pNewHdr;
0 a+ B3 R0 s5 [9 s& O# Z, b BLOCK_HDR* origpHdr; p( n0 [* q. I! O" U( o. l
. \% J' Y0 O( W( T- D- ~' s7 `; G2 m if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */# C% `/ H5 X2 a: z/ R) V, [
{4 v+ D2 S" _) ^; B/ [
return (NULL);( j% j E7 B& t
}4 B, O) [6 _/ k/ e( {2 ?0 b, j
3 A5 P3 q& Y# v' Z) { nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;5 o. O5 _6 s, u) w5 ?& @0 R
6 g! T" F* i, D" T* k5 f if((nWords<<1) < nBytes)" B0 W2 x% o6 j
{9 @, x0 w1 [5 Y( ^
/* TODO suspend the task */! q/ \2 y9 w* h5 ~
return (NULL);! G. b6 b! o- i' {4 G( V
}
/ C& ~) d$ k- O
- Z; D' o# x1 B' a& s7 B) W if(nWords < partId->minBlockWords)
2 U$ p; T# O6 @ {
; M& a) ~% @! s nWords = partId->minBlockWords;7 ]+ U) q* y$ d% x! I: _' ~* G
}7 _1 u. Y5 [! y) y
# w& l3 m# s/ w' e" t9 i1 ? /* TODO task the semaphore hear */8 B6 a9 V; c8 h
semTake(partId->semPartId, WAIT_FOREVER);1 F1 P, w$ a5 E& m- D
pNode = DLL_FIRST(&partId->freeList);; z7 b: ~: O) t% _. C
nWordsExtra = nWords + align/2; /* why? */
/ W! {- ^' ]1 T9 _5 V) ~5 T' L: U, I: Z2 q1 j% z, K8 o) l2 |
for(;;)
# E, X& C# Z1 g9 G; v; r% a Z {* c, s/ E0 n. |
while(NULL != pNode): q) m) Z3 t" q
{
; J7 x& j8 y; M0 Z if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||# R# y, Y! J1 ^, W2 f/ ~
((NODE_TO_HDR(pNode)->nWords == nWords) &&
4 ]' M) z, a* x; T! o (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))$ X8 o; ?+ x2 X/ I% [! D
{
# m) L' o9 R6 \4 E0 Y1 X break;
! Q' a/ b* x, P- ?4 x- u }, ]4 w/ |+ P( D. p9 ^3 u" Z6 s% w
! [8 i1 p1 u+ h. B pNode = DLL_NEXT(pNode);
( r6 ~: e: G9 f }( ^' h$ S/ ~' }
" @% w& S8 ~' @7 x- @9 ~* j if(NULL == pNode)
% y3 w8 y5 M+ U8 h' w. @ {
+ ` t1 d9 G' g/ e! g n6 |, [ /*TODO give the semaphore */
+ J p4 u) g# E+ T semGive(partId->semPartId);
; U0 i; n# _* p( d% W, D return NULL;
8 d u, P+ n, Y$ Y }; G; H" i! u; e5 s
9 W5 j1 H% G! M/ q8 l+ |9 G
pHdr = NODE_TO_HDR(pNode);( ]9 q; |0 M4 u3 A8 q1 ^4 \1 k3 j
origpHdr = pHdr;
# q/ Z/ I( P% |6 ^9 P$ p! E3 H; @( p9 H. H' A0 y$ e5 ~
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
& ?4 E, G7 V6 \7 r# b7 Q if(NULL != pNewHdr)
: A' F) x8 y3 P2 w {" B m) w; p' l4 b) u
pHdr = pNewHdr;
7 O9 {( m8 K, W$ l2 u1 G/ P, K break;6 o. _; J* w2 f
}
3 B6 E, } R& n6 h
5 t1 a7 g6 j% W5 v# F X, O$ L pNode = DLL_NEXT(pNode);
0 u& w. r; M4 E }, }- P6 e* f2 l* U! s5 Q2 b3 R, F
) r" @+ j3 T1 a
pHdr->free = FALSE; G; [/ Y: a7 C$ ?4 I6 N% B
partId->allBlocksAlloc++;+ p1 m) d, m* v
partId->allWordsAlloc += pHdr->nWords;
0 f8 B) ^' C1 _, m3 ] partId->curBlocksAlloc++;
l- ?, {0 s W- |0 q' s6 S- h partId->curWordsAlloc += pHdr->nWords;( Q2 r" P: m2 H) Y+ _
6 Y$ Q$ L8 q* s /*TODO give the semaphore hear */
( L: I2 ?! `0 h+ U& R; l4 w semGive(partId->semPartId);8 F7 S( y5 s. H/ }) G. p2 G
return (HDR_TO_BLOCK(pHdr));
' W/ I* I# ]. y! h' H5 i ' q6 V+ ?1 K3 c5 d7 _$ A% v$ k
}4 ~: n9 l1 L- q, v4 T8 A8 I( t5 v
+ f' b; |4 S [1 x. K- d. }% v: U+ I
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)+ n M8 v8 | W f. g" [# R( f
{
7 o% V" u7 F* B) p return memPartAllignedAlloc(partId, bytes, memDefaultAlign);, ]; [9 n" r: T; C
}# T! m0 T A% y5 g& ^! P4 n
8 \5 ]' V7 s3 E
STATUS memPartFree(PART_ID partId, char* pBlock)
W" J7 A7 j; E; ^) b8 Y{, n' E& ?" C5 h2 x/ z1 p
FAST BLOCK_HDR *pHdr;
3 Z H f- i5 l& ^) ^ FAST unsigned nWords;2 E: H3 c4 ^$ i! C; S3 W3 I
FAST BLOCK_HDR *pNextHdr;: k& n! S' E& l7 l" ]: X# \; l5 L9 c
* d* G* }( q! z9 |: y( @ if(!IS_CLASS(partId, memPartClassId))& ~2 b9 m; W. h( g9 V7 Y1 S( ]
{
$ P3 ~7 d% T3 D7 m! o; _- k+ Z$ v return (ERROR);& @. G2 ]& K: Z9 g0 ^+ F
}
0 n+ Z$ v$ S6 Z8 ~7 r; i! K3 n# L: e, S5 C7 V' E
if(NULL == pBlock) n; A$ b3 {8 z3 P! s
{% `" R0 A0 o* Z8 M
return (OK);( x2 p1 m3 g9 V6 I- V
}8 a3 D( g' a- H+ K+ x2 z
; G: ?: ]* F! ?) m
pHdr = BLOCK_TO_HDR(pBlock);: F: ^, l3 f+ Y/ G
2 [+ B# j5 o$ q. L9 ^2 m; ] semTake(partId->semPartId, WAIT_FOREVER);9 H1 [3 \( g6 j# m
5 H3 p9 e: c* _, l6 |6 X/ s if((partId->options & MEM_BLOCK_CHECK)% J2 r, s1 z. `
&& !memPartBlockIsValid(partId, pHdr, FALSE))2 n9 ]/ d# c+ v, }
{
+ E, g4 f% X, Q) x: _ d semGive(partId->semPartId);
" E0 c/ A8 u5 w- O! P% _/ I return (ERROR);
8 t; I) L* ], v9 S8 j' A' z& c% x }
. d2 D; d T; ~2 @* j# Z0 e$ R: @* S O9 E$ ^. t8 G( k2 ?
nWords = pHdr->nWords;
# a3 X4 J9 D- l! W T if(PREV_HDR(pHdr)->free)! V; I6 a3 G9 K3 G1 E% l
{/* the prev hdr is free and than coalesce with it */5 ?0 ~6 {7 H5 j8 r% l, _
pHdr->free = FALSE;
+ b7 T8 v- X3 o% e( f pHdr = PREV_HDR(pHdr);) w; I0 I0 L( n; \# m9 `/ r& B( j' ?7 @
pHdr->nWords += nWords;
: z5 W8 ?1 X: @ }
: _ {- g# J# K# R0 e7 G else! p0 l4 T7 `6 Q3 T- x
{% P6 }8 V/ j( ^# h
pHdr->free = TRUE;
- v! a H8 B# `4 X* k dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
+ v- u) s0 d+ d& o2 ~: _! m# x& m4 q }- ~0 V. b8 A: D* D. L, k7 C+ H6 L
0 n9 V$ A w# K8 u/ w& f
/* check to coalesce with the next */- a! m9 t$ S$ [' l+ K; U8 _
pNextHdr = NEXT_HDR(pHdr);
$ e+ \/ }" W. ?; [8 q5 H if(pNextHdr->free)+ [. \% |! l4 k6 ~: d; w: q6 I% Z
{
9 s& w+ m! c, F pHdr->nWords += pNextHdr->nWords;
/ U# ~! b4 u* X; w! D dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
' c1 Q3 Z- u/ i" l. G }( T& {( @& `5 ~! `
# C+ i- D X& R; J7 i* m
/* cannot use pNextHdr->prevHdr=pHdr hear */9 B. a# k9 k7 t' `6 o3 S i
NEXT_HDR(pHdr)->prevHdr = pHdr;
8 a1 `9 e6 Q1 i, g
( U6 h9 G# I( t partId->curBlocksAlloc--;
! s; C0 F: _. D6 m1 z8 O0 n% x+ K partId->curWordsAlloc -= nWords;
* a& Q( H* U2 \ Y% y4 b& d6 g2 b# B
/* TODO give sem hear */
, ^1 E1 c* _5 t6 K% Z semGive(partId->semPartId);, I+ n O# A5 s) R3 \- W
" E3 \1 `- z h7 f0 s% I
return (OK);. S3 Z; ~, d! ~% k, B! h. G
}
c' u2 }% B ]! I3 B; l% U7 Q3 b" A% ^/ h E+ |7 R0 c
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
6 d" J, j6 L' t& D1 v' l{
1 q8 }0 g! Y# o6 L P BOOL valid;' A& t I6 r0 c9 o' L7 v& c8 g6 P; d
# s, e( w0 M* ]8 I
TASK_LOCK();
M9 l% t& p9 K4 Z) X semGive(partId->semPartId);4 W1 r- {" W2 k+ S4 D3 V
+ R9 w8 v% M$ [7 E1 ]4 U. C( ?4 ~
valid = MEM_ALIGNED(pHdr)
, d1 a- j& k8 [# |" O) K; ~ && MEM_ALIGNED(pHdr->nWords*2)% |: K* ~# i1 r3 t5 ]- r- w
&& (pHdr->nWords < partId->totalWords) % J( e5 A* m; z
&& (pHdr->free == isFree)6 {+ W. k* h( F& c
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr))) C; s F! N( L' G3 w; |; |3 h
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
' c& z3 l0 }0 S8 |! U 5 s; m$ q: t2 q' a) D
semTake(partId->semPartId, WAIT_FOREVER);9 f2 p9 Y$ I) d# F! b# T
TASK_UNLOCK();
9 ?1 I- s" [: |. j; O% o) O8 X* n9 A0 I
return valid;
! j D+ D( h. {}/ X. i+ v1 w9 [& S( l* ^& {
/ k6 J3 o' c6 s) h% x
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId! h: ?( F% k7 d# D/ E! b: h' E
, FAST BLOCK_HDR* pHdr# `- r6 V9 y+ g: S1 A% C
, FAST unsigned nWords
/ S, Y. f4 W1 \ b' W" c* y , unsigned minWords
) ^/ h4 m( v+ W , unsigned align)
: r5 c. ]7 z/ ]9 v3 U- N3 N5 n{" [9 z, [3 N. x( E
FAST BLOCK_HDR *pNewHdr;
1 i8 F1 a9 c3 F$ x5 ?6 l FAST BLOCK_HDR *pNextHdr;
4 D2 q8 V. H$ d X* Y& ^% J4 Y# n FAST char *endOfBlock;7 a$ f0 g, G- t0 C3 s
FAST char *pNewBlock;0 g0 M. T6 n+ a- _1 _
int blockSize;
) l2 S2 h7 V! `) ?6 c5 a8 t3 [' l- ] K Q9 h
endOfBlock = (char*)pHdr + (pHdr->nWords*2);' `# g' j) n3 A7 C# g" {0 U
8 O- s3 Z; Y, F- x7 e) @% b) c8 f
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));/ t" |# q ^% Z- x6 G! Y
! E) J7 Y: C) C* X6 b4 I+ d pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
9 j8 [2 t" y) g Z
~/ j4 f2 B, ]0 Y0 Y H2 I# d" G pNewHdr = BLOCK_TO_HDR(pNewBlock);2 e/ U( E1 A2 G
$ q; e: H& ?. d blockSize = ((char*)pNewHdr - (char*)pHdr)/2;+ Q% v0 k% W$ o6 G" N! H
0 [+ [- h( [0 R; a6 W p
if(blockSize < minWords)% M" W8 P: m% l" u- V+ {
{/ E7 O: \$ H- }6 ]( x
if(pNewHdr == pHdr)
s' H! x) r Q( [8 ? z" f( ?0 Z {$ o$ _0 ~- j7 T ]
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
/ I: _; e8 G3 v/ X/ k }
" k* x2 i, E$ G) G3 [* o else
% m. e6 b2 G- B, G0 {' Z {3 W$ V$ I" t5 ~* y
return NULL;
5 K! r( G* P+ L$ N }6 K; K' O: Q \3 b8 \# @
}
* A, F/ U S# l9 H else
9 I* x; h4 {7 u { /* recaculate pHdr *// a i" x# J* E& Q% K! e
pNewHdr->prevHdr = pHdr;
* L/ S" q$ X9 L' D3 Z5 W% n pHdr->nWords = blockSize;
0 Z8 A- ]; n8 _. X0 [$ }" P }
' @ C* _" P: Z, q+ _- \
9 a2 v8 s Q, X if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)), d! w1 N& a& x' E( w! _
{
: o$ N1 e; \0 ]5 z+ C2 J pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;, e# ~8 Z. l" U
pNewHdr->free = TRUE;
! b, r# V; W2 h3 M! b! ~
- \) t9 Z, g7 ]' Y, n5 V NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
: z, F0 e. L8 ?, { }1 T3 p) _! Y! R8 d
else
1 @; N& t" v, f2 J8 Q4 f {/* space left is enough to be a fragment on the free list then */
& r [6 D$ [* P pNewHdr->nWords = nWords;
7 G; Y3 W' Y t6 [8 _' B pNewHdr->free = TRUE;
7 P% L" {& F D3 Y% P7 F+ k. y' @$ L1 E1 S
pNextHdr = NEXT_HDR(pNewHdr);/ s6 k- A& I* u p. o
/* words 包括BlockHdr */ h/ u K! i* M( u4 a7 E6 ~0 k8 Z
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
* }7 L( c. _6 k* _ pNextHdr->prevHdr = pNewHdr;4 j( n" P; Z/ x, I
pNextHdr->free = TRUE;
, O( k: X q5 s5 T; w' P3 d1 K, }3 E# x9 I" G
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
/ N7 f. v1 v) Y, H6 b9 i- }# l% X0 [5 L
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr; c x1 X u7 D5 {, Q8 w. c
}, |! R7 z$ ^4 n
# z4 S, I2 \* A& [2 s4 Q return (pNewHdr);; h- L! x4 ]5 W H
}
: E* i; i. C3 r& P* P* T$ T+ ^5 ^" R
static void memPartSemInit(PART_ID partId)# h9 X% q& k% W( G% N* t, E& Z
{
( S, w' F3 y) H- Q semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
8 S* P a1 |% e9 g5 r U3 f- k# n) O1 _0 b) A- K, O2 A
partId->semPartId = &semMemSysPartition;
- K B4 u! g1 ~9 W% _}, |8 o* }/ @0 l" x8 ]' F
. O0 t0 r- _1 Y8 `: X% [& I% ~5 m0 bvoid* malloc(unsigned bytes)
5 y8 y5 B0 ^+ o0 P& M; J" g3 L{, n, J8 |0 X3 S, V- ^
return memPartAlloc(memSysPartId, bytes);
4 ^. P4 B" r t. E9 x}
) f+ x/ W) `+ ~7 z
4 e+ j; J3 N. O) i# {- Yvoid free(void* p)1 C# c% k; D; h2 l( e' F$ ]
{
1 I% k9 g' G1 h7 Z5 ~5 o memPartFree(memSysPartId, (char*)p);
5 r$ B7 m! R7 @. d7 c# J}! O) F1 F |9 E. v* T0 a
|
zan
|