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