数学建模社区-数学中国

标题: malloc(内存分配)在嵌入式下的一种实现 [打印本页]

作者: wangzheng3056    时间: 2013-7-26 10:17
标题: malloc(内存分配)在嵌入式下的一种实现
想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言7 j+ _2 o0 }5 ?

5 p/ ]3 n+ ?6 S& ?( \4 |) a% i9 b( a3 L) j# l

2 W$ E1 g( Z2 S* ~! c/ C8 B *\file/ `0 C, d+ m; x. B0 Q
*\brief                ; m. P& A8 c# W& t; K1 B) |4 P
*\details       
: v" d; x' R) N/ L( c' e- A *
& ]2 ^# V% ?# X+ R2 Y0 [ *\author        Janson3 l3 J: C, Y7 m3 u. H
*\version        - \% x/ W3 |5 g" |6 F1 n
*\date                04Jan12* _9 R9 p- @1 M, Z
*. L. X$ v" {2 M  `* T! E$ U
*\warning        $ ]7 G3 |; N' f& e) T4 x
*8 G7 K$ B0 L. Q7 \6 M0 c% n
*\history \arg        30Jan12, Janson, Create the file: e' }( C" w6 L2 f. M+ N
*        modify from VxWorks source- \2 e; A' B' Y" z+ e9 O% i" c+ Q0 K- w
*  Legal Declaration: it is for studying VxWorks only.; }5 e- D/ b' c0 [: H: ]
*/
6 m+ K) e$ ]# i! o$ d' g  m+ c% b#include "includes.h"
. f% b0 r7 B, X4 m1 m: Z3 @$ Y
4 T* k/ H$ A: `, ~3 [$ J/* The memParLib.h file is hear:
9 |. C5 O: y* `# Hhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
4 O$ H  g( Y3 {* N3 J*/; ~6 O' N' c/ O) Q- \. ?" ~
5 g$ Y( p$ X& U! P; A% Y% E: k  G5 W
/* optional check for bad blocks */
" `% g& ]4 H3 |! F' r& |  Q2 ]0 w1 M8 g
#define MEM_BLOCK_CHECK                        0x10
: R" ~% h1 M8 g8 Z1 p
! u+ p2 g/ d/ I, E/* response to errors when allocating memory */
8 g7 M) R( S. ]( e& |
& J* s$ M4 [3 E- P5 U+ L#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
0 O! R) X1 I' S3 f. y1 q#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x407 L) N* z- N  ]2 F, P6 V

( J  {  G3 o' A( y5 J* j/* response to errors when freeing memory */7 e8 i( a' g8 v& l& Z$ W. t2 c5 ^- G
" }1 j# G- G$ m7 P+ z$ a
#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
1 P* n. c& G/ i#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100) n) k; f# [5 L. ^( l9 F2 K

( |6 {$ r  }( q( ~8 F$ @8 o#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
, ^  n  O: }& A9 k5 V* _0 V$ O, T#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
: C  F6 a7 U* r! X& v% T, J
/ o8 I  ?5 x" V2 U#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
" K( U% u4 H0 \$ R#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
% p7 ]! c9 {5 I3 S6 I                                                sizeof(BLOCK_HDR)))
4 ]2 f" E. T% E2 U$ H  t+ w% y" |' `& J
#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)3 f' o/ w7 W/ u
#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
/ F% c) b/ M5 e( k7 q5 c0 \                                                OFFSET (FREE_BLOCK, node)))
: p; u2 q4 s/ k& B
8 R( L& o0 T$ m( V6 \static BOOL memPartLibInstalled = FALSE;
3 S  ?# ?# X1 J3 s
5 O, q4 B# {; J) k* cstatic OBJ_CLASS memPartClass;
0 ~) }& h3 ?4 D2 [CLASS_ID memPartClassId = &memPartClass;7 i" J$ _; h% D. F

1 J1 G# F! @: Y; f! Bstatic PARTITION memSysPartition;$ c7 P, l$ P7 u( m8 y& u# M" J$ y
PART_ID memSysPartId = &memSysPartition;
; n# D4 E2 n' f* |8 nU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
# R! X) J  S+ m7 J& ~8 _4 J6 A; t) W
static SEMAPHORE semMemSysPartition;% |, A& @0 a: w: N1 J' W. m; U; J% i

# `. U6 t; I/ o" k( N0 y. s- Rstatic void memPartSemInit(PART_ID partId);" f- r" a' ?0 I' ^

& J+ N8 Z$ ]+ wFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;1 P4 A& i; k* h; y3 ]/ R$ C2 y

