在线时间 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++下的版本,更方便调试。有需要请留言1 E+ | W5 E) P3 Z/ F
; w7 B0 o* o; p. i
# ^" y! ]1 n' e5 z: w% W
0 w! z" U6 x7 s4 D; X( w9 V *\file
7 F3 {8 Q q' w *\brief 6 ~+ w* d( y3 W( |
*\details
, m$ Z1 v1 S3 H *( s' `9 Y3 \! _ [- N
*\author Janson3 Z. Z2 @9 \/ ?5 B
*\version 2 t( y7 a: N, D$ c# H" K
*\date 04Jan122 k. \, ]6 s6 s5 z: _- U( O
*
0 q; x7 M& Q2 {$ k *\warning ; v5 z; T( a* E
*+ W) {6 o* k$ A- Y( ^
*\history \arg 30Jan12, Janson, Create the file
! I% ~! d' b9 ?7 u1 g* Q * modify from VxWorks source
, }) @, Z1 n, H& M+ Z( N * Legal Declaration: it is for studying VxWorks only.* i3 p7 a/ @0 j# Q% {& l
*/& F G3 b9 u8 ?
#include "includes.h"
+ O3 P) U- h- m8 @! p! C R9 h * N( S, S( D, ^5 w
/* The memParLib.h file is hear:
- p" c" A O, L https://code.google.com/p/vxwork ... rivate/memPartLib.h
8 U+ K4 B4 W+ M7 f& j */
3 P- ]# ]4 P$ \4 ]0 P: w& b: D* V
/ X' Z8 v3 l( M# X& |; F4 M /* optional check for bad blocks */8 Y- R" b; e; q" h0 N/ I
% O, v9 c( e% W( Y
#define MEM_BLOCK_CHECK 0x10
1 n$ L: S3 w+ I
* b, L% z# d0 c( ?3 w" O /* response to errors when allocating memory */( g/ c$ M' B0 N& M- X4 j1 e
! y5 p8 w: r6 ?" C9 K+ ?, E
#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
8 a8 x" I2 K# P% ~1 ^' ~ #define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40
, Y9 z; y8 p6 v: N; u
* Z: {: F( ]+ z$ {: X# ]$ R) | /* response to errors when freeing memory */
$ R/ L& U: J4 L X ' _( a6 J: N; L! v
#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
3 o. n% y( ^: J; C #define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100; M0 j! T$ E K. _& F
+ G' [: B7 S4 ?% \, i
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))2 Q. j4 P$ G& c
#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
4 M* l, _0 |: D7 h' ]: j' h9 L
Y) e/ @1 A+ G* z5 l ]3 u #define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))- a6 ~' W0 T0 x: r Z
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \' d" S( k8 I6 o6 }8 I& ?9 A, {5 _! G
sizeof(BLOCK_HDR)))
7 F$ R$ g4 a9 U& j6 V F5 Z* |+ x. s2 A" X
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
" W- N4 s) R/ S9 S" V- j$ J #define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \
( ~( n' s, m! U! |. a OFFSET (FREE_BLOCK, node)))6 j/ v) u' R8 e. @6 m/ |, [
1 t" w" n. h* V; |* L1 P8 P static BOOL memPartLibInstalled = FALSE;/ F$ N9 @5 n/ M
: A$ H# h) j, |+ w% }% v( u8 _ static OBJ_CLASS memPartClass;# F' g4 V& G6 ]/ U# T+ `: T
CLASS_ID memPartClassId = &memPartClass;
, {* T; a/ I& {( Y5 Q& ]
J6 m8 R& C" _# k; A9 X# x7 Q8 X static PARTITION memSysPartition;$ ^0 G1 L$ d3 W
PART_ID memSysPartId = &memSysPartition;
( o" w, _" k+ o0 y1 D6 l) { U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
) _ l# V4 q, T/ I2 ~9 h0 E8 {! D/ r 9 N1 [8 z" ?1 z- s
static SEMAPHORE semMemSysPartition;
6 N% r$ k) k2 s6 E1 z : p/ ]7 ?7 Z, P- F( u& e
static void memPartSemInit(PART_ID partId);
3 J$ ^2 ?$ W7 W: [' m q+ y % e9 n8 S2 M! @8 Y8 Q
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
. ^2 L6 D# ~' f" a8 W2 s - ?2 L7 b- w. Q5 b% g4 x% x
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;' q# M+ G) I+ |
. E: A$ ]7 x" U static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);- O0 T v4 d. A3 N% k1 x
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
& ^+ H+ d z# _5 S1 n8 ]7 a" E. b , FAST BLOCK_HDR* pHdr5 {- {) m6 N/ r9 `
, FAST unsigned nWords
2 C# B/ w9 m D% u , unsigned minWords( k9 c+ h4 J# ]- h2 b. @3 W/ H
, unsigned align);9 Y! X0 J. D: G4 G& F0 h2 n
/ n9 Z+ k3 N% b2 ~
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
, T% H$ |& P- T$ a" Q ( j' I. j% F3 J9 u( X. k3 Z
STATUS memPartLibInit(char* pPool, unsigned poolSize)/ q+ q. F A7 S# I; o$ I
{
7 h1 N- h, C9 V if((!memPartLibInstalled) && 3 E/ ^/ s8 f' Y8 h" d
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)' M! e0 E, b# b
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))! r* _- @5 j) z4 P" r* Y" l& J
{; \, j$ s$ v* _3 L% S9 A
memPartInit(&memSysPartition, pPool, poolSize);
0 [ l; w" E( S, F! E/ I7 q; _1 r memPartLibInstalled = TRUE;3 F$ }* B8 i/ ]5 t6 F
}5 h6 ?& H& H# I
7 U4 K. e- ~0 E; K. B/ n ^* J+ l return ((memPartLibInstalled)? OK : ERROR);5 E6 t0 ?" Z! E6 C
}( U* O% C+ U' M. s( r/ l6 ]
! o$ q1 G" ^) f3 U" c PART_ID memPartCreate(char* pPool, unsigned poolSize)
1 P9 X% S+ F p: n& K; o2 A- w {
3 x2 V" \- n8 v, Y W PART_ID pPart = (PART_ID)objAlloc(memPartClassId);) \3 y% L4 f4 z Y3 j* S
6 d2 d3 b3 I9 H2 S, l! w# Y5 ?. S) F
if(NULL != pPart)
3 d& i0 r! J# o {% N' W- e, y" w1 d" X. `' ?2 p3 n
memPartInit(pPart, pPool, poolSize);- K1 s: ]6 v6 B3 b* q1 ?7 z
}
4 i/ I9 w5 x$ d: @6 F; { 6 y5 Z" ], F# l" ` \3 }
return pPart;
& F. H0 z+ h* F2 C* z% [7 _ }
& F* P% y4 j/ c% v
Q4 n7 s0 q3 O2 W0 R void memPartInit(PART_ID partId, char* pPool, unsigned poolSize), k- p7 o2 t1 E1 p$ U' f
{5 [) i& y# t! F7 C9 p
memset((void*)partId, 0, sizeof(*partId));1 X, s! Y+ [5 \" `' m4 _
: D2 V1 j3 q! y; x
partId->options = memPartDefaultOption;
9 x0 a3 l2 g2 L, i* t. ? partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */
) ~: T& d. [" q1 e" d' U + H0 _( p, O a( ]
(* memPartSemInitRtn) (partId);
, ]) ]4 S3 U# h3 @$ Y
% P6 P! `7 V5 Y) x+ @ dllInit(&partId->freeList);' `! E8 |6 C! V+ W" p& z+ z
& u7 ?4 n& }* X! ?8 Z( |% e objCoreInit(&partId->objCore, memPartClassId);
c/ ?. K. q( W p7 f% L% j" S
. O% K( C3 w7 U# B& \1 |7 Y memPartAddToPool(partId, pPool, poolSize);1 l( k+ _. @; c" V9 J
}
% L; h5 Y+ Q [
+ K6 I6 {* J+ V7 y STATUS memPartDestroy(PART_ID partId)1 {9 I3 Z2 W0 {: F @; P
{
' F* e/ { v- y% q% g7 S return (ERROR);1 Y4 K/ S c' O8 O" [6 l
}
: Y3 n2 q9 _/ K- W & W( V8 p. Y0 H% N
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)7 |1 w' B: t* S% }3 s3 R
{" J) K7 N! L! j& B( s7 ?
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);
* U. z5 k$ S Q& k8 P }
5 \: q8 C& z/ |; X8 i 5 q+ ~0 ?) `+ S& P
$ z1 C1 ]2 `+ i3 b' O static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)% _# X" g) h5 ~- u' t, S' E
{, T, ^- U2 E7 T4 y! [
BLOCK_HDR* pHdrStart;
5 X" p2 F7 a6 s& s0 ?3 e | BLOCK_HDR* pHdrMid;+ C J: Y. Y8 |8 W) V
BLOCK_HDR* pHdrEnd;8 {$ |/ ~; V9 }+ S. h9 s
char* tmp;
I: s3 C$ k/ e! T" m+ h6 ?* t- e int reducePool;
0 Z% v8 ?+ {7 j# m2 O0 Y6 n$ o
- k+ M0 m9 q0 O. F7 w. H if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */; [) p M4 V7 R+ h; s, Y9 r
{! {* ^5 Q. j0 ?& {3 ?2 d/ Z A
return (ERROR);
2 r8 r# @/ y* `+ v0 X f* h }4 v3 `+ l3 w' U$ q( b
' f" ^) w- B% K3 H- }, U7 `6 {% n tmp = (char*) MEM_ROUND_UP(pPool);- r3 J$ e# L7 Y& a
reducePool = tmp - pPool;
4 }! y+ t# V$ V + B! ~# X' j n1 K8 F
/* adjust the lenght */( l- r0 ?6 _* [& t ]+ T1 J# F+ A
if(poolSize >= reducePool). d' F* G8 _, L p
{
# u& j8 H" h) h: m, M# a/ ~ poolSize -= reducePool;
/ j3 G/ V3 {0 R% V2 R" d* u }
/ {# p6 m) R# G0 [ Z else
) ^# u8 g& t$ B; I3 I: r {
/ O* z, b& n) c2 g: Y poolSize = 0;
9 C5 e6 m$ v& e# f }
% P" l0 A! O+ u9 s& ~- d- F" G- h; h pPool = tmp;; M8 c8 }1 U0 q
. f B' Y9 h6 W- L poolSize = MEM_ROUND_DOWN(poolSize);
) y7 o; J9 T' E9 l& O5 `5 ^& R * J+ g0 C) N2 [5 y: x( u. _4 Y
/* at least one valid free block and three header blocks */
& D: a2 j5 S N( t+ r if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize); p( K/ L& \' V8 I: ^4 ^
{! f' V8 w: k- t2 v# G& S
return (ERROR);
& t: I" ]7 S/ {$ s }
( g" E* A6 m! G5 Q
" g0 m- [# K. x7 n. |+ G' `# p, H /* initialize three blocks */
+ i: J3 G% [9 B u, T* ?3 P! S pHdrStart = (BLOCK_HDR*)pPool;) {5 X6 ~6 M" s* t2 S; N. \ V
pHdrStart->prevHdr = NULL;
) a9 I! [& M9 x2 ~! Z pHdrStart->free = FALSE; /* never in use */5 ?$ W# j* G) k( U0 s
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;% g0 D; q$ u, U9 Z3 x
0 M# Z" A7 x; v! i0 u pHdrMid = NEXT_HDR(pHdrStart);
( ?& P) A5 v! B+ Q: M9 ^, s i, ` pHdrMid->prevHdr = pHdrStart;
* i& v; B# v6 v m- h pHdrMid->free = TRUE; /* the main block */ l. m) ^5 t4 y* F% ]
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
_. }" V# R5 t
q7 R/ f) w' N! y- ~ pHdrEnd = NEXT_HDR(pHdrMid);
; b, w) K( e; a+ S5 }- K* r7 r pHdrEnd->prevHdr = pHdrMid;
" H X2 d. S3 H9 ~! M pHdrEnd->free = FALSE; r; I( b5 p5 j. x( q
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
1 J, n: F$ ^& r) ? # n0 c6 ^. V3 W4 a6 N
/* TODO take sem hear */+ h. ~8 `" G# M" n
semTake(partId->semPartId, WAIT_FOREVER);( [' N! S0 i( o, X. a2 c7 L, v
; ~( Y+ L. H- N! \% s4 \ dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));3 ~0 t; q% M( ~/ i7 G
partId->totalWords += (poolSize >> 1);
N& q9 x/ q5 Q) \: x& w8 D
4 O5 V% P" v. h /* TODO give sem hear *// \* f' ]5 [$ p8 F7 N1 m3 n7 u% h
semGive(partId->semPartId);
/ v& p: A Y' x% s: w
. i, M, Q, P% D' K% J
$ @% L3 Z% S* o8 u) b% S$ D return (OK);6 c8 q0 c9 C2 s; f" o$ h {$ ?
}) a8 l9 s$ N+ S6 f4 @5 M1 U$ v
" Z7 O0 S' u" i6 w' \) W4 T void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)1 F8 M7 A# Y& o2 B: p5 \" r
{
- K/ x5 o' _: K% _! ^+ g FAST unsigned nWords;
5 E& c- f; Y7 m FAST unsigned nWordsExtra;
* f* V" v( ^! ^3 R2 d FAST DL_NODE* pNode;) W( r' C. s7 g) w$ x' M d
FAST BLOCK_HDR* pHdr;. h9 G* h6 S% t; i1 ? t
BLOCK_HDR* pNewHdr;; M0 b5 _. A! t0 |% P! G( ]
BLOCK_HDR* origpHdr;( V& [7 Z. w/ @2 E
0 f& h9 ]- C) K" v
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */% @5 \# k# Q% v6 k# _
{; i4 S7 U8 i8 ~- {! ?
return (NULL);
`/ A! S- u4 ?" l4 R$ K5 y& Z }( V% M* I7 D! O1 o0 `
6 t: m) E8 |2 j nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;3 m, I* l5 X N( D2 D- `/ e- W8 y9 C
: m( m' H/ @/ U- i0 x& K$ b: @3 D* k
if((nWords<<1) < nBytes)( k7 u- V5 k0 K2 E/ x& A. V
{; Q& G$ w. x9 q8 B& q
/* TODO suspend the task */
# L; f8 j9 M5 ^+ d return (NULL);
- L# [) N! E0 V" g2 ^0 ] }
6 D5 z2 p A; z6 I Q9 U/ U3 G" D1 t , H0 j+ [/ a$ L
if(nWords < partId->minBlockWords): v6 F, K2 s5 y; a5 J; K
{) m" `' o- i2 ], n
nWords = partId->minBlockWords;) n( D b! Z; x. W
}
" _: _- G4 W# c+ Y
; w! {# e: _6 s7 Z6 B /* TODO task the semaphore hear */
3 I4 Y# [% r& u/ V! g& W semTake(partId->semPartId, WAIT_FOREVER);
/ e6 E7 ]0 |7 l _# y: ^! q" _ pNode = DLL_FIRST(&partId->freeList);
: p5 j1 ~6 n( u nWordsExtra = nWords + align/2; /* why? */
; B5 k5 s7 Q; R' r% S1 m
: e0 e( I! ^0 Q9 i5 A$ s) y a for(;;)
) F7 d) |% T3 p9 o9 u {/ {. L7 O: O" g; g8 N' H
while(NULL != pNode)
4 V2 Z+ X& B) F5 S" s {! W* F+ W/ @" S' q0 ^. d& ?7 L7 u
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||7 Q4 M: M. k: y. M. g5 l1 ~
((NODE_TO_HDR(pNode)->nWords == nWords) && : u. ? S; Q# R0 L( U; n1 A7 T
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
$ X- a4 A2 k3 ^: B/ D$ ~! Q$ }% C. R {4 ~5 G; \* J7 r; C& @1 o& |
break;8 x' f+ i' c2 }6 ^3 t9 t0 F ~ \$ D
}
# ]" O8 D. P* h* y6 z 4 b3 m* ^. s' y& G: j/ [
pNode = DLL_NEXT(pNode);3 O2 E1 u7 g% n9 E* X( l& b
}7 S1 P. G% h4 ]* E! ?7 {+ Y. C
: K& O" O8 S3 y) Z" C5 Z: v* k if(NULL == pNode). }6 H" c" @) `! m3 f' d' A1 a
{2 k. @# P. r1 [" ^
/*TODO give the semaphore */# b8 N6 A6 c9 G
semGive(partId->semPartId);2 o; d- S4 O3 b2 A
return NULL;
}& h: r. m- T$ P, S }# G5 p$ [* Q! ^4 `3 }
1 B. o2 E4 Z' i. U; n B$ K) t
pHdr = NODE_TO_HDR(pNode);% T) l% o6 ~6 v+ A+ I; H: b
origpHdr = pHdr;
2 }* a( c$ D( u6 g. j. H# R
S' w6 N8 \; v9 Q( T& G pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);% u" c! h4 A3 i% i+ J6 k! s$ p
if(NULL != pNewHdr)
" ~* v/ ?. a& \ {( i( _* ~: K! C( E- h
pHdr = pNewHdr;( V0 U4 E W# G3 V0 X( z
break;
5 F! G T/ _! J% w' W, E }
+ g4 o$ ]- J! a 3 D3 w- }* ^7 i; G' B* p
pNode = DLL_NEXT(pNode);
+ ^$ F: ^$ a" E- B3 d }0 j0 B+ g) W. g8 P& K
0 |' J+ Y% C7 Z) f) Q pHdr->free = FALSE;
2 F: O* f/ x! Q% j$ `6 a partId->allBlocksAlloc++;
0 ?7 M: Z: S c/ ` j* { partId->allWordsAlloc += pHdr->nWords;/ [- b) A1 F$ E, x% s
partId->curBlocksAlloc++;2 N$ T d9 R: L, A
partId->curWordsAlloc += pHdr->nWords; b+ e) K0 p5 F/ e p' Y" F
: v! v% f+ r# ]9 D2 @% W7 s' I& i
/*TODO give the semaphore hear */5 x5 N% J& G9 M& ?
semGive(partId->semPartId);8 z" t# e" m c" @; F& n+ e K/ s$ S
return (HDR_TO_BLOCK(pHdr));
7 c1 U. Q/ _" `& Z0 w# O( H 6 C" N# ]+ k/ R1 I* `5 L+ w
}0 a" A* s, U. D+ u' m
' ^, c5 a5 s) R! m, e- C
void* memPartAlloc(FAST PART_ID partId, unsigned bytes); Z& L$ w$ q# s4 c) S; i/ ?# z
{! A, I, J' t. V$ K c4 F' c
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);" C3 d& G/ G! E% p3 v
}0 J2 t; Z, V: @
# j' v+ E1 J0 Y1 _" x
STATUS memPartFree(PART_ID partId, char* pBlock)4 ^; E) W8 {2 h' O$ R
{1 K4 P3 u& ~* X3 _7 u/ T
FAST BLOCK_HDR *pHdr;
+ j+ G1 ?1 }- X FAST unsigned nWords;/ R n" z9 \- W3 F. C
FAST BLOCK_HDR *pNextHdr;
% `" [) U9 P+ m" u $ U1 N* F$ d" S0 _" y8 `! y$ }
if(!IS_CLASS(partId, memPartClassId))! P2 C$ q9 S% m% P# N% A
{
. m% |; c" [2 t% y) G return (ERROR);8 \' t4 }( D3 l- }) S
}
7 x/ I1 K6 g! C' A4 V# ^ 6 \9 R! B- `$ g$ @
if(NULL == pBlock)$ ~* _- s* R( l
{
( }9 V9 m1 v9 T4 d. m8 } return (OK);- x$ G& \' a* h6 P/ C$ e$ C# C
}
; x8 q1 K% \+ O: O
1 j# ]+ H6 G: |9 S$ v" x2 G x pHdr = BLOCK_TO_HDR(pBlock);
( j/ l; N6 y( j! R
; y: `2 ^* j6 O5 f _+ c$ C semTake(partId->semPartId, WAIT_FOREVER);9 S1 j6 z j* O# V3 K! i1 j
0 g6 n' K6 m: C" o- w* n
if((partId->options & MEM_BLOCK_CHECK)
( t8 Q' t% n0 C* a* k && !memPartBlockIsValid(partId, pHdr, FALSE)): @. e' K# k+ G4 s h7 C
{
+ T' N+ i7 p4 ]0 W, Z3 o+ W semGive(partId->semPartId);
0 y; }/ d% T& p# t4 e$ ^ return (ERROR);
+ D3 ^2 d0 X' [ }
0 a( C# J( Y( ]1 P6 [ : L- |3 W9 k8 {4 _& W
nWords = pHdr->nWords;
/ n$ [7 d" _8 E. K4 p if(PREV_HDR(pHdr)->free)
! O7 ]9 H+ a& O {/* the prev hdr is free and than coalesce with it */
' z1 B/ Q/ v" l2 F! G3 M pHdr->free = FALSE;
6 ]3 y6 O' Z( j, B1 Q" P; U pHdr = PREV_HDR(pHdr);' H. z; W. E. y2 X7 C( Y
pHdr->nWords += nWords;
$ m& ?3 u; E1 ?" a: E H }
! N! y, W, R2 H% m+ x1 a: R1 Y else: c3 Z5 ? a* s0 r
{
x" }/ r" d% i. ^1 X pHdr->free = TRUE;) Y# \) m4 ]# [/ ^3 t
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
! Q" _; U2 I$ K }
8 w1 L1 A( S! e+ P2 T4 K p& D H' i6 Q1 J$ T& R* H
/* check to coalesce with the next */; g8 `3 c) w) o6 M; F7 p: K( M
pNextHdr = NEXT_HDR(pHdr);
: h& T4 E2 A3 \ if(pNextHdr->free)
, G6 @3 \! m! C" M {: X. |: a) x) m( [' X( W) Y$ P
pHdr->nWords += pNextHdr->nWords;
, x7 Y. |4 J2 P5 K5 a4 _ dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));; _8 X2 z9 s6 u0 h0 w2 D) v5 {, q
}
% K( t, ?4 h5 y5 P / E1 H. f5 ^# G1 I9 }% |2 x
/* cannot use pNextHdr->prevHdr=pHdr hear */
6 y6 `& h9 u$ L/ J NEXT_HDR(pHdr)->prevHdr = pHdr;
- q9 [, t' X: s4 K8 w" Y ! X1 {/ P$ W5 w7 W) z, M( n
partId->curBlocksAlloc--;
% `" M. ?1 R' @0 z! v9 _ partId->curWordsAlloc -= nWords;
{/ z. e0 v( v2 C$ N9 }4 q
5 f$ m! L. b- k /* TODO give sem hear */- q; z8 A% r0 Y
semGive(partId->semPartId);( a" W% {! W' h8 ~% H1 A
. ~% ?. r( D; [" W8 N" R0 P7 ^
return (OK);
- \! b6 D$ {. ^9 ~- e* P }. Z& ^5 M0 o1 P% p/ |1 @8 j
. k1 ]" i' F& l9 C5 |5 v
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
* D6 f3 q* k6 R% `/ C, C2 E {) [2 a3 V' a( U" c& F5 t
BOOL valid;
* u+ B. O2 d, f1 |2 J , x) i: M% g) k
TASK_LOCK();
! O! Z) G- [4 w1 C semGive(partId->semPartId);" f5 a0 i! m! n7 Q- X
( _7 a. f/ o/ a/ w
valid = MEM_ALIGNED(pHdr)( E2 b7 f' v6 Q8 P8 t
&& MEM_ALIGNED(pHdr->nWords*2), c5 `1 G. O( X8 W
&& (pHdr->nWords < partId->totalWords) ) W7 l8 j; r4 ]/ |1 [
&& (pHdr->free == isFree)
4 }+ | Q) Y- r && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
) d% D. e; m+ y) l && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
' q9 I8 x _& _$ r' E8 l , I4 ~$ s5 n& h( P' D! }
semTake(partId->semPartId, WAIT_FOREVER);
3 ~' s1 w. D6 i' O% k# r: I TASK_UNLOCK();1 M- z% f# O) @ l0 i* ]
+ W# {1 c9 r- Z' q& d
return valid;
. F0 F, c+ }+ K }' o2 i* V0 Y5 p
" a6 ~1 ^) x4 D: o9 F6 W
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
- j3 K5 P* ^" Y1 b , FAST BLOCK_HDR* pHdr
$ X( h# u! I' Y Z5 y , FAST unsigned nWords
l, P7 ^- d/ W4 B$ f" t& @ , unsigned minWords
+ D3 O1 N2 f* @ C/ `1 g , unsigned align)
2 Z9 C3 T. {- m, L. _ {
- ^4 @% v7 e& p' p/ k6 o0 z' j FAST BLOCK_HDR *pNewHdr;
$ U1 e3 C2 I, y7 }- }2 t) a. I! N FAST BLOCK_HDR *pNextHdr;
; `9 j, ]# L: C% U* D# F" i' W FAST char *endOfBlock;; E& P6 t3 a) ]8 E
FAST char *pNewBlock;# u4 v' S) D# |8 Y, q0 F
int blockSize;
& E, ^5 h8 r! s$ Y( t : L/ F/ T p6 n1 D) E/ |
endOfBlock = (char*)pHdr + (pHdr->nWords*2);
! [8 Q( ]2 n4 I1 G
/ y" \/ }% N; m# A s pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
! k6 T" a- [$ m 6 l: X R# c) ]. C" q
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));6 u3 Z- T1 ]. I6 Q! W! B" t6 R- P
c2 I! L7 b% y+ t( S9 y0 q pNewHdr = BLOCK_TO_HDR(pNewBlock);
5 T. B$ N3 ]$ {0 P' y0 [9 {9 q; ?9 g + S; [0 f5 m3 t) y: @7 Q
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;* `4 A8 ^2 J' v; N+ y9 @& z; g
1 I0 R; {# F t3 u if(blockSize < minWords)! W# z5 ^2 g7 k& w% \, Q& K% h
{, |7 [5 [* @2 O0 J% M: V+ ? `0 R
if(pNewHdr == pHdr)5 U0 `* \% f: h( _" D7 E! {, y
{
/ R* n7 f2 T* e0 e6 W dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));6 j1 z2 d6 {0 d# P2 ]+ l
}0 U/ N/ s" d0 K- b5 \* z, r1 o
else' [3 ?) A4 F7 _- W+ S
{( ^( D6 ?& [9 U
return NULL;
4 ?' m- j& ]" x* O; M3 {3 e; b }
( z' U0 f: W2 e* O+ n M }
5 e$ d- X! ]" D$ Q8 j# Y- c" B else
6 w3 P' ^8 h4 A- U; f { /* recaculate pHdr */) a+ d. ~ Z% l+ }
pNewHdr->prevHdr = pHdr; p/ p8 p' w; q7 z1 W
pHdr->nWords = blockSize;) v1 O0 z/ }3 s8 r- b. u! g2 Z
} \4 u( o6 ^3 K6 C) ^! K
r) ?) K4 _9 i; L0 U9 ] if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))/ ?; o+ x& Z0 v$ Q% @; w. S! Z$ }$ n
{, L3 B8 l; |) ]; p- K$ e
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;8 n m3 ^. d/ } V$ [9 `
pNewHdr->free = TRUE;2 h1 j. B% J! _; [ V* c' n
- y0 @. I5 m" \# }8 x/ x4 }4 s9 Y NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
5 J3 k' Z1 a! Q* H8 I4 _ }5 f: C d: C# m+ H
else
( u& o1 V, {) B0 c! v6 @) O {/* space left is enough to be a fragment on the free list then */
. @8 A- z: C0 i% W9 h, W$ z* E pNewHdr->nWords = nWords;6 g, u7 b; c, q) X
pNewHdr->free = TRUE;
$ P" T0 H b& B0 ~ 4 q2 m) P* x: v# d3 E1 D, y
pNextHdr = NEXT_HDR(pNewHdr);
) B6 M$ i* `% f2 k) H; A /* words 包括BlockHdr */
|' {& R* U% W0 w3 n pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;, b! ]0 }* C+ d c
pNextHdr->prevHdr = pNewHdr;
( Q" J- m: K$ r- q pNextHdr->free = TRUE;
# H2 B3 m/ A( S( |9 d % {# K+ l$ K0 X/ q3 E
dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
/ y3 c" p Z# h1 R4 |! F5 f
8 h9 E# I0 i( n8 |) O0 { NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
; o* ]2 m0 f4 B0 ? }
; {( R* [& n& w ; U6 k$ R/ w5 A9 e4 h6 D( c
return (pNewHdr);
3 H. U7 F: s9 b' x } m* [' F" T# }6 h: Q, r" {- [
6 a, ~ n, V% u( f static void memPartSemInit(PART_ID partId)
6 _" }" b* O7 K& D: P {! E# c4 U/ e) Y0 M$ G
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);6 z: u" K! ~' N) E! C, \3 \7 |5 U
% Y( ?* j! i, k9 y
partId->semPartId = &semMemSysPartition;
- b& k1 K% u B2 @3 X { }3 ]7 @# ` P2 F% J
0 x. U# @0 z1 W& A" W* w0 h% z! K7 W
void* malloc(unsigned bytes)
0 q) j8 I/ C4 g B2 J {$ E7 B6 w+ ~( Z' l: B+ f3 r% o
return memPartAlloc(memSysPartId, bytes);
0 l, m2 H- e+ _! t/ O5 b* R }
" G/ z. q% ~, q J( g
* }. z9 f' m( p# ^) l void free(void* p)
7 C' x9 v+ |* L2 V: N/ |- | {
# h# x; \% I( {. C( A2 e memPartFree(memSysPartId, (char*)p);) v/ D( d! h6 F
}' l7 L/ T1 l+ r2 X8 c2 S5 d" Q
zan