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