, y8 D2 i: O; [+ I! R+ uunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
7 Q) W( o4 ^: P6 f5 i3 |
/ p8 Q* ?- e2 a- u; a, l! ^static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);: v( G+ g- a3 ?: |
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
" z( l* O7 v. z8 E0 C/ Y, f        , FAST BLOCK_HDR* pHdr
2 j; }& U# I4 y9 L7 O+ s( t        , FAST unsigned nWords3 y2 \! L# Y3 r7 P/ F( J
        , unsigned minWords: I5 y& Q- ~, W* c$ t: l. H
        , unsigned align);  c- {# [5 H/ k/ T; E+ j& [) L

! k* Z4 S: Y3 Cstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
5 m3 d, E6 H) m. k* h0 t% T9 Z1 I
STATUS memPartLibInit(char* pPool, unsigned poolSize)* B, I* @$ X  k: [7 U7 [+ Q
{1 O$ ~. \* m2 S9 E+ X
        if((!memPartLibInstalled) &&
5 S- E3 a/ `8 J0 Z9 Y                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)4 `; v/ B3 K& |
                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
" j: b6 ?. O  @        {
3 M! o. E9 a! N+ h4 ~  D                memPartInit(&memSysPartition, pPool, poolSize);' E2 O& K- Q6 y
                memPartLibInstalled = TRUE;0 c! P& f) M  U7 x+ s2 Q
        }" w, N/ A5 D0 B8 @5 @5 f
2 o* P( v$ U6 s1 C, e' L5 T! B- R
        return ((memPartLibInstalled)? OK : ERROR);2 C" k% `* l4 h& e- H/ t) y
}; }0 b2 V" Z1 h, L; Z( @
! g( o' C- b+ x9 T; i
PART_ID memPartCreate(char* pPool, unsigned poolSize)
2 i! t$ p. r# l{
; e/ x% P, R. q, H+ s6 V% `0 G        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
* h; O' m  S6 K5 y$ U& j  `5 t. Z1 M  x: c# f6 d
        if(NULL != pPart)
2 v' O: S# J9 ^0 C) o' f+ z6 |        {
+ G" u5 U- i2 r                memPartInit(pPart, pPool, poolSize);* r! Q% s! h9 |1 L) p+ d: G
        }
0 [& T. |7 ~  z; A% M$ W3 H2 X8 b4 U8 {* b0 V: n! s; o
        return pPart;; l! S0 k& v  r# o3 r" G/ \
}' ?( u  m3 F' h' c. L" a8 V
& T0 \2 U9 {0 K& h
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)5 e1 N( ^* j. s( N& T
{( f: c: _* A- y/ \! ?$ ^* }' _* X
        memset((void*)partId, 0, sizeof(*partId));9 b$ P' Y' L0 K/ x, x

# S/ \( g+ b9 K        partId->options = memPartDefaultOption;, u& l! B2 D, i3 a' L
        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
" @5 w' g& d4 O: ]
# i0 E( p6 Z. i' D8 l        (* memPartSemInitRtn) (partId);
4 D' {5 ?. E7 \       
% D" }9 e& C# ]% T        dllInit(&partId->freeList);
0 @; w( {$ ~2 }( [  K- l        1 p* G7 B/ w, |
        objCoreInit(&partId->objCore, memPartClassId);" e* o/ v. W6 k5 a5 _( c
       
: w9 _, d' `0 _7 A% D: c1 K        memPartAddToPool(partId, pPool, poolSize);$ |3 c/ W7 u1 q/ ?- G7 E# D
}3 s  {  e) D- D& ^2 M

9 r8 g) Z" E- i& E* u* FSTATUS memPartDestroy(PART_ID partId)
7 r3 a' r! o3 T+ r8 d" }! Q{
4 T' i/ g2 r$ y( ^9 b        return (ERROR);
* f. l$ F, L' J4 s4 [  _7 Q}
+ N! c3 |+ n9 o! g) x7 R% _, M% E  y* ^6 |
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
8 n% T, A- ?; K& r{8 L8 t, }" n# t+ \. G6 w
    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);5 d! n3 k$ m/ J( I8 a/ R
}4 S& z$ f/ t3 }6 ?0 N: J% R1 c- G
, W; v0 C) `0 q
8 l6 Z7 |2 n) R7 h; a5 C5 q: S  e
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)* S/ n; C3 ~  z$ o
{
" q! `/ J  P8 s        BLOCK_HDR* pHdrStart;# g' r+ i: p1 W, t0 l
        BLOCK_HDR* pHdrMid;
) V# k$ {$ d3 c' @9 _! A# g        BLOCK_HDR* pHdrEnd;* z. A5 Z# y- i; Z/ i$ M
        char* tmp;" G5 D5 k# Z$ s- a. i, a
        int reducePool;
8 p9 B& P% L+ a3 k9 c$ T& g, n
0 S: _* V3 V6 g) a2 Y8 K% V        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */" W( a0 |% B5 P7 u4 @. a) W4 Y1 o
        {
6 u* P1 r" G& R5 I+ C3 U                return (ERROR);
7 N/ ^3 u/ }! \0 c1 Y8 K9 Q        }
9 F. m$ x) n- d" a: h8 b) Q
2 o! B8 e/ p" h5 G5 w1 [        tmp = (char*) MEM_ROUND_UP(pPool);
; F9 v* e8 u2 B        reducePool = tmp - pPool;
( h4 }2 L+ w- K$ ]' H# x" S/ P8 _1 M; j
        /* adjust the lenght */
