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