- 在线时间
- 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++下的版本,更方便调试。有需要请留言
- X. J% n0 q0 w9 q( k& n+ t2 l& F( G2 u! j- Q# |* }
) \) `* U& ~, _5 k$ y& ~5 ]6 }" q) @0 v' F$ n4 {
*\file' E! N9 u$ V* w/ U* T# w0 W# T
*\brief 3 `1 q1 B# k, W
*\details
& \5 j4 X6 g7 F# B# C( I3 W *
! |$ D: a: P) h1 \" z0 D; Y0 d *\author Janson! Q' g5 ?8 [# s, Q9 y4 t; t8 J/ e
*\version 7 u" z+ v7 Z# c, Q( W8 P
*\date 04Jan12- L9 g& u* a1 Q3 v0 ?: h: E
*7 M7 I9 z% \$ J; ^* O- \: p
*\warning , C/ z* D8 G8 h! q$ L8 B3 }
*& e" F0 C5 ?7 r, j+ x4 m) V6 G6 b
*\history \arg 30Jan12, Janson, Create the file
7 @* U4 c Q% F* \- i * modify from VxWorks source8 g4 |( a% Y( U8 p
* Legal Declaration: it is for studying VxWorks only.0 R. R9 o6 z6 O% }0 a$ c9 }; o
*/
5 x" e" l9 R" U3 ?+ D! v I#include "includes.h"
$ e5 l W' I3 o: x1 U
* l$ w7 M3 V' K% L/* The memParLib.h file is hear:
" q$ g/ I& q1 Ihttps://code.google.com/p/vxwork ... rivate/memPartLib.h
: c, c0 s7 r2 A( o* f4 R) c*/" D( S* R' q5 ^9 M. J
4 n. m; T G# Q1 F" F. N( t
/* optional check for bad blocks */
: e: r: g; n3 }
0 e; R. C* v5 ?; e( S7 |1 [* ]#define MEM_BLOCK_CHECK 0x103 X4 ?5 K- H; b* D6 x; W/ }/ J
" o0 }0 w' v* z$ @& m0 x' K4 s, q/* response to errors when allocating memory */
6 h2 I9 K/ w$ T4 F9 r. i& T
5 E, w0 _! r- U. `( o( D: O9 B#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
$ i+ b0 t" ~/ r \: l#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x408 p) R/ U! `& F) n/ d1 K
7 Q: [: R9 o2 z: r/* response to errors when freeing memory */" E% P$ G7 V% P& M* l9 d, N
' E6 N% d* s; T. v% _, J; K1 q6 W#define MEM_BLOCK_ERROR_LOG_FLAG 0x80' D, ]* `' U$ e5 A# B
#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x100
5 W" n- L9 b& U
' }; I) y: ?6 ~) W#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
# S" W( q2 a+ W( y1 f0 Z#define PREV_HDR(pHdr) ((pHdr)->prevHdr)0 j- U: ]( a/ f# Z. z
( I+ U+ ]8 r" |+ N$ g& y7 H#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))0 k' f1 }: k7 v( x
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
" u5 ]; X' B8 |4 M sizeof(BLOCK_HDR))): G. c3 a6 P+ k7 m
9 k# e+ x4 I; n7 A" l3 E#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)' q( \/ z) ?. V [8 f
#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \1 R5 z/ c4 Q( y/ N! @* k
OFFSET (FREE_BLOCK, node)))
' f; X8 f5 Y0 U* i) K0 m; y( B
. K1 D* X, c/ A8 m1 qstatic BOOL memPartLibInstalled = FALSE; x$ n3 J) m2 ~2 y
4 y8 z/ K8 I8 h
static OBJ_CLASS memPartClass;
( m4 I: i- ^6 a2 e4 ?CLASS_ID memPartClassId = &memPartClass;
) ?1 T4 |6 F" d- y0 D4 p% r0 |4 t) A$ e7 C
static PARTITION memSysPartition;
- f3 g: n N( QPART_ID memSysPartId = &memSysPartition;0 Y! z1 l6 f( a) ]
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
. I! m! |; C/ [8 v& d" S1 N/ A( x
) H9 Q2 x: R e9 i/ {( \) c# p/ B# estatic SEMAPHORE semMemSysPartition;
9 g' c( V/ Q9 x8 T5 H. K/ J5 o9 C% |% s
static void memPartSemInit(PART_ID partId);
7 J$ ?5 o# d H4 R+ s) S q5 p0 {. H
& `4 x0 r* M6 c( F$ }% u7 aFUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;( |" j! w7 m+ a* m# X7 |3 ]4 e( y
7 h! ~! Z3 S) ]
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;7 ?7 v* ~. z8 p
+ o4 J6 Z+ V% w. T, j4 Z* }' g
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
q; S% a" k% M3 H: I$ k+ Bstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId( h& |# O3 x3 J3 W8 z g% I3 t; `
, FAST BLOCK_HDR* pHdr6 b% m" J6 p* j* s
, FAST unsigned nWords
: Q2 n U. B, w6 t/ @ , unsigned minWords
' V7 ?; `9 B5 T& W' N5 ] , unsigned align);1 n1 h! n; ^0 u2 O( @8 x
3 b# H' g# O3 w* i) E
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);5 x9 \1 c* B5 }) n$ ]3 D
' E3 F% l; i, Z A
STATUS memPartLibInit(char* pPool, unsigned poolSize)
8 i' v9 {1 }* m! m% w% w9 H# ^{/ h) i. f% i- G, g' @, x0 }! I
if((!memPartLibInstalled) && ; _" {, ~4 h% H. J: z3 q# a2 l
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
; P9 Z" j9 B! t* K , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
, Z6 I, W+ p7 M {
0 b7 K; a1 q; x- Q+ ^ memPartInit(&memSysPartition, pPool, poolSize); L9 @4 k I, m3 [3 Z0 l: j& Y( k
memPartLibInstalled = TRUE;
b- X+ O ^& `9 i8 j0 z4 m }
6 `2 I% o3 X3 R% J; Q( z5 n5 r' ]' w) @! S- I2 z
return ((memPartLibInstalled)? OK : ERROR);
/ F& g! Q$ g) Z}
* `1 K/ }8 Q0 j$ r, q L3 f! m( J) k% v9 M2 e, ?4 R9 l
PART_ID memPartCreate(char* pPool, unsigned poolSize)
( z! Q: S, K2 T* d- m. z8 C( M. |{
. w5 ^" j0 b: b I0 H. _ PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
; a- P" D' @) E; h5 _' p2 F. S) J9 n, r
if(NULL != pPart)4 c1 b1 @ O) ^& o8 k P
{* z" z c; J% j% e% p/ Q$ ?
memPartInit(pPart, pPool, poolSize);
& ^3 P7 R. h% [/ o S }4 j% n( T1 P6 `
) m. e! Z7 c+ i& F3 ]/ J return pPart;
& g, B; y$ k5 x* n}
7 n- |; R, A; c! S" f4 h; n; [2 K, h- l/ ]3 k! \6 M
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)* p, S6 Y0 _ x7 U% l% D6 a
{
; z M# _' L( X4 K memset((void*)partId, 0, sizeof(*partId));
" g, ~( h9 t8 f, ]8 r. X
/ S# t7 N6 j9 I2 ~ partId->options = memPartDefaultOption;
$ F$ l" U p) ]6 S. g5 A partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */3 I# ?& m, R& L1 A# e
' ~& t. S) r/ O) E& t (* memPartSemInitRtn) (partId);
- n# ^ m5 V0 f ) W/ @) j& E( R, n
dllInit(&partId->freeList);
- R4 `7 e! q5 S( i) W( g! S9 } : U G: C1 N5 r# p, R7 e. ]
objCoreInit(&partId->objCore, memPartClassId);) \9 F) E3 U5 ?& I
0 g1 \* f; b5 B w. p memPartAddToPool(partId, pPool, poolSize);' }6 [1 J7 d0 m& x! r3 `/ l }
}- X) k! m: u3 W1 D) G
0 ^* A9 H+ L( W, u/ y9 O+ Z$ Q. [
STATUS memPartDestroy(PART_ID partId)9 H0 i$ o* D) ]8 \. `* q& Z9 @
{& }2 k" s# G, R8 l p
return (ERROR);
0 Q7 X4 D4 t) L/ y! X}
# S6 L; G0 f1 k. n* ~! Z+ H% o) V, _% ?' O
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
9 W0 u$ H+ Y; W% V{, o; k0 I; {( ?; X& s
(void)memPartAddToPool(&memSysPartition, pPool, poolSize);
+ C5 v! t" k2 B, v/ |- \1 e3 V( _}
x+ }9 h) n1 d; }: _
, U- `2 L/ S r* V
5 f8 H$ `' }, Nstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)4 U8 n5 z4 A3 ?; n) n
{
+ u& s3 U7 _, U BLOCK_HDR* pHdrStart;
2 T) e- _/ |' ?5 m BLOCK_HDR* pHdrMid;. D9 Z- Z: {) y. D- P9 Y& u- ~
BLOCK_HDR* pHdrEnd;- p* C4 f% i6 n
char* tmp;/ D$ @% x$ `& ]& p1 l
int reducePool;3 m" Z: M6 A4 m% `9 S* Z# l6 U
7 I* d( l" Z8 t9 A: m
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
8 v) P9 Y( s: u) H% c+ w$ ?9 A1 M {
2 C8 `/ }: v% j' l1 l3 w" [# Z( ] return (ERROR);4 l a8 q$ ?$ q' e6 B! a2 H. `' S
}
- ^% y6 O" m" L6 A6 b4 e
4 l+ ], e' G; g& P/ } tmp = (char*) MEM_ROUND_UP(pPool);* ~4 R4 G. d( ~7 v! ~ S) ^
reducePool = tmp - pPool;
@0 A; s" Y1 b( m% I6 P5 V3 G
/ U2 T4 e8 z; K /* adjust the lenght */
/ Z( L, @$ m+ Y. n9 S! E if(poolSize >= reducePool)
, C1 y9 @' N( s( W2 m {. R8 M7 t" b1 V- o# N
poolSize -= reducePool;( q* W5 g% N' k, R& |
}0 v* B( W; |. ^! F' T8 w
else# D. S1 c. F+ H
{/ E* R( L2 o2 p! W7 G1 e5 t2 ~
poolSize = 0; U0 P" X: c7 E0 h5 H* z; v
}# S. Z* R! V1 J7 ^( g7 g
pPool = tmp;! h7 A( B3 K2 S0 S# M2 E
" g& O/ x2 L: F6 ^' A
poolSize = MEM_ROUND_DOWN(poolSize);
' v, {0 I7 o% l# r4 W% E7 O# j2 R& w 7 W9 {$ ~1 g( t5 j# ^
/* at least one valid free block and three header blocks */
# g3 X1 P/ |9 `$ l, b6 S) }- P& ? _ if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)! ^+ _1 c( h* ]! A* @+ g
{% }0 Q' k5 b M2 ^
return (ERROR);
0 c* h2 S; Y; [( e/ A. Y$ ] }/ d. T6 ~ S5 Y9 C+ m
6 ^5 \! n: [5 ?; Y* d- {, h! f
/* initialize three blocks */$ [# X9 L$ l7 L& G0 i. A# @1 J
pHdrStart = (BLOCK_HDR*)pPool;
% u6 w% [. E( u& j* k pHdrStart->prevHdr = NULL;; c0 s7 h, @- e9 x; W$ x
pHdrStart->free = FALSE; /* never in use */
- `+ a7 M1 k# m7 x( M0 l) r pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;8 @. T: |+ B) O* F. W5 n
: d; V" x( E( B pHdrMid = NEXT_HDR(pHdrStart);2 l" Y- p8 Z" S; {
pHdrMid->prevHdr = pHdrStart;/ v/ z2 \5 q/ x
pHdrMid->free = TRUE; /* the main block */
: V& G$ M' N0 B pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;, D4 l) a5 B1 ?& x: c
) @( J/ Q+ h( a. L$ v pHdrEnd = NEXT_HDR(pHdrMid);
/ [1 |3 y) {+ w4 Y pHdrEnd->prevHdr = pHdrMid;
8 b, a$ c) P; m- ?9 s3 M pHdrEnd->free = FALSE;: U9 Y2 _) V8 e+ m% ~. n2 a/ G( @
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;, S! I# v0 E3 h) i
* D. ]; T! D/ Y" ] /* TODO take sem hear */2 p) p. H* g* o }+ S6 j
semTake(partId->semPartId, WAIT_FOREVER);
2 f- v, b( }& K) z8 v- T9 M
% O; ~& v( ?1 t' J+ i dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));. S) |1 T$ r4 | X2 ?/ ?
partId->totalWords += (poolSize >> 1);# M) G* c3 Z2 }& `( j
& `' W0 P9 t: {- G8 v# s7 h
/* TODO give sem hear */
4 g/ v) x0 ~/ N" d3 d1 q semGive(partId->semPartId);
& Z4 K( G+ {# M
7 ]% O" P( M/ h* N0 p& }+ W6 k- J
return (OK);& ^1 B4 M, l6 C3 ]% @% K
}: C3 ?* ^* w0 t5 T5 M7 o3 y' r3 l
/ u/ r3 c% }, ^5 H3 ?
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
$ H0 M8 q( h+ {' X I; R3 E{
. G7 @/ y: D7 C/ X; l. V H+ ] FAST unsigned nWords;
- B% P3 D% G' y2 D3 \ FAST unsigned nWordsExtra;( a5 d' }; T" j, d
FAST DL_NODE* pNode;
! @+ |9 D k! H7 E FAST BLOCK_HDR* pHdr;# t$ A7 `% {; n& t# m* g
BLOCK_HDR* pNewHdr;
2 q7 b! S- y; P4 M; `+ V; b BLOCK_HDR* origpHdr;$ i( }& n. T) M% h! b% @
4 n8 l$ G- _$ x0 ]0 A8 b4 t
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */2 l* @. o8 J N
{& E6 y* q- \% y( m5 c
return (NULL);
# A D4 }6 r* o4 { }, s+ ~" k3 b( u' s% T! L: f
* s, e7 r( p. N& x/ P nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;+ E! V6 p. l2 u% E- x
8 A0 j) d- P: i8 [, m }6 p% V+ q
if((nWords<<1) < nBytes)
- ?( K5 Y' L6 Y! V {
: X& g; C$ Y, z0 |5 C /* TODO suspend the task */" A$ _& D! Q( G4 q4 d S3 X" O
return (NULL);! }, w+ F2 M9 s6 C! a2 f: g3 @3 s
}2 C' f/ m0 y1 ~8 s1 B. Y* s" ?5 n: K
# H4 V6 Z- R! h; Y4 \5 r if(nWords < partId->minBlockWords)
8 o& r* Q3 a" Z% d* Q7 p {
) F3 i% y1 ~9 @3 W3 |; G7 z nWords = partId->minBlockWords;2 V" H& I K* H' {6 p3 i( H0 G
}
. @' E) c8 F" J: G7 }7 S) n H% S) Y" d [) b l
/* TODO task the semaphore hear */& G( e! _$ u/ @, ]- }( w# e/ Q
semTake(partId->semPartId, WAIT_FOREVER);4 u2 O6 n4 a' @5 ~
pNode = DLL_FIRST(&partId->freeList);9 ~3 Y. b N C: ^% P( a8 z
nWordsExtra = nWords + align/2; /* why? */
7 C2 Y. _& K9 v2 e
8 P3 w9 d0 ]) {9 k4 t for(;;)
$ J! x2 \& N; Z# t2 v S! a {
- V7 R% M5 |" X) U while(NULL != pNode)1 W* G% m- o) K z4 ]
{
4 S4 B7 { v9 p/ ]- j/ P if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
" D0 @ A B0 L6 S5 x) d ((NODE_TO_HDR(pNode)->nWords == nWords) && 9 J% U8 C" ?! |% i1 E, q
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
/ B) D) {( o& \- x( \$ c {
; J: C9 d. ]& S% q7 x4 F break;
! A2 }. v w' ~ ]0 O& M- A1 G7 f }
% s- H) Z U+ R* I0 H9 ~# `1 Y# ?0 Q; r O8 D- G* `! d3 o& s9 q# j
pNode = DLL_NEXT(pNode);
" @ w- n# m. e: H3 D& T0 }9 a+ |! E }: [: q Q* o0 o6 h2 Y' T
4 t' P$ Q |6 d6 a4 t7 |
if(NULL == pNode)
5 b$ Q1 i) a. M) b/ h {
& e! x+ ]' W. Z4 `6 h! t /*TODO give the semaphore */; l0 S2 o7 V$ J, u, \
semGive(partId->semPartId);
4 p/ u% e6 g/ m return NULL;) A7 `& z6 z( V
}
4 y( O; p4 I/ [. e1 ~2 c, \5 _6 O. I n* I
pHdr = NODE_TO_HDR(pNode);
6 Z8 D7 f. U: h5 M8 ` origpHdr = pHdr;
) P7 ^ B" k0 I8 S; y5 X' p9 }; z8 T" G, z1 e3 H
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
0 R9 }5 ~0 s T* |% o0 N6 ?: x if(NULL != pNewHdr)4 V0 C. w6 X5 @: C# Q% a- O
{
4 p/ c, \" n3 q+ B9 q: n; h* O pHdr = pNewHdr;
4 i8 h8 E- \( y8 Y# E break;- U0 ^* b1 Q3 @- k
}
5 E# E5 B n; ]( c$ b9 |: F6 X( |* D! @
pNode = DLL_NEXT(pNode);
- y; D. { V+ {2 q2 {3 t8 f4 N7 T }2 x- Q S8 m, \, }$ k
2 @1 D& Q) K/ G7 [; P* ^: q8 x pHdr->free = FALSE;; t) ^9 p% r# R+ c
partId->allBlocksAlloc++;7 h4 u& Z4 {5 J
partId->allWordsAlloc += pHdr->nWords;! _. s7 }9 |: E) e
partId->curBlocksAlloc++;
+ G( D% Z' B5 C: W$ }; D5 F4 H" c partId->curWordsAlloc += pHdr->nWords;' ?' z! Q/ U$ U) c2 S; o1 ~
3 a8 d/ [9 A& b9 i8 d: L0 | /*TODO give the semaphore hear */
3 F, u6 U5 c# \/ X7 B) ~' K semGive(partId->semPartId);
4 s6 _8 Y/ h6 T) N5 S+ w% A return (HDR_TO_BLOCK(pHdr));
0 C7 {. T2 m% s , ]3 Q% R7 L6 j% z
}
; o" @! C% i4 P y& Q( P b0 y. j9 m6 j3 I
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)$ K# |" R$ D' D. Z) z m i- s
{5 t) n' ?9 J3 L' s) Z/ s
return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
/ V4 p0 ?; H3 u( z9 ^8 c}# {1 @- L# m4 L( A$ P
0 S3 p0 J% Z' u- e, w! fSTATUS memPartFree(PART_ID partId, char* pBlock)3 Y) {' \" }9 a# A/ Y+ x
{- g y; ^5 K+ T: F o* X/ F+ \
FAST BLOCK_HDR *pHdr; e2 J. I7 }* w$ J, y
FAST unsigned nWords;
7 P, n6 b, t: T; h8 ] FAST BLOCK_HDR *pNextHdr;
, P" u4 T r3 h
S1 J9 y8 D7 U! t, \ if(!IS_CLASS(partId, memPartClassId))
( D2 M( \' w y7 c4 { p5 X a" F {
, Z9 p# q2 [" K: c return (ERROR);! w8 r. F/ J8 B5 q
}
, J) f! T( _* n8 O2 S0 \
( w+ @# n9 A0 V6 e if(NULL == pBlock)6 U/ C3 n. h. ]3 A, j" q# `
{
9 n C. e9 l5 B/ ?! B return (OK);& z7 Z; @9 h9 \( G
}! y- l/ i. m. ^4 N; P
7 v8 G6 |0 G/ Y9 M! \0 L" g
pHdr = BLOCK_TO_HDR(pBlock);/ q- F: ^% D, a }
6 X, q* \0 }( q) @ M8 E: i semTake(partId->semPartId, WAIT_FOREVER);
3 q5 @ v+ v$ N
( J- g2 K. ]6 m% { if((partId->options & MEM_BLOCK_CHECK)" H3 J F( \- ]# Y. Q
&& !memPartBlockIsValid(partId, pHdr, FALSE)). W. J6 _; a# c( p- y' Y& D# g6 ]
{
7 }% j, ?, B* ?1 ^& L. {* F semGive(partId->semPartId);; A. e) A7 g2 D( K, I `* t9 W
return (ERROR);
4 L& |" J+ K* s# t# D }+ x) V) v! t( h# j0 b- f
* i- h' F8 {0 X+ K% K nWords = pHdr->nWords;& z1 Y4 p+ b9 C9 n& v5 c" P3 z
if(PREV_HDR(pHdr)->free)$ W. R! b: u1 I A G4 K) g* P
{/* the prev hdr is free and than coalesce with it */# \# s/ ^. j/ W! ]0 ~
pHdr->free = FALSE;. l8 C* R3 T) [9 R; O6 m% l; K
pHdr = PREV_HDR(pHdr);
0 N2 }7 ], H3 {8 x) j% [) m6 F pHdr->nWords += nWords;
3 s, H. B3 z1 ^+ v+ X }
% w( B( ?0 v& R% w2 K else+ K- N$ C. x7 x0 w6 C. ~
{- ^6 S+ O4 V N9 t5 w: d
pHdr->free = TRUE;4 ?( V: H: T/ W0 T: Y( G( P0 e8 J6 o
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
- B8 A% W3 g4 F4 V: V3 Y }
$ ~% P+ P& R4 ~9 R7 d- W6 r! U# g- K5 R* Y9 M
/* check to coalesce with the next */
/ D/ E1 N$ R" g/ p pNextHdr = NEXT_HDR(pHdr);
5 J/ z/ I% o+ R( r if(pNextHdr->free)( z/ X9 H: W8 f
{9 L. @# _ i2 s( ~
pHdr->nWords += pNextHdr->nWords;
. R S& Y7 d* z: z) _ U3 D dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));4 w# }& I2 J! M6 n& e! P0 Z: ?; T6 T
}' k- b$ y9 O1 h4 } c# s+ C
# v* c( `6 X1 ?, I% S /* cannot use pNextHdr->prevHdr=pHdr hear */
" b! s+ y. J8 N% ]0 r NEXT_HDR(pHdr)->prevHdr = pHdr;, S: r3 q/ d2 R
! m* E( n: d0 R0 `# a$ K+ n" Q; g
partId->curBlocksAlloc--;
+ H, i6 h0 r4 L8 w" j partId->curWordsAlloc -= nWords;
9 M* s# `2 Z9 F, B$ c+ e6 A, v1 s
/* TODO give sem hear */
8 Z2 m+ X4 \* g8 t* J semGive(partId->semPartId);! _: F# ]6 N% f0 }
* M7 u, l6 V/ i( D8 `# c: U
return (OK);3 K3 c4 a, w/ g) o/ S
}# A, X5 Z3 G5 S! }5 U# G: k
- }4 ~6 N2 g q0 }6 ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
. w" o3 T# P) F( }1 u{
& V4 N5 I& C4 i( W+ w- n BOOL valid;
3 S. m/ I6 _- O8 `$ a0 `% q9 W2 L
TASK_LOCK();0 D* s( B/ S( Y; |/ F/ t2 t
semGive(partId->semPartId);
$ ~3 W( J! V' I, V 6 K% M3 {, H* z
valid = MEM_ALIGNED(pHdr)1 m. e- \9 \6 u; Z* b9 N; J
&& MEM_ALIGNED(pHdr->nWords*2)
% N3 s% ]9 j, j& [) S && (pHdr->nWords < partId->totalWords)
" U. N; W1 \; }' T && (pHdr->free == isFree)- [9 f" O& T9 H l
&& (pHdr == PREV_HDR(NEXT_HDR(pHdr))). o! |" \! W. S( i9 @+ l1 b1 ?
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
5 ]& S2 T" p7 G& E- y - W1 G; w$ a3 ^/ @
semTake(partId->semPartId, WAIT_FOREVER);
# O* ?/ M4 X, G6 Z% t$ H TASK_UNLOCK();
+ r0 O2 D/ D I; A4 X( |: t8 {" I' ]/ E
return valid;# D/ {+ ^) F; v3 R+ O" Y$ t
}
8 c! Y% S, U, k. }. d8 r0 n1 f2 N; Q( w0 e' K
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId8 t4 L+ w+ y7 I$ ]9 x* r, w. T
, FAST BLOCK_HDR* pHdr! v/ b7 M& \$ d- Z# B0 Q
, FAST unsigned nWords/ l+ w; K7 X7 n% J" ?
, unsigned minWords+ c* _! y6 k2 }/ r% a( r1 }( a& y
, unsigned align)' J' `; m. L% F. Y t
{ o; ^( P h* p; m0 F# m- Z0 G2 ~9 }
FAST BLOCK_HDR *pNewHdr;* @: x* a4 o- u6 f8 B; A- O# o5 t
FAST BLOCK_HDR *pNextHdr;5 e7 S8 _5 F; `+ j2 t1 H
FAST char *endOfBlock;) }, ?% ^% O+ k. j. x1 ~
FAST char *pNewBlock;
3 x( `8 P2 x( S& c( A" d6 J6 y- V int blockSize;
; z. r; `; J5 p8 P, g. q1 ]2 k* O! o- a; i( V- W# C4 c
endOfBlock = (char*)pHdr + (pHdr->nWords*2);
& S4 K0 }/ ^2 e1 C1 U4 p& ~
5 H5 t- u1 F" Y2 D pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
: O% E; S* h7 C' z& h8 t7 w; p
/ G* @; ~0 w7 D) C+ ^$ d; r0 q1 i pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));( d8 ?: p4 m- o9 Q i6 [6 r8 P
+ M& [) R8 G8 ?4 k. |- \/ v
pNewHdr = BLOCK_TO_HDR(pNewBlock);& G" r( K3 O$ l( C5 @& X
6 w$ R: [3 j: Y! ^4 H
blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
7 w6 a7 [* K, y9 K9 N- j ^4 w* y# D- b$ ]
if(blockSize < minWords)
( L" x& R( h5 {; W4 y5 Y! R$ H. s: W% G {9 m3 I4 z$ Z7 g* O1 m. d" o/ E
if(pNewHdr == pHdr)& I3 J/ `" ?/ W) E( J
{* ~) A, [' D& z0 |. n8 W/ ~
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));9 I" b8 Q8 b. W5 C1 `( m6 N
}
( n9 g! n, p7 L. f else, J( `+ L% k5 B" H$ d% F/ s
{
; Q9 A- t" L# c0 H4 [% Z1 a return NULL;
' [/ D7 ~/ G4 N+ l: B }
* [. ~5 w4 Q" o# m, c' ~$ B+ [ }* I8 t3 z: w# H N, C* L4 T
else
* L; r& r, h4 D0 F3 Q+ F { /* recaculate pHdr */
, J3 ?1 B) P; g# x pNewHdr->prevHdr = pHdr;
& R! h5 p* M, E9 K1 N6 i0 u' S pHdr->nWords = blockSize;
+ J0 m5 ]# a: m: g, R$ J }
6 x, `; l! C" ?4 r1 }; n) h1 ~8 C- M$ w4 O
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
% g a9 s5 l3 R% p ] {! n. O- X! A+ T- S8 J# m0 _
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
: `' g9 ^. K* U9 O1 q pNewHdr->free = TRUE;0 W/ M V' d" `9 ]) _, L
2 m7 Y/ u( Q' l NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
' J8 j- }" H6 g+ b3 d }4 k# `& V9 L C9 p
else& m' n2 l; i$ X( `5 Y
{/* space left is enough to be a fragment on the free list then */4 e# y' ~1 H3 c: L! [# j
pNewHdr->nWords = nWords;
- A3 P' |: O) t" Z" N% { pNewHdr->free = TRUE;. P2 r. M7 p' r8 h3 z# R5 i5 y
7 v0 _) I( W2 ^7 Q* E8 Q
pNextHdr = NEXT_HDR(pNewHdr);
6 B/ Z/ x: n2 ~) ^. _ /* words 包括BlockHdr */) ~3 i3 F, f X5 J/ `5 p+ y
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
; P$ V& y# \$ C0 T pNextHdr->prevHdr = pNewHdr;
* a D0 \. ?8 M$ y1 f pNextHdr->free = TRUE;! Q" Q6 U. A5 [# P5 L4 N0 A
& n; l1 m: \* |' X% l dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
7 r9 {" s6 P2 _4 q I, s8 o8 F
. \ F- F: N, m* f NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;+ }6 I; X) C. K P' Z) o! T% B
}
1 S$ J. L% K7 i$ {$ g% R( k2 K" h3 R) y8 C+ \0 E/ ?
return (pNewHdr);
, [! S0 H+ x0 F* S}/ U) o5 ~2 l9 ?" n0 w
- `' J( u+ r/ C3 q8 Dstatic void memPartSemInit(PART_ID partId)
3 `# g6 E# ]0 q6 y o6 L; h{
& | f8 J6 Z# {- Y% v semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
7 T. S: S( U& T. w& ^8 _, q* ?
# h# Q, \- B+ X3 b% E partId->semPartId = &semMemSysPartition;
2 z) d; x7 E( e M} s% F9 C: b1 F+ |4 ^
- g, K9 B6 R) {$ O7 c
void* malloc(unsigned bytes). ^: v/ v! K a3 M: ] l+ ?
{
1 W1 }* y$ f9 c: M4 s; G1 x return memPartAlloc(memSysPartId, bytes);
$ B7 s. `) S. Z4 j1 a}7 t" L/ A4 B' C/ e$ k6 T( k
" f6 O; J8 i( l7 \1 Qvoid free(void* p), y8 Y0 r$ o# p$ v6 r
{
! H0 J3 p+ y. B0 q: i+ X memPartFree(memSysPartId, (char*)p);' ~" m* f0 D/ N i) \
}
% K A1 W3 D# }9 A* @% k u |
zan
|