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