( {- I/ v2 z: `9 n4 \        if(poolSize >= reducePool)
+ A, L+ \4 |) Q: s( {  \+ Q        {  X$ u; e6 p# p. F3 ^) J: @- b3 K
                poolSize -= reducePool;
, Y( r* {2 `+ {        }
/ o% J+ W/ K0 k& d# X* Y        else. v) a6 C! Q: j9 B$ f
        {, ^( ?& o! ]1 x) [7 |" L
                poolSize = 0;
, y* ^% R& ~2 M3 C& `9 ^8 B        }
% N, Q# R- h7 Y% c+ h        pPool = tmp;4 E* w, x* H4 B% N
       
) h# b& w( P, u6 f        poolSize = MEM_ROUND_DOWN(poolSize);7 i3 C% r5 O2 m" ]2 q- Q
       
' e/ P9 }1 ]& L" p. H        /* at least one valid free block and three header blocks */
7 ?8 ^) e& Z- n8 y9 X; v        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
8 W/ r0 ]. q4 O$ v. S& g: O/ @7 z0 L        {* |. j' i& u- Y; F  l
                return (ERROR);2 M- i0 H- H" G* p( v% v
        }
6 r% y7 C* ~2 k. j$ z: [0 z, G1 x3 e# H# s+ @$ N
        /* initialize three blocks */& M; c- z" X0 W
        pHdrStart = (BLOCK_HDR*)pPool;6 B( E9 ?$ b9 i! v4 K1 y( d, o2 `
        pHdrStart->prevHdr = NULL;
. N' I' ~: o9 @$ `4 h* t        pHdrStart->free = FALSE;                /* never in use *// M% K- J0 Z1 v5 v, ]
        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
( i( |# j3 \- |$ ^0 A( P' g$ g2 X( P% L7 d' ?4 o. u, [
        pHdrMid = NEXT_HDR(pHdrStart);/ Q' s4 E2 {1 v( f/ F
        pHdrMid->prevHdr = pHdrStart;3 r% H# ~) G: Y8 l# L' A
        pHdrMid->free = TRUE;                        /* the main block */
* c/ }% K5 B: D+ C, z        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;3 e& E4 G7 Y7 _

) o( t: ^' H  T- h9 \' v. c2 s! f        pHdrEnd = NEXT_HDR(pHdrMid);, V# u2 B! N( c: F& a3 @+ I
        pHdrEnd->prevHdr = pHdrMid;
: ^, m6 r. j0 p; c6 h9 Y        pHdrEnd->free = FALSE;
7 R3 E0 B- W9 m9 U7 N, L% \        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
# `. c2 b" ~1 _8 t9 S' e, L5 g% y( _9 l  o
        /* TODO take sem hear */; }7 }; I# y4 ^2 U$ M
        semTake(partId->semPartId, WAIT_FOREVER);
" R( u/ p" }( c9 E% a; {       
, X* Q7 q9 C" N5 I7 ]7 n+ _        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
" ^# k6 H. y; z. S) a* K        partId->totalWords += (poolSize >> 1);9 s0 Z/ B) L$ B+ l+ V2 I

# s' V1 T& R' J% I; g: r7 p3 c- L        /* TODO give sem hear */6 R6 a" U) S: |1 ]! N) d
        semGive(partId->semPartId);
. `5 n) H* a6 v& J( y4 e
6 G; F8 D4 k2 b9 w2 ~
' ]5 [5 h1 L% p& }9 b5 n        return (OK);) m4 ?7 V% B0 I& c7 J% r( M
}! K: r( g) D0 F1 P6 E! g) f$ i

% t, L2 S  S3 Lvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)) ~1 c( Q, `* x
{
& V5 n& b3 `" D9 g3 I6 }$ w        FAST unsigned nWords;' g4 s' y3 z8 g; {7 n. K
        FAST unsigned nWordsExtra;
" B' u3 \0 x& v5 u/ S        FAST DL_NODE* pNode;
" H4 N6 ]8 v8 T+ @        FAST BLOCK_HDR* pHdr;& ~  G/ y5 K4 I' E$ D+ @3 N# s
        BLOCK_HDR* pNewHdr;
$ R+ [& w! z# q" W; H# o, ]0 f6 z# U        BLOCK_HDR* origpHdr;# u4 y" L0 O$ ^0 C/ W
& z; y) {* l$ L6 S8 F" T5 N
        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */$ o+ D6 m, N) O$ [. e8 |
        {
( Z$ j# p6 W) a/ }; T7 B7 e; o- A% r  i                return (NULL);1 ^& N6 D+ w& ?
        }
3 s7 i' X% J' A8 t$ i4 B! z
) P) i. }7 l. D$ i( D( X        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! i+ X; L, y) _& a/ T' P$ l, t
! V: b+ v8 j( j' m
        if((nWords<<1) < nBytes)4 r* u* k0 {) S8 r2 R, Q. c
        {" `1 {8 T4 j9 }$ @  U% M& A  F
                /* TODO suspend the task */
( ~. b$ O0 n. N; F/ K4 M& ?: U# s                return (NULL);
5 u+ c+ C5 N# Q4 _        }6 E8 E+ V) X& T7 c; _

2 S& M5 b. I4 R/ C  ]        if(nWords < partId->minBlockWords)
5 a6 r6 D9 F8 m5 A# _0 z1 f        {
$ R( O6 q0 M. R7 i" B" ~                nWords = partId->minBlockWords;+ [+ M% y& J8 `6 F
        }5 }& z* y( E9 E* Q; A

. P" ]: i* v4 _/ a. a1 |        /* TODO task the semaphore hear */8 t$ S1 [) A, t! H% S: B" h
        semTake(partId->semPartId, WAIT_FOREVER);
5 p% a, s9 D) d$ p0 u+ p        pNode = DLL_FIRST(&partId->freeList);
" h) @! u( G( q& u; J9 H        nWordsExtra = nWords + align/2; /* why? */  j- S* `. |2 b8 P8 o2 Q3 s5 i
' H# Y% B% l2 m) ~8 V
        for(;;)/ X1 `5 }; g" e' j8 m% R4 f$ t
        {
0 l: T! k# O' \7 k) M; V                while(NULL != pNode)
0 w% N9 p" g' I+ E: l; [+ \                {
5 F/ e3 \' N* X+ j# s6 z, e                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
6 F0 s5 e  i8 [3 q: r4 F                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
2 ], p8 \: s5 ]4 {                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
4 }# f9 {4 j1 t1 d- M6 g  C/ C7 n                        {
$ d- f. z0 l, n- b8 ?0 F                                break;% @& h) s, m8 _9 X3 z0 i' A2 U
                        }
6 i: Z. F& I' ]/ ?7 [
3 ~& ?- s  t0 J6 ~" V5 |& j( }                        pNode = DLL_NEXT(pNode);# H  A: `3 I$ O$ `# h+ J5 D
                }
- |6 n! \; x& N/ `$ ?; f6 @
0 Z  y& m) U5 n0 M& V$ N                if(NULL == pNode)
, G( m2 z8 p7 t                {
- q& c$ C- Q! P9 `1 ^7 h2 s                        /*TODO give the semaphore */
. b/ L9 h6 N( z1 _8 K) Z3 ^                        semGive(partId->semPartId);& |$ _. U0 I$ b% H5 u: V
                        return NULL;3 B1 Y( F: y$ u" J3 |/ j) l. Y+ {
                }
7 n$ A: h9 w! d9 g! |" U! O
( h: m5 o" [! ]" P+ V                pHdr = NODE_TO_HDR(pNode);2 n7 H: k+ W8 X7 d2 e
                origpHdr = pHdr;( A; w5 s- g2 O0 H4 b

- b& P) I/ k) m  E                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
: B' t- {; g' Y9 w- B$ [7 q                if(NULL != pNewHdr)
  Y8 _* G# |! e9 ~2 H2 r: R                {( D% k6 d; p( N& n* ]
                        pHdr = pNewHdr;
; W, ?0 l+ X, a% f9 v: L                        break;  N9 f* C; T$ Q' t4 r; `0 w
                }
( Y8 l( U- a+ d+ C0 w1 z. a5 D" Q2 M1 e8 A
5 Z& T  P3 f; V  a0 `" |/ F                pNode = DLL_NEXT(pNode);7 t" z: R5 j) ?2 ]: [; i
        }
; _( k* z" I( j2 {1 V; J5 V! s3 E
, h. O6 N* ^5 I& T4 U        pHdr->free = FALSE;
* Z  {7 S+ R2 f- B        partId->allBlocksAlloc++;
" T: V" D. o+ R" w2 o- q5 D3 g        partId->allWordsAlloc += pHdr->nWords;5 I: \1 c2 a: ]7 X
        partId->curBlocksAlloc++;
) m* ^; Q0 u, ^/ ^        partId->curWordsAlloc += pHdr->nWords;( ?. e* T) O, j! H3 V4 @

/ s  F! P5 P, y( G4 A        /*TODO give the  semaphore hear */7 T7 N/ ~1 ^8 c, r
        semGive(partId->semPartId);; ]/ j7 e7 Z0 a- u- H( o
        return (HDR_TO_BLOCK(pHdr));: D& l7 p+ ~5 C
        - ~4 P2 o1 C' B) E' X
}
$ R( v/ G: S0 v4 x- A3 }9 ?9 f7 Z) p7 |$ \$ [, B
void* memPartAlloc(FAST PART_ID partId, unsigned bytes)! _. `1 X" x$ F
{
& C( l8 n  n. W4 r8 x7 ^  ^        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
% h9 q' T+ m4 }}# Z: X. Z3 ~$ w/ Z. }! _8 {& {" o

! U( ^9 A6 {+ l+ p3 {. E: ?STATUS memPartFree(PART_ID partId, char* pBlock): V7 w7 y8 s- [; O* w4 ]
{
" ?. H3 f" ?! [9 k, ~        FAST BLOCK_HDR *pHdr;  n, h* j7 i3 U2 L! V, x
    FAST unsigned   nWords;
8 h0 v1 y8 h. X& f, ?2 }' D    FAST BLOCK_HDR *pNextHdr;
! ]% W* Y2 f; t) i# v
3 X' T7 o0 c! y# Z4 w3 a: l        if(!IS_CLASS(partId, memPartClassId)). o4 y) D0 ]3 s* v0 K- h9 b* b
        {
3 z5 r" H9 d. T1 s                return (ERROR);. H/ P; S: M' ~5 ?3 o& ^% \
        }
/ D- U! |& Y0 _' L
' @- {# \" n5 |/ p- M9 Y        if(NULL == pBlock)
' n' a+ |( _2 ]: E( d8 c0 Q        {
' C8 l6 L- n, v8 @) r                return (OK);
6 l% y, X  a) k        }
3 e, t/ |0 y# N' ?
, n% z9 u- w- S$ P" z3 h        pHdr =  BLOCK_TO_HDR(pBlock);
/ y7 Q. `7 J) O/ r) ?- d& ?6 t2 C- q( i8 @/ n8 P& H8 u
        semTake(partId->semPartId, WAIT_FOREVER);
0 ~& i6 y% p3 ~# {6 j  _9 p8 O- o! f, J8 A
        if((partId->options & MEM_BLOCK_CHECK)8 b  K" T, W2 U" d# {+ E: l
                && !memPartBlockIsValid(partId, pHdr, FALSE))
1 B7 O1 b5 X& m7 v3 i" R8 @2 Z        {  k4 l3 f) o- b
                semGive(partId->semPartId);3 ~% a# u7 e4 q+ \
                return (ERROR);
. V  v( j: v- x; l4 R1 b! j        }
! C9 S& i% Y7 `  l
- ?, `! b& P: w- y/ w- W7 u        nWords = pHdr->nWords;
3 W, I, K/ i" `% N9 r1 U6 w1 N; R+ X) S        if(PREV_HDR(pHdr)->free)$ {2 t, ?! o- f- j( ]% e
        {/* the prev hdr is free and than coalesce with it */2 i- G' D( t. y  q
                pHdr->free = FALSE;; I: j+ q: e! q
                pHdr = PREV_HDR(pHdr);
5 V3 C: \8 g' V8 A; w                pHdr->nWords += nWords;
4 n  E3 \% b& N  ]7 i, I& K        }9 I6 R% |/ `$ |  b' u4 n6 D
        else3 g3 N8 Y0 {: X; e; o( ^! I
        {5 b' x8 X& v$ K$ L2 }
                pHdr->free = TRUE;
" A/ j! I' ?( c3 b: l9 M                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
% s  m: M" b7 l1 @! u! e        }
8 u* j& A/ _- u8 ~/ }' ^& O, G5 F1 _5 r& |$ ]+ p+ G% \" R  \
        /* check to coalesce with the next */1 G3 H+ W0 a' w7 [% C$ z
        pNextHdr = NEXT_HDR(pHdr);
; a3 O1 s0 j) W" [- W* H6 ]        if(pNextHdr->free)
" z# T( y% Z, K- d        {
3 l; L+ x2 w' t& |% S3 W                pHdr->nWords += pNextHdr->nWords;
9 h6 D1 Q: A$ e( U' S- t+ r% e                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
! d. k1 w% C: f: N# y0 W        }! ]  \2 J: o9 r% q- m1 z0 G

3 W+ Y, n6 `; ^0 z; C& v        /* cannot use pNextHdr->prevHdr=pHdr hear */- H+ Z  R8 F2 h+ u) {7 o. R
        NEXT_HDR(pHdr)->prevHdr = pHdr;, o  j3 N: N! t0 g9 V; U
3 q, E  w" y) n; n, q
        partId->curBlocksAlloc--;
! }, l$ R4 N  e5 j# P7 l% ^        partId->curWordsAlloc -= nWords;
; ]$ P7 ]6 |8 R# C  V) i& h4 g
+ E0 X- [6 u4 D$ k2 r7 g- f        /* TODO give sem hear */
! K' Z9 m* F. i: X7 o        semGive(partId->semPartId);
5 W4 g" j4 ^8 S        0 z7 t7 W& G- x
        return (OK);
0 [4 W% t4 S  z2 P$ F) m" w4 C}
3 v# b$ d2 p4 R* R  n0 T
7 c* x4 [, \& k& Nstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
; H) p* V' o+ E9 I/ o{
0 Q) I6 w9 L  e: N        BOOL valid;* O4 S" j/ P: Y4 C8 B

' d3 x3 H; p5 S9 W  B        TASK_LOCK();3 ~/ F+ o+ N& t" s9 y$ Z9 p
        semGive(partId->semPartId);1 V7 N; G5 D! I  F! G4 e! \
          {; F/ k5 m4 v/ C! Z' N! j
        valid = MEM_ALIGNED(pHdr)
( d: a4 o. [) G        && MEM_ALIGNED(pHdr->nWords*2): w- h8 a: p) Y! z
        && (pHdr->nWords < partId->totalWords)
7 ]# r9 z& `: n        && (pHdr->free == isFree)
, i, J! k8 }; O! Z+ E. R6 x. q        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))' g5 k7 m2 ~5 M5 i/ y% y# c
        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
+ ~3 K/ y3 }  L0 f8 ^3 z       
7 S) t1 j" z5 k& a3 B        semTake(partId->semPartId, WAIT_FOREVER);
5 O1 O! c9 ?# W4 n; ^! [' }$ Z# N        TASK_UNLOCK();$ x% E  g/ X5 I; k4 Y4 v% U, P

: N8 r0 v; u0 j, c$ R* F        return valid;/ P& z: a) b  F. v9 `
}& N$ F- n8 f# Q- }5 B+ G3 z' W7 ?

) _' ]# m; i4 d. m, d- r0 Ostatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId' j2 p; F) q# u  n/ l
        , FAST BLOCK_HDR* pHdr% N8 u( U4 Y: h# i& s# K4 S
        , FAST unsigned nWords
7 W( ^$ z) @! P, N1 {) V( V* w        , unsigned minWords' _4 w2 s4 O9 \' o; t/ J3 X; k5 i
        , unsigned align)* ^' s$ e% |: Z+ u; v* {4 n1 A
{
% ^* d* o) `6 x        FAST BLOCK_HDR *pNewHdr;2 m3 _1 E$ c# e# C
    FAST BLOCK_HDR *pNextHdr;9 k' w; o7 V$ t
    FAST char *endOfBlock;) H! G4 v0 q, j; L4 p  Y
    FAST char *pNewBlock;1 d, `3 d1 ^  u  l, A
    int blockSize;8 H1 S* ^, R9 G$ l4 Y+ V2 h0 Z0 [
0 V/ C9 l* H' L: F- {: u- F$ y
        endOfBlock = (char*)pHdr + (pHdr->nWords*2);, |& T/ ~9 U$ a. ~, e$ T

) R9 F4 S& u. D3 }        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
7 R, j6 e- |1 R
) a" p1 `0 [3 v' z6 t" J% o        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
2 n# s8 d. W' @+ L0 B8 O+ R7 W  ], }( a/ ?$ M4 Z2 S
        pNewHdr = BLOCK_TO_HDR(pNewBlock);) ?$ `: u9 v1 j& |" h& t+ d
6 u4 d  ?2 R' Q
        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;) Q) ^* `: O. h; r' W
, j4 l. Q$ |4 B% W! v! P. f
        if(blockSize < minWords)
# o# v7 W4 c' ?        {
0 x" B6 Q  N; @+ a" R. O8 R                if(pNewHdr == pHdr)
- L; S: q% P- @' a; d4 D8 J                {0 m/ s" s7 F: O" r
                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
) n5 F( _  }# z% A& K: J                }
; m: [. t3 T* n7 u: e( o- f, M2 q                else
; P: C6 t* R! M; _- p% U; w                {
0 p$ M1 `6 t5 V                        return NULL;' I$ p& a8 W. o( h) D
                }$ P7 k" O0 a* Q6 T/ Q
        }
/ C; k1 w( t& E% q& L% a/ q        else
' O4 G( {2 K% ?" c5 [* w2 w        {        /* recaculate pHdr */
1 a: B/ |* R0 }$ y                pNewHdr->prevHdr = pHdr;! [3 t4 J3 }& C* ^/ P
                pHdr->nWords = blockSize;$ L) r: ~9 y1 a& A
        }
8 N$ [: T4 K# j0 L: r" C
5 c! h9 R1 D# I7 R' U        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))) s0 Z1 G9 N# G4 e3 M
        {
2 s7 A1 o3 H; k8 F                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
; E, G. i( v$ J                pNewHdr->free = TRUE;4 u; j( m6 K5 S: B
5 L- o' h! Z, Z+ M% t7 \7 E
                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
% T: S! d( B* H& N- S        }7 T1 s' i7 x) C9 T
        else$ Z. l. a( y& a9 x* X# ^% e
        {/* space left is enough to be a fragment on the free list then */
2 Z* U5 h7 J* c/ B8 n) L8 O1 `                pNewHdr->nWords = nWords;5 L2 Q. d( i1 K  Z
                pNewHdr->free = TRUE;5 _# I. }' W/ ]
# q/ W8 }" l  R2 Q7 h/ a9 W* I% H
                pNextHdr = NEXT_HDR(pNewHdr);! r* Y# j' L$ T. U. K, M$ R
                /* words 包括BlockHdr */
+ X" y8 H1 C7 U1 D8 q" ~. Y* N" \                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;4 K/ q) G/ v* F3 c
                pNextHdr->prevHdr = pNewHdr;" h: Y' m, _: J! Y7 H1 E8 h
                pNextHdr->free = TRUE;. C6 G$ w+ j6 E0 ]" |. T

/ N$ z9 ?" r: m                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));% [2 I# w/ r2 c
( g. d5 W+ C% S1 X6 R
                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
% B. e* x! q7 f1 _! A5 H        }% C3 m; j- ^6 `

7 U4 B3 k% e. I6 J        return (pNewHdr);
- t2 K6 K. M" T6 }4 d; v! D}) Z) ^+ @  ^! Z. v

, B3 ], X- ^2 Ustatic void memPartSemInit(PART_ID partId)
. J1 r: [4 J9 }0 g- n: c{( [7 r6 ^; F- u
        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);0 |, u( n" Z. I) C6 P. s: `

) z( P$ {5 u1 P        partId->semPartId = &semMemSysPartition;6 q, U, I  U9 g2 O! N
}! G' l1 Y  M* v% Z' [  K1 C
! X/ f) t% L6 _' S+ Z# Y, d, L
void* malloc(unsigned bytes); Z1 P: K4 X" A# B
{" T5 i' S7 Q; G
        return memPartAlloc(memSysPartId, bytes);
. P. ~, O0 k  m/ B+ I6 D- X7 i}
7 V- K" q8 L1 u9 j4 h6 O% f/ V! E
" M* A$ i1 \) Pvoid free(void* p)9 Y6 T1 J# Z" d" H& R
{
4 S/ }( @, T. P        memPartFree(memSysPartId, (char*)p);
9 E# q0 }/ x' b. }}
  t3 p8 Z5 k" j; X




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5