- 在线时间
- 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++下的版本,更方便调试。有需要请留言
" a- x. j9 ^2 b/ s
" Y3 W+ a+ ^) e
; ? B, c0 }& I7 ?- I5 t
- h8 j/ u6 P8 _7 T. i7 n0 M *\file
3 q4 A# L* i7 p# H6 o: R *\brief
4 D8 n) H* a/ @: b2 |1 D/ \3 k( [ *\details ( Z% M9 f, x5 I; d
*
- X8 `, G- w) _ } *\author Janson
' c- C# t$ R# P& s# U *\version # P4 y( c" a) Z# i7 P& Y
*\date 04Jan12
- _( B6 d0 }! x *
( g+ a- R" B U' v$ t9 V *\warning 5 o" [ N' L' Q; [4 U# `
*
8 O ^& T) n' ?2 }. S- J2 i *\history \arg 30Jan12, Janson, Create the file
+ d% T- n g0 e. E& R% I% O% ~% l * modify from VxWorks source- t4 |, y7 l1 a- A9 P
* Legal Declaration: it is for studying VxWorks only.
: `, _% L6 `5 W3 J */
0 e8 g6 E5 K9 x#include "includes.h"* w, O0 }1 T$ G! G! u; D T
/ F+ A Y* q+ h/ m/* The memParLib.h file is hear:
4 i! M, y3 K. w4 F4 C4 Mhttps://code.google.com/p/vxwork ... rivate/memPartLib.h- n4 e: ^; M3 g* Q
*/5 M6 R: @; a, B. R$ o' ]5 V. \
/ ?* q3 I4 J- n9 F2 _# a" E/* optional check for bad blocks *// K4 F1 v0 G J' o3 b
2 O* U/ c3 f! B#define MEM_BLOCK_CHECK 0x10: J& M k/ r5 i1 A+ P+ v
' l U9 \' U) `+ q5 Q6 N/* response to errors when allocating memory */' X5 Y. {9 ~# T k7 Q, Q
: p# U! d! W7 \! d F#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
4 v$ y) ^9 Q% n# \2 H#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40; w( }7 b: `: r, {
) e+ H2 T5 B9 F0 x. f0 r2 J( o6 Q
/* response to errors when freeing memory */
8 r! e W, e: u' i) z" @$ [* L Q7 P5 K- E3 [( b# [; E; t+ T
#define MEM_BLOCK_ERROR_LOG_FLAG 0x803 ]6 ?9 n: _- j' C) r
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
; A& N, `# T. T" s8 ?5 k/ T6 K
$ q- j4 {# N* F( C, S; x7 |#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))$ |4 a. W% h$ [ K
#define PREV_HDR(pHdr) ((pHdr)->prevHdr)- ?: K4 k2 v7 a5 `7 C2 e
8 c+ G! {9 i7 C3 S6 Q#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))8 z1 o) N1 B' l
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \) ^( b% D' L# Y5 P* f$ Z& S) V5 U
sizeof(BLOCK_HDR)))) Q6 X4 x# S4 k0 I; ^4 O8 i
" Q% q/ P- {* |& |
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)9 G& Z6 Q) b% ` p/ T% N
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \
c: I0 }4 L. c6 k3 c4 N! K8 | OFFSET (FREE_BLOCK, node)))
- F- q6 D) P3 o, ]/ X- B1 t, W# U9 m( Y: j1 w
static BOOL memPartLibInstalled = FALSE;
0 m8 h: N, }9 [: E0 ^: i, k+ F% M1 |" y
static OBJ_CLASS memPartClass;
+ {0 L3 o7 A9 c1 w m: ]CLASS_ID memPartClassId = &memPartClass;1 Y" X. t+ H# x1 b& v7 C
e, n3 T8 Y, T0 \static PARTITION memSysPartition;
/ S2 U$ u1 }7 \1 X2 LPART_ID memSysPartId = &memSysPartition;% b; t2 i1 V: n' ?* Z+ g
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
! x* c u% A9 P" s$ j; X3 B- `" w7 Y1 E' @, I; v- g) |. p
static SEMAPHORE semMemSysPartition;/ g2 z- Y4 e G& W7 E$ C
- q/ z" X( r. D4 U* Xstatic void memPartSemInit(PART_ID partId);3 U# K0 M6 d& u# @/ d! f
5 e/ k; z* n$ B. e& Q1 Y0 u8 VFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;4 J4 X% X& t) C
! @& C# x6 N& Hunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
) I1 W8 o. d I# p- r0 s& X5 b% X4 Y( R% m2 @. @' {
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
! q J: y' ^' p6 i6 j( Y* c! \0 Wstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId% K0 {' C1 `4 }0 x! Z! a& y
, FAST BLOCK_HDR* pHdr
6 ^5 g5 _ x( b5 e1 x+ b , FAST unsigned nWords
4 u. D: _) {, u/ @' I , unsigned minWords5 z% C4 I# b* o& ?9 I2 i
, unsigned align);0 {4 n: K# a& H5 Z S7 g
' Y' V3 b- ~$ t# g3 {1 Z
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);& R3 k( P$ l) e
$ O$ Y4 g# O9 P- N! b4 _$ eSTATUS memPartLibInit(char* pPool, unsigned poolSize)2 L" D" a0 o9 d$ F
{
) o0 ?& O( P2 a if((!memPartLibInstalled) && 6 l/ t8 c! U4 }3 A5 X& n0 E: G$ _8 M
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
3 X7 Y3 V+ T: \1 Y, }, t2 [( |$ g( y , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))' g/ `( A2 K1 Y/ A
{
& i) U4 e1 w' T5 y- ?+ Z memPartInit(&memSysPartition, pPool, poolSize);
. c% Q9 d: D+ M' P- S% C memPartLibInstalled = TRUE;7 d+ n0 E1 ]: L" G
}
! {# M; n2 _* G) }
3 a7 c& Y2 l' V% F" N, I; \% z return ((memPartLibInstalled)? OK : ERROR);
, ]# C& V- P% Q- m}* g! ]6 B5 F6 ~% x2 Q# r( b
' j3 `& S8 C. [& k6 x4 U7 S+ w7 s
PART_ID memPartCreate(char* pPool, unsigned poolSize)- L4 y! U. p9 n. t( B9 ]& D
{% i; I/ {9 t* p6 E i5 f6 J
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);9 P2 e9 b5 M7 ?/ a& c' v
/ ?& g7 z0 \3 K. q; l9 h
if(NULL != pPart)5 s$ _& u$ D( |; D" |6 v
{ Z. x. i- H2 M# o" l: D- q
memPartInit(pPart, pPool, poolSize);
; u$ @0 W% r9 D7 Q8 g }
3 w+ H/ h6 s8 W9 N: B! C
# J, h- @- y/ [7 \$ E return pPart;3 K e3 P8 p" ]3 j
}+ e( l$ c9 F9 h9 u1 E
+ g: y$ D& n9 o K/ u! c) A
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)2 i8 z! B5 O3 P# T1 g9 W+ C
{
8 G, ?) s. @. ~# d8 y( N memset((void*)partId, 0, sizeof(*partId));
+ z# u, G) ]8 v e9 d8 J* e& A5 r, Z) p. c s s/ E+ C" Z
partId->options = memPartDefaultOption;, L$ m7 K6 C; A7 l5 g
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */; i: |: }' N* \2 N" z5 g/ ^- H" f
5 z# N4 E! s2 e: R2 j- f/ `
(* memPartSemInitRtn) (partId);0 g3 }0 _: v/ F( s% m& s4 n
6 ]* S! f& s+ H! Y2 z5 ?/ f dllInit(&partId->freeList);
0 q1 S$ K0 F- x
8 `# x/ R* {& T3 [# Q( t objCoreInit(&partId->objCore, memPartClassId);2 H$ c: K+ W, X6 T
2 v# b" W" U* }( Z* Z+ Z* R A
memPartAddToPool(partId, pPool, poolSize);, |+ }- L; M C7 {* P; Z) k5 f; d
}
9 g N) Q" n2 P$ V( ?, t& F' S+ S- m( W& s0 {2 ]
STATUS memPartDestroy(PART_ID partId)
* H# G/ h. ~. h( y& ~{* w3 m3 F; M4 E. d( r$ H
return (ERROR);2 T' u8 {7 O/ H* p& I9 Y
}
( _$ x, @/ ^! R0 j* a0 \; j" h' {+ h! k* ^9 P$ Z' t7 E
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)5 H& Z- J6 ~9 n0 k; ]: B% F
{0 H7 Q. o9 Z: p- `4 E7 o- |; K# }
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);
# E6 ^" [( M( K! R1 y}
+ Z! S. Q# m% f* V
: _3 d5 f2 h3 j5 S
, |6 p6 P/ L0 t4 A+ ^$ Q% ~! Xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) s% g+ h: B) \" y0 g2 ^
{' P. g7 M0 C' }
BLOCK_HDR* pHdrStart;: O6 T: D. c& I7 q/ j: d4 u0 {
BLOCK_HDR* pHdrMid;) H' U7 f7 V9 i* w5 G. n
BLOCK_HDR* pHdrEnd;- v$ }$ r! s% W7 `# c# a
char* tmp;# j* B( p1 K, k! a$ b
int reducePool;, G0 a$ r& h2 a0 I% S+ O
5 R: p, k) i2 C0 @6 R5 C' R# g1 X' | if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */5 x% g: _' M2 j2 w9 m
{
( b' u- m K$ p- r) y4 N return (ERROR);
! p: ?" v; p$ Z2 x }
0 f# s8 K9 j- ^; h2 u' ]0 {
0 r2 l8 m1 U* z4 _: E6 n1 u tmp = (char*) MEM_ROUND_UP(pPool);
% l+ P) n3 a1 J) W3 @ reducePool = tmp - pPool;) C1 q; b# |; |/ ]" T
4 _. p/ p4 s' e1 s0 U /* adjust the lenght */
8 G2 j. [% @# o A: s" a if(poolSize >= reducePool)6 P. K2 `. a( U5 |! {& X0 W# [! k- [
{) G4 ^+ \7 S2 w$ ~5 z" z: D& F, o- \
poolSize -= reducePool;
5 E9 q8 v" B( g2 | }
! c( D+ L3 c2 r' _0 v3 ~ else/ q4 G3 Z5 b2 _
{6 X( y) }, Y9 R# n
poolSize = 0;, x$ Q8 J1 }% K' r* `
}
' F& r o! {) u5 J% `9 w7 W pPool = tmp;% v5 r- e' V) ^
' h4 K' H$ m( y( b) k
poolSize = MEM_ROUND_DOWN(poolSize);
: k, }- j z: p. H! |, k, h 0 X M# w7 s# a* G& p4 u5 V d6 J* S" l
/* at least one valid free block and three header blocks */
8 r4 R! E+ [( `2 I+ U if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize): q9 J/ i6 F* z) \( D' B' Z
{& h: \$ n/ \, F: i. L9 O6 t
return (ERROR);
/ o2 q5 D2 f7 i3 F6 m' _ }
6 w/ [7 s/ U" n. C( {4 U7 t6 p& v' ]4 ^
/* initialize three blocks */8 n; C+ N0 d# G$ V
pHdrStart = (BLOCK_HDR*)pPool;, X: w# P7 ]0 O/ u0 [
pHdrStart->prevHdr = NULL;
& U8 k/ v( E$ A- f3 `: x pHdrStart->free = FALSE; /* never in use */( M! C) y3 n2 c& M
pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
4 Z. u' k2 S, T/ c8 q5 Z. c
# w J8 K: d- |& d3 D pHdrMid = NEXT_HDR(pHdrStart);# ]/ J+ [& t2 b6 V! h
pHdrMid->prevHdr = pHdrStart;- E) k- F; T* B( f2 D/ G
pHdrMid->free = TRUE; /* the main block *// W* k8 R; r" ]* |
pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;' ~, D" W7 Y: m' U: _; R7 Z) K
* f0 k& ?# X ]( w, h$ c
pHdrEnd = NEXT_HDR(pHdrMid);
- v3 D0 k& k3 z" ] pHdrEnd->prevHdr = pHdrMid;, n# ~, r d5 P( L
pHdrEnd->free = FALSE;- ]( q: O$ D# {; u+ \
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;7 Q7 K& {* H$ s
}) M' g: ^& a% Y# O4 L( z /* TODO take sem hear */* }* a0 \3 H; r9 W7 ^, T- W
semTake(partId->semPartId, WAIT_FOREVER);" I! ]$ ~7 N! v5 V' n2 N$ m. ^ H
' W/ T: \; M( ] dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
: g! W$ n$ _% j1 @ partId->totalWords += (poolSize >> 1);. s% Y/ O0 P+ I( U5 }
% A* @# L. G/ e, M* x /* TODO give sem hear */
: u9 u5 a! R5 D1 S6 f semGive(partId->semPartId);4 J" U! ?* g& h6 y5 u- [: S5 r9 a5 m
' h* C4 s1 }3 @& p6 p" @, Q) Y3 l+ ~8 e
return (OK);
/ ?+ W, ^! q$ o+ H}8 [, c# A2 C3 U. T/ B* T
& {# Y ]1 W- H2 T# h7 H* H2 B
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
: P; v' n. a7 c }* z; t+ k{
% z. B2 s" z; p7 t4 k3 E+ N FAST unsigned nWords;
1 ]9 D7 C0 ]* [8 j/ R FAST unsigned nWordsExtra;. g6 \$ S* G/ O4 Y3 a
FAST DL_NODE* pNode;
+ D6 [& a1 r) O# w( p3 H& x7 j+ T FAST BLOCK_HDR* pHdr;0 G( t1 v6 J" i" W! Q
BLOCK_HDR* pNewHdr;
6 i% A6 l3 ~/ I) Z S, ? BLOCK_HDR* origpHdr;
" i1 I; n# o! ]. m
7 M/ o) ?- f4 { @: y) } if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
1 N% X) v8 S# w3 w7 ` {& J u D4 L: _9 Y
return (NULL);9 d) L { t* ^" v0 a2 B
}
4 Y# G7 I5 C- T9 N7 H
5 U7 v9 z, a' u9 ^8 n nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
9 Q R7 J5 R. A8 m
& D) d, E4 \& s3 X if((nWords<<1) < nBytes)9 ~! Q8 g0 @0 s8 Y S
{, }' I. {. V; i# A
/* TODO suspend the task */
. b- z r/ o8 L8 l2 o* [ return (NULL);3 {3 Y0 j2 P- p, c: O$ j5 ^+ Z
}# g, v2 K. f1 Y2 w& `* F4 B* T
' ~% f3 u; w1 f0 V- _0 R if(nWords < partId->minBlockWords)1 Z) G6 D7 v5 V2 T8 L* v7 C
{
! u" l8 F/ T4 k4 @7 X/ I nWords = partId->minBlockWords;: @! A- R% k0 Z
}
* a; I: O. o: G9 }/ t7 {: S) U. H/ e) _7 A4 c
/* TODO task the semaphore hear */" o2 N: E3 E# \: K! H
semTake(partId->semPartId, WAIT_FOREVER);3 E. f3 I2 C4 e6 p" t; H
pNode = DLL_FIRST(&partId->freeList);
4 l2 H6 ]( F% c, w) O: r nWordsExtra = nWords + align/2; /* why? */6 z& L& i( f4 `% {) `' c
$ E2 D8 x, w0 D9 N, s for(;;)
" _" V, ^5 f4 ~9 J2 b: v% x4 x {
& j' H, _7 |6 t3 S7 ] T5 N while(NULL != pNode)$ K4 A: J. u O5 W! _8 y0 J
{, P* D" {8 z* e5 ]+ @/ T
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
8 j( Q9 a7 |. r' W ((NODE_TO_HDR(pNode)->nWords == nWords) &&
' {- S7 u& l/ p6 M! q; o- D' R (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
) i# w/ D- i9 r {% ~- e2 Y2 S* o5 h
break;
3 ?* b, u4 M! q }
% s" _2 ?" G: F# Z' f7 ^! r; e% w% Z( t
pNode = DLL_NEXT(pNode);
4 @+ Y% q# d' }/ \# l$ g! G }
' N9 q. R; W+ v6 V+ a& p
7 I9 t5 `5 y: @# g2 Y if(NULL == pNode)
* T- Z. R _4 E, a1 O# l& g8 L1 x {0 n/ ?3 l5 w7 w7 {! r/ V4 B
/*TODO give the semaphore */
! S( F/ T) K# W: \ semGive(partId->semPartId);
0 K) ]$ L3 f4 m- b/ \9 k) ?& `6 P return NULL;
+ w0 V% a" q2 D8 E( T! P }5 y0 [/ H6 t9 |$ M: x/ A5 c
6 Q. e3 e p8 V. D$ ]# j( d. ] pHdr = NODE_TO_HDR(pNode);
. r6 d" Z( D9 T6 r origpHdr = pHdr;
- e/ w3 e/ Q, B! h
6 s5 I# F" l( r2 g2 S7 _ pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);9 ?- p1 |8 V5 k$ d; W
if(NULL != pNewHdr)3 A; s/ ~, |( c
{
$ T4 b# p j7 ?$ m/ E2 x) r8 L# r pHdr = pNewHdr;# F" W7 ]; D" ~& H% D
break;
( ^: d: ^& @- y) ~1 t; K' g }
. z. ]% Q$ z8 D0 x* `
$ z2 |* z: C5 }7 n% f4 [. s5 r) C pNode = DLL_NEXT(pNode);; F( c4 S% u8 o9 r+ I" |
}
1 C! x. u. E; u' y C
% s/ P" g! ~5 U# |6 M) X pHdr->free = FALSE;7 \3 Z/ Y# h- Q; g% C d, Y
partId->allBlocksAlloc++;
) m9 s# n4 }: C# l6 N" s+ L partId->allWordsAlloc += pHdr->nWords;
2 y- `3 v0 y3 p partId->curBlocksAlloc++;! v; @ B- {! p8 R$ h: i" K
partId->curWordsAlloc += pHdr->nWords;+ p4 X% P9 q5 ~! R5 O# Z0 Z2 \5 h
2 Q6 d, e! y3 x# p! U& x6 N8 e b
/*TODO give the semaphore hear */+ m' }% X9 w% y: q& O' @
semGive(partId->semPartId);
; D D/ r5 @7 }! ]' x return (HDR_TO_BLOCK(pHdr));, D% k. k1 \. H! J1 ~( E( l- {
7 K6 B( C9 @( J+ E5 f
}3 k4 g( L4 b G7 [- O7 U' J* Z: D9 _
6 `! @5 Q; A! ^* M( e% H. d
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)7 n# t7 A" `) F# C% H
{
" o# g- e% q; e2 [' }, `% e' Y return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
8 n; q3 O6 `1 ^4 l3 h}2 ^. `5 D: q& a! ]' v, g
" s6 X. U- n [4 C1 k1 M) {STATUS memPartFree(PART_ID partId, char* pBlock)
* B. f& R) C |{, p3 ?7 H9 W* `
FAST BLOCK_HDR *pHdr;
$ Z- K* h& S P: Z7 u) m FAST unsigned nWords;
: M9 V% c3 L( a; @; r) V FAST BLOCK_HDR *pNextHdr;
8 o' _4 C5 h' w' S' n# g/ c# t1 F, I+ n7 k" U$ S
if(!IS_CLASS(partId, memPartClassId))
$ {1 k6 ^* w( l0 e4 b {
; O1 }- C% K2 M3 K( V( }8 Q return (ERROR);
6 v- M# ]; L0 J! B }
, ?" I+ w: F6 ?+ H2 w1 t) |# _2 T: H3 C' h _, k
if(NULL == pBlock)& Q# T! v2 Y a! N! x# b
{. ~; u3 ]9 J- b8 F$ ?1 o" N
return (OK);" d, m* T: ]6 a' W' j- s
}
- F8 u1 E+ n6 a& n7 o" r
1 x Y* Q6 p' V pHdr = BLOCK_TO_HDR(pBlock);
' j! l' y* @+ J
1 v! q! O) u$ w5 x; r9 s, C M semTake(partId->semPartId, WAIT_FOREVER);
2 k: V k2 Q# U' ]/ G U4 l- N& i: z+ f$ z
if((partId->options & MEM_BLOCK_CHECK)4 a: F, y ?/ j. z! e% T$ {
&& !memPartBlockIsValid(partId, pHdr, FALSE))& m0 N/ H5 m- w2 f* K0 U; V) _& C/ H$ w
{5 |3 t, U2 M; {
semGive(partId->semPartId);( C: ^& x+ s, s; X7 e" S2 d4 Z
return (ERROR);
( |1 O) f3 \! Z* r1 B4 { }9 `' j2 T4 b% M8 J% q' S6 a
; M& h) T/ Q: M, ~, E Z: ] nWords = pHdr->nWords;
3 a& P* c0 D( N6 G' T0 u if(PREV_HDR(pHdr)->free)
I2 A; Q) {& i& U. O5 s. U" } {/* the prev hdr is free and than coalesce with it */
: s M" k& O/ J# s pHdr->free = FALSE;
2 B# Z2 l m g7 d; M' L& `0 M1 Y pHdr = PREV_HDR(pHdr);) V0 Y3 Y. @4 C. \8 b
pHdr->nWords += nWords;- \* E ~5 e) Z) j- a+ A
} C2 L% ^6 {. C/ S2 g
else
6 a& j* x+ O0 H {. W7 ^. v& l% h3 X4 q3 h
pHdr->free = TRUE;
" K- y) w3 a& } dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
& ?8 Y. {( p4 I }
7 G0 X- S) y" J
& [9 v, c0 C7 F: l /* check to coalesce with the next */$ u! I3 Q5 A* i( t! A$ F! H( m
pNextHdr = NEXT_HDR(pHdr);, j1 b" x; t4 i0 w5 B+ O
if(pNextHdr->free), p% Y( k7 b+ V4 t
{
# i# g* o1 L0 _- y# J p pHdr->nWords += pNextHdr->nWords;/ ]! X2 u4 f/ k8 E0 g- d8 v6 D# K
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));; |( o7 ?, u9 t" h" y; G
}2 P( ]/ k u# v1 \! v* \! R
2 k7 G6 U- y& X
/* cannot use pNextHdr->prevHdr=pHdr hear */& Q# w" Q* Y7 _- m
NEXT_HDR(pHdr)->prevHdr = pHdr;) n8 u o. H+ W2 s: w0 v$ D* R* f
$ C- \3 a$ u. b) E1 q1 [
partId->curBlocksAlloc--;
. b! \$ Y, y, K5 g; |2 c+ I partId->curWordsAlloc -= nWords;
# e; W2 L2 |1 \( V: {2 e
8 Z g a% r& \1 g /* TODO give sem hear */
* ]- O6 @, P, g" S- n8 M1 t( L semGive(partId->semPartId);7 c: W& c( ^$ Z5 Q
5 L) `5 L7 f6 X4 O8 o& f6 K. J3 E
return (OK);2 h1 @( H) r: K; @' l; L
}
I8 V) ^ g5 k' E/ C1 m# V# z0 X/ ^, X6 R6 E( n- f1 M
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
`6 `4 {2 M4 L# l X( H/ l{ B. F) l7 i" K- S* ~3 J4 o
BOOL valid;
( @) E0 \/ B! X; a+ }6 P
/ L J" D. q! [; P TASK_LOCK();
+ \8 s4 u. a# c- D' C semGive(partId->semPartId);
+ q/ w# Y1 l9 o6 X2 h
* w7 Q( _3 ?, R# @5 Q) L- ]4 F valid = MEM_ALIGNED(pHdr)
1 c' {6 L; U" Z$ ? && MEM_ALIGNED(pHdr->nWords*2)8 `7 X! R% h7 ^5 ?* ]; K
&& (pHdr->nWords < partId->totalWords) ' @* u/ ]: y. @& l; _: G2 u
&& (pHdr->free == isFree)# L, t- C- A5 D# y( F7 J
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr)))' n2 C, F8 x9 n/ \! \* Z- |
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));: {( ?7 |" S0 l
. E% n3 C! W5 i9 X: d8 A, f, P' v semTake(partId->semPartId, WAIT_FOREVER);
8 _/ h2 g2 S7 Z' X' M/ `8 l" A3 s5 J! H TASK_UNLOCK();$ T- q: F* C V- a
8 s( l( m) k5 Z: Z
return valid;) F* q! V" M/ B, N# l6 ~
}% X9 j* c I3 T/ M; m6 e4 b
& E. o; r6 P, d6 Q) C+ y
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId1 S4 k0 v$ m" G$ c
, FAST BLOCK_HDR* pHdr
a- l! t }, F4 i , FAST unsigned nWords
) g! _" R( p q: z , unsigned minWords% [4 b) N8 S7 z9 g2 h2 \
, unsigned align)
* q% o u4 L9 m2 s! R{, V. }$ f q2 d8 q
FAST BLOCK_HDR *pNewHdr;
% Q. U+ }# m0 c& p& t9 s1 h FAST BLOCK_HDR *pNextHdr;6 I6 o5 ^$ S4 Q+ b0 X; o' l6 R/ B |9 P
FAST char *endOfBlock;
/ Z$ x: s& D. k W FAST char *pNewBlock;' @) E7 l! i% J/ k3 g9 i+ t5 V7 o
int blockSize;
/ [& R1 `5 v* L2 p5 \6 V+ S& ]7 _/ \- j0 V
endOfBlock = (char*)pHdr + (pHdr->nWords*2);% B) D( [+ s R' _8 B# I
, h3 p3 }5 V# Q pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
* ]3 g, I0 q+ D' f. `0 E2 K1 S& @4 p" T0 R5 x" l" p5 R4 h' Y
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
& Q) l6 O, f% U" G3 ]5 c! Z$ ^2 |* x& S9 @ v8 r
pNewHdr = BLOCK_TO_HDR(pNewBlock);0 N% d% Q- `( ]% N
9 j& x4 ^8 N; h9 p! t4 V blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
/ ?" {* T2 s9 N' U$ L* U/ q4 Q( }4 W, l; [9 q6 f# [+ Y
if(blockSize < minWords)
7 w7 b# j/ n+ p4 K {
9 W9 C G$ ^6 e8 A9 ? if(pNewHdr == pHdr)
* ?, }; H) |$ l) F; [. V {# k5 }9 K( K& {: V
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
2 y: Y7 ?/ {" O }
/ {8 M* W r8 [, V" `/ z1 p3 D else7 u, ~! B* C, a& F. _
{$ y4 C8 O1 S# u" m: ~: g5 |. t
return NULL;6 m1 x1 a$ ]$ v. R
}6 K8 {0 f' x% H# |. ^/ a& U( G; z ~% u
}, [9 R- b( M9 D c% E
else. ?/ Y+ s* ^6 K6 X
{ /* recaculate pHdr */
! I$ z% F3 H/ @$ j8 x pNewHdr->prevHdr = pHdr;$ B$ z8 b. O" g5 w
pHdr->nWords = blockSize;; q: Q1 [0 Q r: p/ \/ l
}
9 C4 U2 f2 j1 `0 w; E1 T
9 k. W) r2 M: s# D0 z- ]6 @ if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))4 s, } r4 t/ I" k0 }/ G7 M
{
# [$ a9 }" z% m- w L5 t pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
, Z* |/ R8 W: c3 [+ \% x pNewHdr->free = TRUE;" Q- q$ o( w+ e
& F; l7 ]: e$ X" q" ~$ O. ^
NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
; y( D( u; n5 G6 w }
# [) @7 ]0 p5 r. s: z else' ]! d: H2 `* T! D% d
{/* space left is enough to be a fragment on the free list then */
: O4 X. ]. _. K4 T& r: f+ c | pNewHdr->nWords = nWords;2 U% |! L5 _# s1 V
pNewHdr->free = TRUE;7 r( V: R' T2 l
0 y( v/ t0 m3 F2 }9 n- H, |, {
pNextHdr = NEXT_HDR(pNewHdr);$ Y1 A9 b9 Q# e2 R
/* words 包括BlockHdr */, Y6 ]: p: e9 M- W% ~; F
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
- Y5 l8 G7 ]- a" i pNextHdr->prevHdr = pNewHdr;5 V9 s6 o" Y; G; `: r% x# ^! z
pNextHdr->free = TRUE;
7 b& I1 N/ ?8 U( W4 o# }1 x$ c
# C+ @ s: u/ o, K+ ?4 Q$ p dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));( n7 y. F! k' Z$ m
! o" A, G) R5 x- s9 u8 u" ? NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;( F. h7 k8 q5 W; u
}1 K2 ~9 n3 r) r# _! m
0 Z9 ^ {& _& f; O7 q9 } return (pNewHdr);, K, A+ [. R5 E8 i6 i8 d
}# k I! t$ g1 @. n$ [& u b$ ^
' i0 V0 q7 g1 m3 z* T. {
static void memPartSemInit(PART_ID partId)
9 d; b" t* s7 D( I! G& \{4 \7 g9 G5 T/ y! e) M6 Y) D8 e/ s
semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
) j( _, H! E0 l @* u, h! y5 K; i0 _1 @% Y9 _3 u% Y. }# V# g
partId->semPartId = &semMemSysPartition;
- T' \ p* o% K9 \# U}
$ U8 n; y6 |7 s, C9 v
4 z% ~2 l9 a; g: C- b, nvoid* malloc(unsigned bytes)9 p( m* E6 B* Z$ F1 b, X* F6 F
{
% c- K u- V9 f2 |6 a/ j, u" N return memPartAlloc(memSysPartId, bytes);
) G; u- j" h& V- u1 m2 ]}
( p7 D* Z- j5 J6 v/ q5 S5 @: S' I2 T) u% E/ f
void free(void* p)6 @: c+ U* N1 q7 [: h
{
2 w( f3 k: D: ?# l4 o memPartFree(memSysPartId, (char*)p);
6 o& ?3 M- Z' R* S}6 W8 u/ T0 f5 m3 s6 Q
|
zan
|