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