- 在线时间
- 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++下的版本,更方便调试。有需要请留言
7 l; X8 p' {8 M
$ B9 s# Q! i* T, |( o* Z! W* Z6 R8 x
1 G% o+ l- @( i+ d* ~5 F *\file
8 d3 e% q! N0 O d' K/ n) y *\brief % ]; i, b) b0 h% m; z; k- r
*\details
" V$ N& b7 ?! P' D; t' i& a *
2 Y+ ~1 P7 H- _% V *\author Janson
, n! t4 J- X `$ E0 k+ f2 M3 ? *\version
" o* T: S4 Y4 x/ k6 N% O *\date 04Jan12, E ~$ y' }# G$ j$ e3 \# R
*/ H$ S( Z9 z4 o% m
*\warning
' z$ C9 x* H* c0 g- ~" B *7 ^& b, G4 D, g& q+ }/ _
*\history \arg 30Jan12, Janson, Create the file [9 Y* Z5 Y: Q& W# d* l& s" f
* modify from VxWorks source9 o K6 s) ^0 F/ L3 t
* Legal Declaration: it is for studying VxWorks only.9 |! R1 N! F, p7 B8 V
*/* |: L& Q" D- Z, W9 @
#include "includes.h"
8 R# f0 ?4 ?- d& B% U' @! N8 x: f7 I
/* The memParLib.h file is hear:
- S% T0 X& t z+ o9 }/ e. ?https://code.google.com/p/vxwork ... rivate/memPartLib.h- F- Y% G; j. v6 ^6 u) l9 F' v
*/
2 K' ?: _. ?: ~
) }+ ?2 @. z; ^/ |5 e/* optional check for bad blocks */5 x, j* |0 g" ]/ C
9 C, B7 U" @0 A+ Q2 b: o$ |+ z0 w#define MEM_BLOCK_CHECK 0x10
# x8 t8 X! D# S6 G
% l- E* H M& b# B& H1 R; T/* response to errors when allocating memory */
9 |- M4 j q D( c+ v8 i! K& O3 F1 G( z% t4 }" V9 s& q* c. f: l
#define MEM_ALLOC_ERROR_LOG_FLAG 0x208 a Z0 G1 w/ c2 ~
#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40
, u& T# `! x8 {8 x& i/ J# B6 D! `, n5 M+ @
/* response to errors when freeing memory */
' p# M, c' _2 u
# {0 S; ?3 U, s6 `4 `#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
& o+ z0 Y0 ]. ?#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
h/ `% v9 d0 D
) d1 C/ [5 N" c0 ^4 r4 P#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
' l3 @, s+ n1 E( y8 f#define PREV_HDR(pHdr) ((pHdr)->prevHdr)3 V r7 W& @% Q3 }/ j. f
# K0 g7 R" U3 `) Q
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
) {. q1 o* {# ~( P K6 \" \1 S#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
- d1 b5 E s- m0 M; N sizeof(BLOCK_HDR)))/ N+ N0 s# S; @' W J0 ^; x- N; u
6 c( b, i; j1 D8 U' I
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
, H. J$ F1 ?) f& o#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \8 y+ K! U8 x" x6 i3 I6 N# e' E9 T
OFFSET (FREE_BLOCK, node)))
8 X+ c$ F3 u6 L) I ?! k3 ]
, e2 V8 p9 B1 m" ]% ostatic BOOL memPartLibInstalled = FALSE;
. V3 b1 {! O1 O) E3 e0 J+ L" ]% U" d z
static OBJ_CLASS memPartClass;
8 s) `. Q1 H' ICLASS_ID memPartClassId = &memPartClass;
o. ` P2 f9 u( K( `( a
& L: u6 f3 r- {7 B* z- i; gstatic PARTITION memSysPartition;7 O H# b( J: {. a$ t; ?. A- R; y
PART_ID memSysPartId = &memSysPartition;
/ n, m* f+ I! Q1 B1 j( b* tU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
* A5 Z3 I/ n! I! H7 t
2 C' D0 F4 n5 cstatic SEMAPHORE semMemSysPartition;
; j5 t/ A. t$ Q* u2 E8 M! j9 y6 ^$ g- s1 ~: w K& l+ g
static void memPartSemInit(PART_ID partId);; E& D" O% G. Y6 e! o
/ D. o/ A, L) k$ OFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;
/ f# n- g2 P" Y' c; ~
6 ~% A" s. E3 A! b" ?! Xunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
% c+ u6 l$ [5 @& i
" I+ Y6 ?/ ^0 D6 ~6 x* A: Dstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
6 {! U% \5 z& f D& N7 a4 K% Istatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId; L" j6 V- q) |% U- e V
, FAST BLOCK_HDR* pHdr
& s- [# v$ [7 O# G8 t- f4 s# s , FAST unsigned nWords& d3 C* ]+ V. K% P- v X
, unsigned minWords
7 a \/ y; y) C5 j$ _8 s) F , unsigned align);
9 u1 P9 Q# L# a$ ] M9 ]% {3 z$ _& ^' z9 J' F# }
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
* w' c: x0 O, j0 X- C3 w/ J
" M/ F3 \0 b( i6 iSTATUS memPartLibInit(char* pPool, unsigned poolSize)
2 {5 _3 |, m) x{! m! j0 D8 F; n6 C
if((!memPartLibInstalled) && ; t$ ~ G2 @$ c' [2 M* w1 S* V
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)8 [( I4 O9 K* p0 P1 ^. P, g
, (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
" i! U/ ^' g6 w b {9 s8 Y" L3 J( H* [* I1 j
memPartInit(&memSysPartition, pPool, poolSize);
, ?' m$ z9 G, g& g6 ? memPartLibInstalled = TRUE;
' ]# [8 w% ?- w1 o1 @- N }& {( u5 A; R: j! G0 h
) C. B2 w3 r. F! Z# O return ((memPartLibInstalled)? OK : ERROR);
- n4 U3 j4 F! M# {}1 ]1 k: X1 X. r: l" Y! ]
9 H6 B( b- A5 {1 MPART_ID memPartCreate(char* pPool, unsigned poolSize)
! i- h+ a8 Z' O* y6 y{+ K9 e0 v! K p; t' _0 y+ B7 u
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
; {+ \- C1 j! x: x) V
# G7 B" S9 N% N: b2 G' R if(NULL != pPart)' s+ y( ~& b' ]5 |- x7 O
{! S; e, `* a8 k$ e& a7 }8 p
memPartInit(pPart, pPool, poolSize);# T. d9 Q, j8 N+ o
}
5 s; p* a* q. ^* J0 ]5 _. Z" K) p: l2 g7 z9 S j3 n# x: F
return pPart;+ ^$ T2 s) o# ^. O- P
}
! I6 \0 j# w5 g% g- E
, `/ E# P4 b6 W2 w3 nvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)% _* \# _+ R. N- I% r4 n+ X# l7 J
{" P& a: O2 T7 k! P+ W0 l! Q+ \
memset((void*)partId, 0, sizeof(*partId));/ P% s/ s) u& T5 Z
+ p- ], Y' w7 y& \0 ~' \5 G, G partId->options = memPartDefaultOption;
5 G! B, t; o W/ q5 ~1 R4 L& ]5 P partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */
: U+ G3 q8 ^ s! x5 G
. \9 r% F* j+ k; H# [' O5 A3 d( i (* memPartSemInitRtn) (partId);
; `+ r1 ~# V6 u. d! D0 ^: t3 }$ p) t " \6 s- g3 ~6 G
dllInit(&partId->freeList);. v8 o5 ]; s" M: N" ^6 \/ h. I
" f" H5 H: W+ P; m$ @, A
objCoreInit(&partId->objCore, memPartClassId);0 v; u) k2 K. Q% q8 A
E! b. J' [8 s
memPartAddToPool(partId, pPool, poolSize);/ t, ~, b1 j J# W3 N0 v
}
2 o' @& y. _0 Z/ d) Q$ E
" e: S: E9 b5 r7 F! d9 p) \/ ^3 VSTATUS memPartDestroy(PART_ID partId)7 o9 \7 k4 W3 A. O3 q, U0 Z
{
) W, P4 w( i( O return (ERROR);
5 }- g' e6 R8 d. ~}8 E! U( j# r$ B5 }" U5 T
# w" ^* ]3 W5 v) E
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
( g: ^2 T$ e) Z- c0 V{4 Y9 p) Q6 k: f. r! \3 X/ w
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);% u0 G, N! a ~- q- g
}, G7 N5 R% Q3 z6 `, s
4 \4 v! L' C: U7 }
& Y5 d: w" ^! s$ C6 @3 v
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
% Y }: c! r2 C9 S{
. x# }: I" i( W# Y: X2 k BLOCK_HDR* pHdrStart;$ X2 o( i1 r; I& \
BLOCK_HDR* pHdrMid;
; h8 R6 L& [! Y) k/ ]% ~3 n BLOCK_HDR* pHdrEnd;- {" l! _3 r( L& l9 \- f
char* tmp;. t5 r4 O+ ]% Y: O
int reducePool;. E$ y }" b: @
! P: y5 z# C4 h8 O9 d+ D
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */+ l3 w) {5 u L! P' R2 ^' q
{2 R7 h9 l, Y( C# {1 j
return (ERROR);
|2 w* X; Z! |7 [. y9 s& M0 H }
7 i1 M- Y" ]8 p# `+ @! I+ e' @$ O; U0 Y3 m3 m" @# [3 Z8 [
tmp = (char*) MEM_ROUND_UP(pPool);, t/ f# r/ _/ l0 e9 a3 T7 }2 @
reducePool = tmp - pPool;# x) A$ y/ u2 ~2 A5 g8 n
T" b: I, u! W/ y- h& R /* adjust the lenght */
$ ^4 W, G2 E/ V: j2 B' A if(poolSize >= reducePool)
t; R7 ?& w; s; p {
5 B( n% d. q( I* m: t- c poolSize -= reducePool;6 a$ g$ E; S4 U$ G
}
0 C; q/ W9 I: }8 R& p" w else
6 C6 ^% v, }; y7 \$ Y* r7 S. j {
* ~" Q: e# q" J* Z& \9 z poolSize = 0;
0 W% P2 q. B+ H; s( P& A0 R1 X! s }0 l* J5 G; Z$ w/ E* g1 B6 ^- m' u
pPool = tmp;$ k, J" Q. C/ m u% A2 k
' m* E* a! B3 ] W k
poolSize = MEM_ROUND_DOWN(poolSize);: {. w% y& }2 @* ^) ?/ p P
# h$ |( u7 d2 J C( F" t/ e6 N3 g /* at least one valid free block and three header blocks */( y* W% a3 X( H9 j$ g; l6 Z
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)5 x I, O/ x: t) X' ]. s6 @
{
/ w2 R6 z+ i9 R return (ERROR);
' i: V2 b: @+ \5 t7 e9 r }7 {. q x) M" c
: ?8 m, ]9 C, o5 e; a
/* initialize three blocks */
/ x( F3 }% O& f7 F pHdrStart = (BLOCK_HDR*)pPool;
3 ^2 P/ @; Q6 q: ?; H* ?- S/ f5 b pHdrStart->prevHdr = NULL;
' A: f! n' N4 L% O pHdrStart->free = FALSE; /* never in use */8 ?0 z/ x9 r% j, w7 ^5 o( j6 T$ `
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
) j- a4 I( T' }. k$ E* e' @6 c/ O! K) Z$ e1 r" d; k
pHdrMid = NEXT_HDR(pHdrStart);8 y9 }$ Z, V/ k9 S) ?8 M) _) h
pHdrMid->prevHdr = pHdrStart;
4 _3 M! q( e) \; R pHdrMid->free = TRUE; /* the main block */( P& ^# d* K a$ m! l* I- x
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;9 `: d. y) |; G$ Z# v
& u9 `7 M( s" i) b3 J' p
pHdrEnd = NEXT_HDR(pHdrMid);! j9 ^; L' \# B+ ~
pHdrEnd->prevHdr = pHdrMid;
) s. `$ L; _2 [; T+ L( g; v, c# I pHdrEnd->free = FALSE;
% G- _+ y9 U/ O# Q# E4 T6 f6 A% A pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;! M$ v2 S% k* }1 t- a
7 A4 N+ }: C0 g& S4 B9 W* k
/* TODO take sem hear */
, a* h! s7 W( `3 S, E semTake(partId->semPartId, WAIT_FOREVER);
8 n4 ~) W: J( b# y
7 w* B% @* e& `& f6 A dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));' v0 Y4 S8 B' f$ O( r) N
partId->totalWords += (poolSize >> 1);
3 S6 ~7 ?3 L( S b6 l4 f0 b9 q) w& h- D {/ L- l
/* TODO give sem hear */
& T4 j, H$ u r+ T, a7 L2 g3 X% X% a semGive(partId->semPartId);
$ @9 h' r( a- U" P, B
* e5 K3 g3 f* N9 ]( I" M; D* E0 Y& q. q: f- R9 `
return (OK);1 f; r; Z4 e u
}
8 Y/ Q8 v: w4 G# |
3 A" I j* Y3 A9 D! f- Tvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
2 X0 u9 \+ k: N$ o{+ L) ~) B ]' T4 C. m% t, T
FAST unsigned nWords;6 l, f3 ^; H% E4 D6 x
FAST unsigned nWordsExtra;
* M( |, F/ X8 X8 C) p$ B7 `. Q5 u FAST DL_NODE* pNode;
# R/ |$ P9 i6 z FAST BLOCK_HDR* pHdr;/ r) R' j! ?) I# o1 A R
BLOCK_HDR* pNewHdr;! d/ I! o% a; ]5 y) \
BLOCK_HDR* origpHdr;4 N( E6 k) p) H, Y9 O
6 E2 L" v# g( R4 o if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */# z9 L0 p5 v2 W$ M* D7 n
{7 a2 F! |4 ^( `% A0 z0 A# \
return (NULL);
% c5 [1 i. E. l$ X, N6 g }5 r7 Y" _3 X0 W! ?: A: O5 P+ V
+ r& R9 Q. m) h nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
+ M+ k0 W8 K% i5 r. d: m; A$ E0 ~( `
if((nWords<<1) < nBytes)
. l3 _% x8 F7 F: H2 e# L; v {
* \* D6 Y. `4 D' p& \0 _9 {! B /* TODO suspend the task */
. }1 y2 ~+ D; O# ]+ d3 Q return (NULL);+ u3 r/ a" c F" p. U( w! G
}
9 n- J# W: c+ p: t0 K# r; t: ]: H( G& B9 S8 I
if(nWords < partId->minBlockWords)( j* V! V9 Y4 M" Y7 ?& [
{
( x' O. U( Y b5 w" W/ N nWords = partId->minBlockWords;
. W8 S- Q8 ], b- `1 [# [ }3 b% |1 @. A% b: t+ }" p! L
8 @! x1 t, O) i4 b% q
/* TODO task the semaphore hear */5 [, h& J7 M0 ]1 n
semTake(partId->semPartId, WAIT_FOREVER);/ a3 d4 r- F9 ?8 u, s: ]6 p; L
pNode = DLL_FIRST(&partId->freeList);
! r% c6 `, g0 k) ^/ M nWordsExtra = nWords + align/2; /* why? */# d6 c! n/ K4 _/ v x \
) v' R3 H! K, S for(;;)
" e" e( O5 H# {9 d/ y: t {
; T& S5 O$ z" v. _+ s while(NULL != pNode)6 B- U( A, `! u4 {) M3 m
{% @ S0 r8 \' w* s
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
# N8 Q2 o8 A1 r$ K Q( N' I! d ((NODE_TO_HDR(pNode)->nWords == nWords) &&
# {, Q2 b0 m6 J/ u; ]- V (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))% o3 ^% l. c9 T
{
1 m* _1 X5 K1 S- S break; K" F4 s {! X
}
J2 T7 I( M2 u' h4 k4 h! [" H0 c6 ~( T, a
pNode = DLL_NEXT(pNode);
o5 \2 P( H7 e4 o7 P }
' R5 H; l# ^5 c6 Z/ r3 X) z# t. Z% {; M" ?+ V
if(NULL == pNode)
" w6 _- |$ p% M9 j2 r, ]0 A8 h {0 C$ [6 `$ @. E* J) n
/*TODO give the semaphore */
% c1 A$ m7 C8 E% R2 l semGive(partId->semPartId);
. r; i5 K" K1 ~/ k return NULL;
7 O0 A c; J- g' b T }
" X, y+ X( Y# A& ?( x, ^
0 y" v) _2 y [ ?3 f$ e pHdr = NODE_TO_HDR(pNode);; C- q8 ?# \9 ?* x& {
origpHdr = pHdr;7 ]+ T; Q% _9 Q) d+ h. _* j
. G; ^( O& ^5 C9 j" X pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
9 l& C( l& J9 D if(NULL != pNewHdr)
4 q) N" Z' C; r# |# [' T {
" ?, V: Q* J" U( Z pHdr = pNewHdr;& P; I! p/ W9 g! _$ ?4 u* J
break;- p& u* f7 W, N! {/ F* o+ ]; H' y
}; R2 _8 t# ~! e9 L
! m$ B/ N% f, b1 e1 q! |" `
pNode = DLL_NEXT(pNode);% `) V$ e- n& _" e5 \% r
}0 O" h1 u) f* y" |5 M& o
' J% y$ |! |' \/ \ pHdr->free = FALSE;; Q- j8 Z& l5 y% X9 f2 A
partId->allBlocksAlloc++;3 T# Y$ }) |4 q2 s( q/ k1 E
partId->allWordsAlloc += pHdr->nWords;5 o: z+ {# X$ h( c
partId->curBlocksAlloc++;
3 H3 w0 d. g6 V( z m) X partId->curWordsAlloc += pHdr->nWords;7 K4 V, R2 c1 j- C
: d$ S; J; c2 d+ p& [
/*TODO give the semaphore hear */
5 f4 I8 }7 k) m) Z3 K semGive(partId->semPartId);7 C5 ]1 q# o2 M$ R( X/ X e0 ?4 S
return (HDR_TO_BLOCK(pHdr));$ |( u2 h2 j" f# L( ?/ ~
$ E! s1 ^% F V1 V; i' ]7 m}
- P. \7 o3 |% _7 l% d7 s8 q8 R8 c+ Z' d& ]
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)2 F3 k w& D# _2 x
{2 ~% E) r# q! Y: U" d
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
5 _& w' @" P( k9 O; `9 @}* m" L# Z) |& f4 e( e
, D$ g9 ]( y: `1 D9 B5 `
STATUS memPartFree(PART_ID partId, char* pBlock)
) n6 v, O) R- y, X# } e{
/ q/ [; g7 R6 V% I: l" @* q" m2 [% L FAST BLOCK_HDR *pHdr;
( j U7 u/ |1 v& M2 G+ x% ]$ y FAST unsigned nWords;
`3 P( |/ S6 L5 i2 } FAST BLOCK_HDR *pNextHdr;
3 `, i2 x6 ]- M( P& P* T0 Z& [' A2 y% `" e6 Z* J/ ~
if(!IS_CLASS(partId, memPartClassId)): `5 @9 l' _- Q, `. O7 E! `
{* H5 d+ o! [ A: D S, b( W
return (ERROR);
. Z" }& V6 K/ R }
8 M. M' T5 ~& |& t7 Q
! {5 z) Z& M+ z% s/ d if(NULL == pBlock)0 |5 J" k, R; E& {- }
{
, d# X: F0 m3 e! \" C return (OK);
" |; ]4 N$ i& n$ _ }
2 q3 {) I- F. z" F6 `; t
; G i5 h( \ l- O( H pHdr = BLOCK_TO_HDR(pBlock);
: t. b& w- d( F$ k7 j. t; E3 x0 d2 b n, S
semTake(partId->semPartId, WAIT_FOREVER); m$ h1 s1 c/ g6 B' ?" a
3 y; `" f; q* Z6 N, l, w" X7 o% y if((partId->options & MEM_BLOCK_CHECK)
_, n& B- C4 A& z' @% v& x$ Y && !memPartBlockIsValid(partId, pHdr, FALSE))& S' l' a) Q _. w0 g# a% z0 z$ c# V
{8 C4 L! _/ x9 E3 K
semGive(partId->semPartId);
& L9 `' ]) k3 U- B' ~. {* m9 k2 v0 _ return (ERROR);! u& K' `/ e9 V0 o8 ~
}* d5 r- L8 S2 v Y9 l- p
, |3 i% ~- A1 j4 e9 a; o0 J: L
nWords = pHdr->nWords;8 K, X! U9 J- v% b& Z% }
if(PREV_HDR(pHdr)->free)/ C% | }7 F; p, _$ w+ M; F% {$ M) ~' h
{/* the prev hdr is free and than coalesce with it */
& i; S0 y/ V- V- Y7 f. E; @1 c pHdr->free = FALSE;
% K4 V% ~% m1 o2 q4 p pHdr = PREV_HDR(pHdr);, F* [' c1 y1 N9 u ` S5 }6 @
pHdr->nWords += nWords;
% |; [2 t6 r. \$ `( b* q5 t }, d4 {; \5 f' a
else* c; n! h* u' S4 j4 w4 `* r
{
' i7 ~3 r9 E# a# \0 _ pHdr->free = TRUE;
: M5 b6 P2 |- J dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));. N/ t) W3 g/ I; \6 D e$ E. d# O* P
}4 e. I& M/ a% {
8 J, v1 ^; v0 _# Q2 O# D0 j /* check to coalesce with the next */' R) D- s8 x# n- K& v" N1 N
pNextHdr = NEXT_HDR(pHdr);- R% o0 D7 J* {6 N& l1 g3 b
if(pNextHdr->free)
$ r1 G* E6 O; x( x: b4 G: ]* @ {3 D' ?' p4 f1 o" g. o. N/ o) U d( |
pHdr->nWords += pNextHdr->nWords;* _$ m: U8 z/ ^ d1 K* I
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
: d q% \! G" t n+ a" W }
4 {8 p3 i; G6 ^& W5 i# Z, \8 G: V1 ?, F- L; {; I( b
/* cannot use pNextHdr->prevHdr=pHdr hear */! }% ` _6 q8 @
NEXT_HDR(pHdr)->prevHdr = pHdr;
4 k, |4 O% L/ D4 b. w: d* A5 K: `' z/ L4 O( F3 `
partId->curBlocksAlloc--;
5 z* m2 @: a" Z {: a3 Y6 w Z partId->curWordsAlloc -= nWords;
6 ^. w' D+ M) e: R
4 S( i4 }8 F0 q+ y /* TODO give sem hear */& k, P* Z+ n3 [+ f. O1 `
semGive(partId->semPartId);
9 i" A, K6 u+ ^. q% n- O9 Z# b+ K
% {1 ~3 D. W* G2 E# e3 u. v return (OK);
( B- W# p. p. q1 G a* h e}- t9 ^8 o3 g( f
! a8 i2 a' j; z3 ^7 a" e8 Pstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
5 {+ u' \+ Z: q0 Q{
: Y' |3 b0 l8 |6 ]3 v) _& i1 b3 k BOOL valid;0 ?" U; |" r5 L" Z6 v2 H
! P! D, W! c3 E) P8 b TASK_LOCK();
0 L# N+ x3 f8 j) u* b4 c2 O) f4 F6 F semGive(partId->semPartId);: V' U6 l' v- m6 D/ W4 W% y
! c' T5 Q& x+ a$ A* ` valid = MEM_ALIGNED(pHdr)
, U0 [8 S6 n) [+ S5 P2 e && MEM_ALIGNED(pHdr->nWords*2)2 Q$ [( U& }0 F6 {2 N
&& (pHdr->nWords < partId->totalWords) ( z. g0 ?! h: H5 \5 [' c6 h
&& (pHdr->free == isFree)+ d6 O5 v. k/ h. e J
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))1 a; a1 N' x. U$ k! {8 p1 ^
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
. k* I* b3 v. {, l$ u9 F: F
p$ w# ^6 ~# F# B# { semTake(partId->semPartId, WAIT_FOREVER);
# X8 G3 C1 T3 R5 r; q7 @2 O9 u TASK_UNLOCK();5 \, U' W. i. m
) W* e! l; [- _ return valid;% a, U/ r4 V {' @( `; r) L9 B
}+ H6 V/ A& a8 t- \
' ~' t5 k: _# kstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
* l' z- j+ a! U% {$ A# y' D , FAST BLOCK_HDR* pHdr
( n: J0 b6 M9 ~( p! Z4 ~3 E3 O , FAST unsigned nWords
' ]' d. ~- `: I% P2 f: R$ H , unsigned minWords
" L" P* z, o: A) e& ?% j$ c , unsigned align)
8 r8 t7 L; |( r* ]' b& R{
]9 ^6 Z+ D' O; @ FAST BLOCK_HDR *pNewHdr;
/ Y9 {7 c0 _8 {- a) Z FAST BLOCK_HDR *pNextHdr;% j3 ^5 [ e% n) g( U: i
FAST char *endOfBlock;
7 v- c8 g1 e) {5 u FAST char *pNewBlock;
: F# i# ~' p, `, E. L2 Q& I2 k T+ [ int blockSize;& f, @, W5 f% O% f( P1 U/ A0 M2 J4 c
/ a( |+ [- J4 l4 c( J# b! ?; _ endOfBlock = (char*)pHdr + (pHdr->nWords*2);
6 [% |3 z% j' y, U( b/ z& |, C5 C* ^3 R" W
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
2 G0 O8 k5 c, ^6 p: f: H1 t1 r8 Q q* l ?% i- ?% ]% e
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));) m7 A! e1 v+ u, N' h8 H9 E
J' @! {8 L5 R* ?2 T0 o pNewHdr = BLOCK_TO_HDR(pNewBlock);
3 B/ ?: U2 h7 H! m& C& G! ^" N* E$ M- [. o2 @7 S0 F: E
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;$ F, L) i/ }2 C& X
9 g& D0 E& p' p! N
if(blockSize < minWords), H1 t: k5 i5 w4 r3 x+ ~+ B% W
{4 O1 f7 x. {. \
if(pNewHdr == pHdr)
0 i j: T! ?- V. B2 J6 V+ ?* ?3 i {- d0 q ?& W; L
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
/ e/ ^% e! Y4 d6 o, L }. j+ A; E x* b4 s7 z
else
# s% b* c3 q. K" \/ {' x( H3 u" ]; Q {
) z' T) `. Q- q5 p0 b( O, B9 c( o return NULL;: t4 K* `8 x' f5 G5 V9 j9 Y' s
}4 }2 X% A: Q# K+ M0 p% K
}$ Z7 x7 m5 I+ @. q f
else; m, l% B* K- o
{ /* recaculate pHdr */# W+ X, r v8 p2 W
pNewHdr->prevHdr = pHdr;/ H; s" `( ~ D3 Y5 N1 D0 L* W+ i
pHdr->nWords = blockSize;
% q# m9 H6 j8 W f; i2 i0 ? }% J! O9 U! E/ e) H# |
3 x: Q7 g: O P* o( J" O5 o if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
' j8 R: s, e8 U, `. N& j* o {
6 L( I6 T/ x+ Q$ u4 r3 ^" d pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;) U2 @, L( B; c
pNewHdr->free = TRUE;
4 P. m3 \; I5 a# [8 D- Y$ V0 g0 l1 ~5 y. s V3 r9 ]6 x
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;+ s# k# A5 W: x+ x% g/ w! E3 O2 u" ^1 g
}
9 N4 f- F) L. } j* r else
0 c3 S5 H5 G2 q* |3 H8 C" z. F; j {/* space left is enough to be a fragment on the free list then */! E {. P/ v4 W; C
pNewHdr->nWords = nWords;
3 y! m3 [1 e9 ~$ k& ?4 W M pNewHdr->free = TRUE;
3 i: v1 a" {1 |, B% C) W: x! N6 M5 c$ r& M" w4 D# h
pNextHdr = NEXT_HDR(pNewHdr);
! f( X7 E. J/ l. r /* words 包括BlockHdr */
1 J* ~3 p2 A1 ~, l/ v pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 a6 ^* n0 V+ }: W: R3 V0 `* r
pNextHdr->prevHdr = pNewHdr;$ O! h/ s0 y" M6 N% d+ W
pNextHdr->free = TRUE;
+ b/ E4 H1 ], s8 ^* X% |% Z/ t
, _% Q, c" H1 Y5 Q. i+ g3 n1 Q dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));) \# H: S: P0 e2 E$ p/ Q& b( s
6 W* r1 r! O5 \2 z1 u3 U5 z
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;0 w7 {# }; m) j0 e1 @# l- `% _
}
! o# a: O3 g$ U9 V9 P$ ?' G" E( j5 H/ ?" \0 K
return (pNewHdr);
2 G7 C: [2 ~# h}
$ U# m7 h# w* ^0 {& e: Q4 `
) l6 E' n6 x6 q" {/ q% Ostatic void memPartSemInit(PART_ID partId), _! I8 g9 e' \: T0 C
{
2 p* @1 D4 E5 R4 A- W semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
( c* x- ~" J5 R0 \4 o" q, a
2 q) C: \% a8 I partId->semPartId = &semMemSysPartition;: |3 E6 v: a P1 L( J' V7 C' m
}
. l0 V' {; e7 u h0 R0 E+ j* F8 T5 p' @, S1 k
void* malloc(unsigned bytes)
3 M$ M {5 P: _{
; z7 X3 a, F" c0 W0 t5 d return memPartAlloc(memSysPartId, bytes);0 R- e# U) u9 v4 `" M3 l3 Z- A) l
}
( M5 m. y9 S% Q2 P) N
0 z/ h7 K. J) Avoid free(void* p)
+ ^3 f+ l0 h5 ^" ^* Z{
$ ]+ U4 c0 Y( \, N memPartFree(memSysPartId, (char*)p);% p3 a- N: _# ?# u2 ^9 n& m3 I
}
' J! {5 ^ U c3 S# f6 } |
zan
|