- 在线时间
- 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++下的版本,更方便调试。有需要请留言
2 v" a- `0 W H& S r
; g+ a a! X6 x. y9 P3 Z/ V, B$ R8 H% |& d5 I2 Q
; s2 v9 d' U) | *\file: a: P ~) `4 r) g6 c
*\brief - b1 j& u; }2 G" r
*\details
5 I6 u9 o& o' B, O* j: l' ` *
6 ?) S8 x. h7 B/ M0 c- I, {% {0 g$ W *\author Janson" t* {3 R V$ v# E
*\version
. M5 J0 m1 ^$ B" i. { *\date 04Jan12
, q- G" ^% k3 d" r" w *
2 v5 ^& `1 w. m: D1 R: d$ ^' z *\warning 0 ?% E9 u5 @$ w1 n# Z2 y9 D
*
F8 o9 C `4 x; R3 w *\history \arg 30Jan12, Janson, Create the file& n% v# @ |( b( h0 s' F
* modify from VxWorks source B2 N$ u/ J; a# |; J- m
* Legal Declaration: it is for studying VxWorks only.3 O- K: e! Y! T% |
*/
! K {/ t, U) `/ W#include "includes.h"
9 h2 s1 q5 Y5 `( ` i% m5 D5 U' f) t9 G, Y; z, V5 J1 Q9 C
/* The memParLib.h file is hear:
h9 g8 [; ]. n& C0 ]8 J uhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
/ T# l1 y/ I# c*/
# p% ~. D n6 `2 U1 E8 E! J: W% c1 G* t' u* M
/* optional check for bad blocks */
7 L/ o% M2 v. _1 s- R+ p2 z; h
6 i3 P( O' x0 ~#define MEM_BLOCK_CHECK 0x10
2 o; K3 z6 _8 J( a$ J; D; x' g3 r3 Y/ ?0 M. v2 F# Y
/* response to errors when allocating memory */
% S. F, h# @" x4 U8 t; d
0 p5 M, R2 X/ \& B1 g#define MEM_ALLOC_ERROR_LOG_FLAG 0x20
5 M6 N0 K; k: t& N! M+ ^#define MEM_ALLOC_ERROR_SUSPEND_FLAG 0x40
- }/ v4 O( C* }) [4 l4 d) o2 Z# H% F+ P/ y3 z5 J! U/ w
/* response to errors when freeing memory */4 p' o* W8 n. t
, c# P6 ~ f7 H7 P U#define MEM_BLOCK_ERROR_LOG_FLAG 0x80
& K& l& {7 b8 y2 J! m' c2 p#define MEM_BLOCK_ERROR_SUSPEND_FLAG 0x1002 C7 l6 a4 o$ h. W& @" w( E; D! ]
4 R7 H- C1 R7 q- I7 U$ ^
#define NEXT_HDR(pHdr) ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
w4 U. J" j5 S3 U* n#define PREV_HDR(pHdr) ((pHdr)->prevHdr)
% r) Z8 w, ?# h2 O" Z0 c; i/ M1 H$ E7 j' h& \' X
#define HDR_TO_BLOCK(pHdr) ((char *) ((int) pHdr + sizeof (BLOCK_HDR))): I# h. v' \" ?; j: ~6 Z) I: d
#define BLOCK_TO_HDR(pBlock) ((BLOCK_HDR *) ((int) pBlock - \
5 z- y: }( L: e1 a+ e- U/ M! I sizeof(BLOCK_HDR)))
( R+ s0 v k: m1 f) O) ?) W. {! x8 u: m
#define HDR_TO_NODE(pHdr) (& ((FREE_BLOCK *) pHdr)->node)
' E) `4 F( S) h- \& e$ {$ O#define NODE_TO_HDR(pNode) ((BLOCK_HDR *) ((int) pNode - \, Q" o- F2 E' V8 s
OFFSET (FREE_BLOCK, node)))
1 Q7 d& b* b" |8 D- M' ?
% s0 Q6 o" e) w7 `4 wstatic BOOL memPartLibInstalled = FALSE;) t# P9 c( {! D! R4 F* q) z- R
' z) ^* ]: E$ H0 n! u1 F N/ Z2 fstatic OBJ_CLASS memPartClass;
; L# l( z0 B( q$ ^; d, UCLASS_ID memPartClassId = &memPartClass;2 g/ ^2 x3 w& a7 B5 f5 l. J, ?
* t0 r) `( j% {- v# H* [
static PARTITION memSysPartition;
~8 e2 T( ^; G; B4 j* \PART_ID memSysPartId = &memSysPartition;' q* v4 v {! [+ k {5 b1 l
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
) V) n. r. _: [
! U% ]) g8 F# {) f6 D/ Pstatic SEMAPHORE semMemSysPartition;7 c+ ?. H$ I- w& U$ O" \* r
: _+ D( B# h/ g: M* y$ }9 z
static void memPartSemInit(PART_ID partId);3 i7 N8 W; o* T8 s
" {3 x( G5 Z4 U1 |" F% F4 V- W) Z
FUNCTION memPartSemInitRtn = (FUNCTION) memPartSemInit;3 h9 p1 q% Q8 v
w; Z6 h2 L# Gunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
2 {: `4 U& d1 ?3 A* [
D: i ^9 I/ A, @* nstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);: ]% e0 E5 e6 o! L( U
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
: r6 V( F% N- Y , FAST BLOCK_HDR* pHdr
5 B+ {1 u% t c4 t" V2 |- Y& [2 J: B , FAST unsigned nWords
4 a2 ^- G+ L6 Y) S% h9 R , unsigned minWords |1 i$ S( b# C# x" w! D
, unsigned align);
/ ]% W' ~! _( U0 ?, s0 N9 `8 a/ @' p6 g
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);- a; D; m" C4 ?) f9 Q0 A, [
3 ^) |( v) ~8 i9 QSTATUS memPartLibInit(char* pPool, unsigned poolSize)
' k' t# } z5 c- y1 S0 T$ @, d{
) f9 O0 f/ `. v8 Z9 L if((!memPartLibInstalled) && : C" X- ^" L& m
(OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
$ w4 [) F, [8 Z; p2 Z , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))5 }/ a( C. z# A9 [) k1 T. R
{
+ K5 M% n8 I E2 T3 R memPartInit(&memSysPartition, pPool, poolSize);
$ c. j( C3 a0 N% K( ^& w0 G3 S" H memPartLibInstalled = TRUE;
) [" l, w& Q" h" D: g }
/ w. f! Y: W- M+ I F3 R$ ?- r; o% E' Q9 @$ q. r
return ((memPartLibInstalled)? OK : ERROR);
! l3 k0 v! D9 f! a}- P I- h6 ?( ^& S7 o8 o7 y
9 f; m" c" K' q! W2 e
PART_ID memPartCreate(char* pPool, unsigned poolSize)
6 j6 a+ ~% D: [; ^5 ?{- h* t3 P. x/ Q" m) I+ Q
PART_ID pPart = (PART_ID)objAlloc(memPartClassId);' F8 v6 u; [. t
9 r- J- _5 t# F9 K* o
if(NULL != pPart)% c6 F! F" `5 b# m" u; y- I5 x, m1 u
{/ r) ^6 r. }' g l6 {' R
memPartInit(pPart, pPool, poolSize);
4 w* v, b. o4 r+ U# E7 S }7 X* _! Z" `9 C8 V
" j4 |: y2 F$ K return pPart;1 v! u) k, Q" e$ W: q7 |% l u+ R0 D
}! m h& ^, C4 `7 M- R# \# v: _
1 d6 s/ m, I8 @$ y3 ]2 U8 a8 a* X: fvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
. O8 u( U7 ~& w) L{
+ K! ^0 K" z5 G' f6 J- p* p$ j memset((void*)partId, 0, sizeof(*partId));5 E% \( ?$ |4 A4 H
: F$ F w5 r* u! H7 i
partId->options = memPartDefaultOption;9 F( P! e4 C- ]/ S
partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */4 N* W# `. n! n K/ z2 l5 P+ i3 R
% v$ [! T# ^$ o4 t7 Y1 t4 P9 [( [' a& c (* memPartSemInitRtn) (partId);9 D/ Y; i8 `2 S' Z6 h7 e! K
|7 O% o5 r. @: O dllInit(&partId->freeList);
6 y8 H% @4 i3 R' U6 n& q
9 k4 P& d( @$ v! c5 g# L, L1 ] objCoreInit(&partId->objCore, memPartClassId);4 F. s7 b# T2 O
" g: P! N( i8 k+ w2 m
memPartAddToPool(partId, pPool, poolSize);
+ ~. h5 h6 c/ a* A5 M}
. I. ]/ {+ C5 Z; a8 y7 _' j, h0 w% A ?7 Z" p- p8 i) L( D
STATUS memPartDestroy(PART_ID partId)' U5 D4 V2 K. ^% T. ]- b. e
{
, v. k6 b4 o5 G return (ERROR);
/ h* D A( r) Z$ H8 b7 d8 g}
0 j0 n9 e5 Y) D4 b- H
8 W. Q1 W/ O4 L7 X6 M3 r2 ovoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
' T7 y7 S( k4 e4 k{
" C7 E- i7 y( P; V. a7 y$ r (void)memPartAddToPool(&memSysPartition, pPool, poolSize);, m( u' x4 U* Q% O: W. v+ z7 i% b
}0 S' B8 h6 F4 B9 X9 [! D3 d& y9 F6 L
7 s5 `. G$ u- ` N, n
6 S( Y0 e7 l! z. D. ~ l4 W
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
7 n( k1 ~! c: q# \3 ]8 v! {: v2 d0 X{
# z( D; J4 @+ j, T% ? BLOCK_HDR* pHdrStart;7 s& C0 O5 a) j \$ S
BLOCK_HDR* pHdrMid;' {* g/ x! A( E; W$ o
BLOCK_HDR* pHdrEnd;
; S: T3 o4 E! T2 }. A char* tmp;
6 t9 j4 r$ }' I: y& K2 V int reducePool;
# B+ Z) w' \, d
6 L, t' v# V! i& [1 D if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
: h( V! f, u' l p6 J1 ` {6 D' [. b% l1 o: M i% \
return (ERROR);7 n5 X2 {% {/ r; J- h/ A$ R6 j
}7 `$ [2 \9 A4 [* j. y1 f0 a
: H* N M# p$ ~! U, e
tmp = (char*) MEM_ROUND_UP(pPool);( R# P! ?3 k% E$ `/ t, { r
reducePool = tmp - pPool;8 {. n5 Q. b/ T; N( Q
( E+ ~# j- p/ T B' ?: {$ h! r5 p
/* adjust the lenght */+ N. k( [0 O$ r
if(poolSize >= reducePool)
6 M% c% i. g* ^: l; E {' w% l8 j# b. S4 Z4 h
poolSize -= reducePool;
& J& Q) D4 U- A& W" ] }
: M0 N- }# w% H; K$ Y' T* i/ `8 m else W, J* J4 n3 B( h+ @( Z2 r
{
6 F" c( @5 M u6 c6 s0 i J poolSize = 0;
% A0 s D. f! L4 b }" E4 e' T3 l+ E, i
pPool = tmp;
! O" h7 P" O/ P# l* E , w; z' f$ p Z7 l4 j# c
poolSize = MEM_ROUND_DOWN(poolSize);( [6 i% s7 b! k" y$ t! d& X
/ f. I9 b: u: ~
/* at least one valid free block and three header blocks */
$ i9 h5 n D$ N$ n- O# V0 f ? if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
) U# y4 M' {% P- M- ?, v+ Z {
4 V: U8 S1 k. {2 } return (ERROR);
( }4 j: ^8 a- M6 F2 h/ g }( I3 Z. K% i* }7 x
+ M" B6 s4 m/ K: O /* initialize three blocks */, a( U8 J. L; x% o( p+ T
pHdrStart = (BLOCK_HDR*)pPool;
6 \" [/ J: Q, Y' c: a8 R F pHdrStart->prevHdr = NULL;1 a( x; U# d+ m+ d+ _
pHdrStart->free = FALSE; /* never in use */
; }6 W; \! |6 ]7 Q8 L$ h% Q! ~ pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;4 c0 C) E ]! y9 ~. i! ]! c3 `
/ F( c Q v/ q
pHdrMid = NEXT_HDR(pHdrStart);
0 v7 }8 f* c2 E- e# v8 U) z. l pHdrMid->prevHdr = pHdrStart;, D% T) _3 b! C
pHdrMid->free = TRUE; /* the main block */
0 u. i: c! t4 t# Q pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
. ~' y4 ]% w9 g* a1 y4 e6 w! z" ~' R; m; R
pHdrEnd = NEXT_HDR(pHdrMid);% u0 t u ]8 ~7 M
pHdrEnd->prevHdr = pHdrMid;/ T1 i( ?5 ]% V) h
pHdrEnd->free = FALSE;: ^/ t4 t3 S# c$ Y6 @3 e
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
7 j0 o! E& R, _* p0 L- R: P5 E$ \5 m4 L
/* TODO take sem hear */
0 T0 j+ ^! v1 U2 L- R& ? f semTake(partId->semPartId, WAIT_FOREVER);
) }+ g6 I! d2 K
4 C# k' e7 w* N; `; X* v3 C- } dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# \+ Q8 x: A! P6 Z3 u" u
partId->totalWords += (poolSize >> 1);( E% T6 ^& O0 A, C- c8 y
6 V$ E- F) s' \# f C /* TODO give sem hear */- E, t8 E4 `/ [- I
semGive(partId->semPartId);
0 b, j" h+ f8 ~3 t; X) ]& P. f# q% {9 X3 M; J
" s% A; E( S1 m; j
return (OK);
( Z3 ^! N1 H& b, N/ s}" N2 g+ T% J; m+ e+ \. v
6 m5 X2 J ^6 z! b/ ]9 Kvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
, Q: s8 H/ v( K# y" F3 m: Z' l{
V ?1 h& o) m0 A2 w FAST unsigned nWords;
5 ~$ D6 r* r* z4 b FAST unsigned nWordsExtra;# {$ Z( t1 ~1 s& w& {' r6 q
FAST DL_NODE* pNode;6 V8 v, K" f* v' l4 u, I
FAST BLOCK_HDR* pHdr;
2 U1 t' j! E \% d BLOCK_HDR* pNewHdr;! b2 D% V$ G8 {5 s! G' Q
BLOCK_HDR* origpHdr;
: U3 x% Q" P! @, W4 g6 h) b( Q6 M7 E2 Z& p3 |3 y# i" u# ^5 p# k
if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */
/ j1 Z2 r8 h; f# }" a, \ {
/ m* c' H/ |% z3 o6 J3 T* d return (NULL);! e! I* G3 v5 m- B E
}9 v6 q# r! s3 P$ M8 E& l% Q# q/ z
8 B+ f% w' O+ v* W7 y
nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;* Y' N, M* Y: y' J6 f0 r
! U6 I: @, q# p2 m6 S. s if((nWords<<1) < nBytes): c' E I4 {5 r
{
/ Z# u- J) c; J3 I& i /* TODO suspend the task */! w' {7 Z, G5 Z) ]0 K* [
return (NULL); x/ ~( J3 ^% V" x
}4 B% w6 X% | f7 L3 W6 \& a
* ]' S9 x! p+ S6 N8 k* l
if(nWords < partId->minBlockWords)
2 z' I- }# h+ Q; \9 S, m {& k0 ]. u6 A8 h
nWords = partId->minBlockWords;
: e8 X3 X; t& ^0 H }
) [$ M) I8 m- q4 w
?8 e, H" v! y: x, c /* TODO task the semaphore hear */
. w/ U4 C, c$ g) g; @0 @& U semTake(partId->semPartId, WAIT_FOREVER);# z4 W! C+ e2 N% J! s& i* \
pNode = DLL_FIRST(&partId->freeList);$ l; Z/ n0 r! O' m5 K
nWordsExtra = nWords + align/2; /* why? */
0 R+ G% J5 v* W
2 [9 h# {' h8 m8 D for(;;)
+ W+ F$ x( l/ p( o5 _9 L7 G4 x {
& W( r+ ^; m. \# a9 w( U while(NULL != pNode)
8 o8 _) w! F5 U* m {/ w/ j( [* {7 `1 Y
if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
' g7 }3 z/ v/ z0 U4 |; a0 o ((NODE_TO_HDR(pNode)->nWords == nWords) && ( E) m! i. V3 \) u. q
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))" `0 K/ M ^1 m+ n) C
{
% z- d3 t. E& Z3 Z break;
$ _' `% n o# y% T, b- D }
/ T$ x8 H) }$ X& C! f: Y: v1 {8 u, N9 n7 F' M% ~" k
pNode = DLL_NEXT(pNode);
4 m5 a( D& |9 s. W5 a* {) u: R }
! v7 D5 B3 d, P2 N; T& f/ u8 a9 z
$ r* V# w9 J* o, G3 o% s. M( Z# K if(NULL == pNode)
/ g& k9 n( z4 o3 ?5 {& }7 r {7 ]6 n, ^( h& A# |7 w8 f
/*TODO give the semaphore */
0 l- I) e7 h( c4 D5 N semGive(partId->semPartId);& q# g- ~8 G2 ]+ V9 k; g& q Y8 y
return NULL;
+ H. i( W B' A) x1 b$ g7 } }' V/ ?2 Q: E9 r( v- a1 z3 q
N" F( q5 r. l5 i6 d8 u2 I
pHdr = NODE_TO_HDR(pNode);
: H4 u- }1 j. E origpHdr = pHdr;
: C+ Z+ u( o! O. M3 z4 N6 w8 B0 ^5 W0 j+ f9 y: S& M( J4 Z, b
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);4 D6 u- j! C; Y5 A% C* j
if(NULL != pNewHdr)
5 l/ F; t% n* @, u. O! L- O {. x! k: F J( Y+ \
pHdr = pNewHdr; J3 J' |) r ~) t0 A# t( L% ^
break;
) Y; G" W: ~0 \ }4 }4 T" K/ d7 R4 H3 E3 V
6 [. G$ ^3 P6 C, P" L
pNode = DLL_NEXT(pNode);
, B+ T4 P; @: y G+ Y$ `. v7 g, r. [ }
+ v4 X7 h+ i; i% B' r1 S- E
9 d% n& Z) q2 o2 ? pHdr->free = FALSE;( f+ K9 A. S z6 _4 h" Q9 r3 u6 O
partId->allBlocksAlloc++;( ` z0 E0 d P. Q5 Z4 h
partId->allWordsAlloc += pHdr->nWords;3 l: `6 |7 p* _% x% }: ~. `
partId->curBlocksAlloc++;
9 Y: J/ e8 ]3 d* D+ C; ? partId->curWordsAlloc += pHdr->nWords;) \7 g) S) h% c
! b* D! }7 B- f$ Q /*TODO give the semaphore hear */$ Y! V' l. b" Z C% Z3 _$ |
semGive(partId->semPartId);
; K% \' q/ S1 _, S2 f$ K' Q% K return (HDR_TO_BLOCK(pHdr));3 z5 J5 c" D" N8 ]' ~) e; e7 t
* i: V& ?' [. G1 ~3 G- H R}
: k4 P" R9 F2 j9 G# @8 l7 Z1 p+ Q
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)" m3 u/ @" f. G, `% B$ S7 F+ c
{
" c7 L$ B1 K- k* x return memPartAllignedAlloc(partId, bytes, memDefaultAlign);# I; N) w$ N' F0 N! s
}2 _3 }- L9 ?) |! ^5 x
7 }( T1 F$ U* f! _# i8 J4 Z
STATUS memPartFree(PART_ID partId, char* pBlock)
4 Z6 K) n6 A, D{
8 ^4 b8 o% N) g0 J, X) o% M5 r FAST BLOCK_HDR *pHdr;; R/ K1 }- J* I* u- ?6 a9 C1 V" y
FAST unsigned nWords;
% w9 I0 s0 c5 K \ U- |1 u FAST BLOCK_HDR *pNextHdr;8 H$ k3 ]/ ^$ U9 R
8 d: M7 @4 `. ? if(!IS_CLASS(partId, memPartClassId))- W% |# D. k+ h3 u) p {3 x e F
{
8 Y3 T" F+ {& q) O1 }3 b6 J: x$ e return (ERROR);
! Y9 t, A" i% c! Q6 d( R3 N6 I+ A }
2 X- T# r8 h( _" \1 y; U" X5 b6 k! f
if(NULL == pBlock)
' o& u, j9 w8 ? {% D9 T+ z! m: i; Z) D/ c4 [& [0 p- L
return (OK);: p4 M8 X" B9 u5 L: w& o, [# j! i
}$ W1 |9 }7 f9 q4 c: e( Q* L
E2 o/ a. b8 {# e) ~9 c pHdr = BLOCK_TO_HDR(pBlock);8 S6 A: _9 z' F5 C* H9 l
; {; `5 {% |$ H# ~; q i, B
semTake(partId->semPartId, WAIT_FOREVER);
7 E# F5 w9 o1 \0 d2 G: }7 P9 d+ Q7 v; ]- O8 B6 ~$ D4 u
if((partId->options & MEM_BLOCK_CHECK)+ {5 ]& ` z! g( K3 }/ ^& z5 R
&& !memPartBlockIsValid(partId, pHdr, FALSE))1 E5 q' a: b% k5 b% c+ K
{6 R1 N, T7 y/ m8 [: I! I
semGive(partId->semPartId);5 d# \8 b, r0 l: Y) H
return (ERROR);: o/ r3 } ~8 C G I9 _+ `
}- C' @- j) R$ T' g& ~1 o
& G( Z1 I6 n+ M/ z# i. o+ f5 j nWords = pHdr->nWords;
8 f/ r- r7 [: f+ _8 Q- Q& {' X if(PREV_HDR(pHdr)->free)
+ v0 H* v, C! u* j1 u+ Y" ] l, ` {/* the prev hdr is free and than coalesce with it */4 m1 K3 p7 A. T* K0 b" @, o
pHdr->free = FALSE;
& J7 [ f+ e* k- v$ d pHdr = PREV_HDR(pHdr);
3 @! V4 K* `, U$ C& L _ pHdr->nWords += nWords;& n9 f. ^6 n; R/ `$ L
}
4 F2 k1 X. t6 C6 E3 {7 @ else
( o" q/ E3 x8 z4 P8 A {
0 |+ s6 `, v# j Q6 z pHdr->free = TRUE;9 R! F$ e I' E
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));/ P$ P! t9 ?3 l/ h" ?, I! n+ c
}9 U) l! `% e9 K; H& v& [
& U- I! y" M. Y" v$ y9 m1 N% F
/* check to coalesce with the next */' v# U' c6 n3 e% J
pNextHdr = NEXT_HDR(pHdr);
/ [$ H0 V& Q, a if(pNextHdr->free): \4 F, u7 p7 l( H. S
{
* H& @& C5 Z+ t# A. u pHdr->nWords += pNextHdr->nWords;% j; e, n5 \9 N5 X% F
dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
! `$ J8 X% U+ ~% C' ?& R( { }
0 j D: B# d% p" ]3 g
! u& k. o1 X. ~; j; |+ _% _0 ~ /* cannot use pNextHdr->prevHdr=pHdr hear */& Z D6 j: C* o7 p4 A, I5 B! Z
NEXT_HDR(pHdr)->prevHdr = pHdr;0 z7 B, L' e; Y3 m" L; L
1 I+ w0 M1 E d
partId->curBlocksAlloc--;, y; M5 ]7 |4 |- C/ K: n0 C, h
partId->curWordsAlloc -= nWords;
- Q$ p# u% {( S
6 q* Q! i- \4 {3 M, ~ |2 o /* TODO give sem hear */
0 w2 n/ f/ _' g& m6 D semGive(partId->semPartId);. n0 y; v+ o7 g
0 e' f* x: e7 k* B6 H U, Y# R) K% w) t return (OK);
1 H6 J4 P( a$ f3 g: \" e* C% _! L}: l6 H* x4 {/ {7 R
) b! [' N& o0 kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
7 F( _8 f, ^; `9 ]) T3 f* E{* O1 Z3 [3 T6 }, K
BOOL valid;! k% e: x1 u. e! L; M" F& l
$ P4 ? P- D' q2 \6 h3 ]! Z TASK_LOCK();' W" Z& ~7 o3 |4 J6 E9 L' M( m
semGive(partId->semPartId);1 g+ e: R+ ]' @, }0 P9 z, |
2 X6 f' C2 G7 W4 T: X% d, ^
valid = MEM_ALIGNED(pHdr). L7 Z% {8 G* \& A1 E. i
&& MEM_ALIGNED(pHdr->nWords*2)8 w& X! w$ J- ?
&& (pHdr->nWords < partId->totalWords) 6 U2 m Y. O0 `
&& (pHdr->free == isFree)
! u6 x* |) t7 `$ P2 u8 J1 ^ && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
# B6 R$ ]2 o( u && (pHdr == NEXT_HDR(PREV_HDR(pHdr))); d! v, C5 c1 y/ B6 N# j
' j7 [; @) r8 a7 G" A) D! V' D semTake(partId->semPartId, WAIT_FOREVER);
" q4 q m" [6 S+ O1 l% c2 T TASK_UNLOCK();
( t, _. ]" e( h. V5 R
! C9 ?! k1 _6 _/ V' C$ Y& x% K! o return valid;
$ J( ?9 X7 K( X# I8 r/ o, j! {}
' b4 B! A6 P" `$ D& a9 R
* P6 N& L% i4 v, B- v% ]! Qstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
, C& M* f3 u. G , FAST BLOCK_HDR* pHdr7 @2 S K$ T! W
, FAST unsigned nWords
% X# j2 W; |. L- t+ p: s- B , unsigned minWords& |1 ~9 r' o4 v7 V
, unsigned align)- z' y% f& F8 Q# ]( T3 p5 ]
{7 S: D! }: W3 r9 J# c
FAST BLOCK_HDR *pNewHdr;
/ W+ D/ n( m+ b( J FAST BLOCK_HDR *pNextHdr;- s! B# }# ~$ n( r
FAST char *endOfBlock;* j' a' z. K5 E% v/ _- t
FAST char *pNewBlock;+ o5 B; u! B5 p) [
int blockSize;
{- [- G5 F/ N8 B% T" k7 x) i2 f% T4 S( D
endOfBlock = (char*)pHdr + (pHdr->nWords*2);$ A5 k Z8 a6 b
9 Y2 V! p9 s) Q7 D, ^# g2 q2 H
pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));+ e. I2 f* }0 i9 u+ f- e/ B
5 ^4 |8 x3 M }$ k pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));! h, O1 a# ~$ S$ g) s6 T7 k8 m, R
, o8 R( k4 i {( G! P# h" _3 L9 q
pNewHdr = BLOCK_TO_HDR(pNewBlock);" J5 l# y/ ~! ~# D0 s3 E" I
3 ?7 h$ Q; ]" M+ |1 v) b blockSize = ((char*)pNewHdr - (char*)pHdr)/2;9 J+ W5 F' f+ K' D
- H: Y5 y8 `, ~# h, v# g( p! Y if(blockSize < minWords)9 z9 F, A! e( p3 k1 v
{3 W+ \" n& k# B: D) _5 c
if(pNewHdr == pHdr)$ V- d0 P2 G' M3 o1 ]9 H/ N4 _
{; X! P+ [' q @9 d( O& [
dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
: T0 Z: _3 j& X4 q) D }
+ B* }8 U9 n' _ X else
, J# a& q5 Q/ |, W3 z4 n* { {
/ D' b) {) q7 X# R$ s, b0 k return NULL;
& g. g3 q5 C7 s0 s4 @ }
7 j/ a$ L- c4 T0 J/ p }$ X) p! g# G% t# N; Z3 k+ s5 C
else
) n! Y: |4 @" c# C. n { /* recaculate pHdr */
" [2 a1 d% W/ O* u2 {4 [' L4 U7 Z pNewHdr->prevHdr = pHdr;
- b' M. `9 q1 m3 N3 Z9 ^ pHdr->nWords = blockSize;* Y# F+ @9 Q W' m5 I/ Y% H
}
3 T8 l0 q/ h% U/ H: Q' B7 ~) f0 a
if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
; A5 r0 C* D4 d- h M6 V; N4 x' [ {1 I! u% o1 W. K# O, f3 J
pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;2 j' s7 E: P: ?) F6 L7 ^. P
pNewHdr->free = TRUE;
. p ~3 A7 h0 m: L
+ l7 ]0 y3 q( A' e) F8 O: } U NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;, M: H1 R# \7 W- {. I+ q( n
}
0 n! J% @& }; i- C. J else" M: r* J. i4 V9 P7 Y* M
{/* space left is enough to be a fragment on the free list then */) {: M% i% m1 X4 X
pNewHdr->nWords = nWords;
- }4 j5 v3 \& m, V/ t/ P pNewHdr->free = TRUE;
- Q2 O. V' Y: J* D+ u
0 R1 |6 M4 W: r) w d q" Q pNextHdr = NEXT_HDR(pNewHdr);1 |# H4 c. J/ h. a! B9 J5 I
/* words 包括BlockHdr */ {# ^# c5 Q. a: z9 M# o$ j+ I% C
pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
0 r2 F* w# u0 K pNextHdr->prevHdr = pNewHdr;
3 w$ j9 F$ _4 n' n' ?# s pNextHdr->free = TRUE;
! s. Z5 c! k; D* T+ a" {
8 g a0 a( a' O b. M6 X! k- d dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));0 V; O/ K- S* ^) M
, g' j3 s m3 Z: V y1 n- ?! Y NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;3 A, _1 _; W- x% W8 q. W4 N
}. B4 R# c5 {; j2 J
# q! D) [2 ~* e" Y3 l return (pNewHdr);- Z6 R6 z6 ~& g' I3 \
}
, }5 y0 n) {6 n. ^7 Y' Q' q; S! C# `% X( I2 }
static void memPartSemInit(PART_ID partId)9 ]8 x! N$ i, m4 X6 S3 m. x( ?
{
4 \% T) o' O6 q2 q V5 Z& L semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);' v& d/ Q) `" ]3 y( {
+ t1 W7 J1 x9 D2 B ~+ J
partId->semPartId = &semMemSysPartition;1 @" r9 d( U' L& u
}9 N: Y4 O8 t3 d
/ b& X( O" p& V( s" ~
void* malloc(unsigned bytes)/ N: ^( {+ L, U9 N$ y- z7 a/ \( T
{( w: H- O3 m0 D- N+ G0 Z
return memPartAlloc(memSysPartId, bytes);
! v @0 ?" T# x2 J o}
5 _" x5 {3 D6 [; r( H
& f- ]. x% p& s2 y' z2 M. Fvoid free(void* p). x- @: q3 y4 @0 N7 q: A
{8 z2 T% m! a+ c- T3 H( V. z
memPartFree(memSysPartId, (char*)p);
; J/ U" G* b5 z4 g}& M$ e" M# Q/ h9 ^' B
|
zan
|