数学建模社区-数学中国

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

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

$ t2 k% X/ U6 L4 ~9 t# l. P
, N6 q& T5 Z+ ~: z: P5 h) ?" ?3 C$ O  x
*\file* n8 V* @3 b& [4 z7 {1 ?' I
*\brief                . i9 i# ^% U) S
*\details        7 ]1 N7 i* P9 l0 J: g
*. ?9 X" y0 \# q( x) I- r
*\author        Janson
5 a+ W0 x$ ~% q# ^7 L. S: q7 { *\version       
# U6 Y  y+ E) |, i *\date                04Jan126 V$ U: U( ?4 H% j7 x! ~
*
. Z1 G! O" o1 B/ ` *\warning        9 k5 h, _$ r2 u0 d
*
$ a$ i! `5 w- m/ j0 i *\history \arg        30Jan12, Janson, Create the file/ @; n& V7 ~) |
*        modify from VxWorks source
9 a* f! C4 g/ W8 M4 i0 W *  Legal Declaration: it is for studying VxWorks only.
: `: z/ g  e( Z' N7 N */
$ F; E# O" K' r7 `! i/ D, c3 Q#include "includes.h"! Q) N. S' I5 a/ y
& W- x. @, i5 q6 q5 a4 o% j: t
/* The memParLib.h file is hear:
$ B; S) i8 ~/ m5 Y7 w; ]https://code.google.com/p/vxwork ... rivate/memPartLib.h
& P1 U% |( _9 D( t! @( B, F*/) t8 y' T) [9 o  Z7 D( ~

* t( z; o; R2 a" Y/* optional check for bad blocks */* N% x: L* m/ n) S2 Z/ F

- B4 C3 t& D1 U#define MEM_BLOCK_CHECK                        0x10- k) g6 Q, ]$ T' A( ^; N

1 f  I- G8 h8 O* P! S% P/* response to errors when allocating memory */, {* V$ b, i  a

$ W. R" V8 \6 K/ Z* n  ~  j6 E3 D#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
9 p9 f: `3 o' y# O" J  u3 ]6 Q#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
$ t1 s5 X! e8 r7 k0 y* y! o/ h  q; `( @1 |" C# M5 R) j# G3 W% @! R
/* response to errors when freeing memory */
! H! ?# c' X5 U) l
1 W1 f" d9 Z/ U#define MEM_BLOCK_ERROR_LOG_FLAG        0x807 |4 y- i* Y* E. Y7 I$ n0 Q' [
#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
) [5 `+ R4 @6 s2 n
' Q1 G, a+ F8 o#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))% V9 Y6 d2 _+ U2 R$ X
#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)) x% v3 o) D, e( F

7 q5 a8 \3 m1 q0 u#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
. Y0 T& s2 C+ B: j) |1 g* q#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
, c" z( X7 V6 {+ f* O: |4 P& i                                                sizeof(BLOCK_HDR)))6 P  `$ _+ Y: a- H8 x. K, ~  T) C
; c0 r& O- o% N! s1 U$ f$ J% U
#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)+ a2 a' `( t9 C& ?- \
#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
3 d/ q3 U2 r& I  S. n' J0 l8 |                                                OFFSET (FREE_BLOCK, node)))2 ]" d1 w1 E3 c6 M

1 C, J( p( \9 ?- B; l/ e& k8 k4 [static BOOL memPartLibInstalled = FALSE;
- T7 ?/ P7 ^( j; {" f$ I- b3 s0 X0 r; t) G+ i: _. y9 g
static OBJ_CLASS memPartClass;
6 Q2 W/ I. A9 r) P+ Q1 XCLASS_ID memPartClassId = &memPartClass;
2 O; k9 E# Q6 n4 z1 O; o" `9 ^. W$ n1 e0 }
static PARTITION memSysPartition;
9 ]8 D+ U* _3 _. b' Q: T* O8 _PART_ID memSysPartId = &memSysPartition;7 j) I* P/ \. y( r- g' I, \
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;% D5 M! S( M. w# d" |6 Y  A% V% G

1 L2 t0 N0 h3 _& F0 E. Y$ d$ fstatic SEMAPHORE semMemSysPartition;
3 o# F  g( M2 ]1 @' D
5 s- N. p2 ?4 ]3 _+ b3 Astatic void memPartSemInit(PART_ID partId);
# ~$ S1 ^; c1 z; ?& c0 A# c, N; J" p
FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
) f) }# S; F& q; o% N3 E( r" u8 f
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
! @1 I! Z: i% w# _1 V! F6 ~: P) C+ B# p; T& L# F1 J* I% z
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
7 r2 }4 Q  S, V% |) |& I- Ostatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
7 ?. Z% K- H/ }, S: j4 @# m+ B0 A        , FAST BLOCK_HDR* pHdr9 u# u% i1 E5 X3 P! o$ q1 ^2 t  M: T
        , FAST unsigned nWords0 i/ B, m5 B( h4 t% K/ K5 U
        , unsigned minWords' [5 k# U# A3 Y. Z4 r8 U9 i6 ^
        , unsigned align);9 T" c. U$ q9 `, X: ?! W
7 g% s7 b/ S4 H: o. o: v% Z$ O
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
. N) F% \& a1 ~4 a
" E6 \  N# l7 H& m4 FSTATUS memPartLibInit(char* pPool, unsigned poolSize)# }0 S: m2 Q& I  R/ H% k9 ^
{
: U) w. C* j- Z" }        if((!memPartLibInstalled) && ' B4 m4 N( y+ `# d7 ]; `' u
                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)" N2 l4 s) W) Y- I+ ~) v4 i6 Z1 ]: K5 m- P3 a
                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
1 [+ }- O- `/ O$ P        {
  _1 m( o5 I7 V6 |6 h0 N8 [                memPartInit(&memSysPartition, pPool, poolSize);
. l5 E+ n! x8 X( l7 \% P+ S4 r$ d                memPartLibInstalled = TRUE;
2 H$ ?2 x. W# C. Y8 [) V. e        }9 n: a$ K; s2 ^+ H5 y
0 W/ C5 g3 r5 o# Z  g
        return ((memPartLibInstalled)? OK : ERROR);
" F( C5 E6 r) x! g3 A}. x4 I! U0 i# G# W, T
# d& j; r3 k  Z2 Z% p. ]+ {: f! @9 R/ l
PART_ID memPartCreate(char* pPool, unsigned poolSize)
' b& G5 ?+ l* _$ |{$ B8 W9 M6 S/ Y: r/ k+ K: l. x
        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
) `0 r7 C" j3 m' `/ P) h" H: T" q; M7 H9 j& E/ d: e
        if(NULL != pPart)
# U. B( j3 v1 |. b$ B' W2 H        {
" h& K) {1 b- f* _: {) ]8 @- ~                memPartInit(pPart, pPool, poolSize);. j! r) }0 q& f" j) |! V( Q
        }& @5 M) ~. ?  U$ [

1 K0 ^7 R0 R9 f, w6 {        return pPart;
' D2 R1 B* A5 l; ~; T/ ?}
! ?0 _9 X4 ^9 L
/ k# N6 c4 k6 Y; d. @" Tvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
- [, Z$ L: L; v; @( K- g8 _- ]2 @; @{
& n3 V- l1 K+ |5 G1 S" T        memset((void*)partId, 0, sizeof(*partId));6 i; F* }9 y/ a" y
! E' S. F0 H# z% z' L- Y
        partId->options = memPartDefaultOption;, h. b% F9 Y  L$ p0 r: Z
        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */' |' J- H$ w* i( }7 @3 ~4 ?$ A6 e

# @1 T5 @  q/ ^5 f, s+ k        (* memPartSemInitRtn) (partId);
! [0 Y" @+ A/ W6 m1 q$ }        5 F1 O. t) Q* H
        dllInit(&partId->freeList);
2 ~' f+ h: Y( J# C$ L0 i- u4 R" g; @        2 x% J& H. Z. x
        objCoreInit(&partId->objCore, memPartClassId);. W) h4 \2 h9 ^' E$ n4 e$ P5 a3 w
       
+ L; ?4 |$ ?% E/ [' q! @6 z        memPartAddToPool(partId, pPool, poolSize);  N( W) N) z# s# ^: e3 a2 V
}" G3 E( `7 Q0 i9 R7 b+ \
+ P4 o+ p' e5 b0 B1 u+ V
STATUS memPartDestroy(PART_ID partId)
, P+ H3 h0 E4 }! O6 l{- f& i) g* w, E7 R
        return (ERROR);: C7 K; `$ @( N
}
1 h$ k6 C' L' p( X, p! I9 |# q0 l2 R1 A0 ]
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)# C& [. S8 v  j. ]; n
{
  M+ }; a, a) [    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
4 h/ |- {+ P, i2 [1 N- C}
! b9 M3 }9 d" d  y6 _4 k$ k. t! {
$ D  u% W0 k6 }
! G. c, K! m, d3 L) r( C6 Rstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)* [7 V3 @4 N# v; Y+ `
{* O6 y6 D0 a5 z  I$ v' K4 `) X) m
        BLOCK_HDR* pHdrStart;* u2 v- o1 V' E
        BLOCK_HDR* pHdrMid;
. Z+ u% ]. j) a. M8 b        BLOCK_HDR* pHdrEnd;
4 f0 T  U2 j7 ~7 ?# S        char* tmp;
( [! `! k# s. ^* W5 x        int reducePool;; t+ Z' Y3 S* U

$ Z- @3 v7 v7 N! f* l        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */4 }. K2 y, O- x, m9 O  c! x
        {0 M, R, {, o3 |( G, Y, e  G4 j
                return (ERROR);
- u: R5 B3 b/ u0 |- t, R        }
7 R4 ^- S+ |3 }9 {
  A/ _- U/ l- N) l        tmp = (char*) MEM_ROUND_UP(pPool);
" b4 a7 \4 O$ c# a, b2 Z+ L' o        reducePool = tmp - pPool;) v( F! s; j. A) C" B! ], y

& \( k- {% Q, k( L        /* adjust the lenght */4 o. d) A* V% a
        if(poolSize >= reducePool)
' L6 a! h; R* P5 j% g; g        {  O7 A1 i. X+ Y
                poolSize -= reducePool;% {* Y6 b& X8 t7 X, `* U
        }- v# p6 n3 u# i# O
        else
- n/ j$ c. V- x: _2 p8 X. k8 x6 `; `, {        {$ S$ a. @# H& F, |6 ~
                poolSize = 0;
9 z% x5 e4 O, @# E- w3 Z2 G        }, z6 q4 C2 t9 |2 ]& d
        pPool = tmp;( S( S1 @; f% S% ^0 `1 w9 D7 o
       
# G) Y& q! I, v2 H' K0 m8 ~        poolSize = MEM_ROUND_DOWN(poolSize);  v( z1 o% x' p9 ]3 Y3 A6 z
        / [2 {& t( i3 g  O4 M! N+ O
        /* at least one valid free block and three header blocks */% c, g7 N) {& p1 M: w4 T" g% `
        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)1 G0 i7 `& }/ r1 }. ^* q
        {
' o& W8 `3 N) r                return (ERROR);
* q% l3 _( z/ U3 t1 ]        }
5 b  {7 t1 t: F$ @* f8 s3 L" d( r/ f
9 c% Q, N* h" s2 V# Z        /* initialize three blocks */3 `- K7 f: {3 e* A/ U9 x; J! P( @
        pHdrStart = (BLOCK_HDR*)pPool;2 U# z3 `3 z9 @" E& k3 ?% S
        pHdrStart->prevHdr = NULL;
3 D# n  v0 @8 z* F) E+ _+ l* o        pHdrStart->free = FALSE;                /* never in use */" q* ~9 t3 \' ~9 B4 |- r0 C0 ~. V% Y
        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;  d/ J# g9 r% T/ F1 A9 g. r

3 M5 p7 B' y* ~        pHdrMid = NEXT_HDR(pHdrStart);: v$ A4 j  s' Q0 I" r- @- _
        pHdrMid->prevHdr = pHdrStart;; J9 I2 \9 j9 G* c
        pHdrMid->free = TRUE;                        /* the main block */6 X. h0 ?' E/ G7 Z  q6 A% I
        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;8 S. M. H6 y, @! U

. A0 J$ c5 l+ K9 d$ q8 W/ A        pHdrEnd = NEXT_HDR(pHdrMid);" H4 P" h- }; r# b" x) p
        pHdrEnd->prevHdr = pHdrMid;
( K  f- X) w: }: d, W        pHdrEnd->free = FALSE;
- e: O  b9 k! B8 [& S& i; L6 f        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;( E. z$ ]( O4 M. i$ p: l
7 p+ W) u+ L/ ]9 ]9 D+ Q
        /* TODO take sem hear */
% C' b7 }' n& g& k' \        semTake(partId->semPartId, WAIT_FOREVER);% r; g8 G0 |' j# V0 W% X9 L9 K  i6 @0 g
        % \+ ^, J9 F$ ^1 f$ ^
        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));1 K3 ~$ F, u, V1 `( S
        partId->totalWords += (poolSize >> 1);
7 S& _! z+ d: n& B8 Q+ }/ x+ W" U! m* ?
        /* TODO give sem hear */! L# R& n  D& M  G4 |1 K
        semGive(partId->semPartId);: q# P5 z' j4 A1 P: z; |7 I, K5 k. R
) j) Z; a6 r2 O9 s: ]

4 j0 u2 v. W+ s; C0 r) i        return (OK);( U! f0 u+ x9 m6 G# q" ?7 q
}
) w& N: N0 ~6 b; `. @- W3 E7 [
' K1 n; ^6 b+ m' gvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
$ f; Q' c! c6 \{
3 s: r, n, Z) C        FAST unsigned nWords;
. g/ o, I7 M( C* G& \        FAST unsigned nWordsExtra;) O: s: R. x, U  Q2 o- I
        FAST DL_NODE* pNode;$ I, @& V( J4 U% E) v
        FAST BLOCK_HDR* pHdr;- C' R) y& b' K. u2 O' `
        BLOCK_HDR* pNewHdr;
# `# b6 q3 ~. ~        BLOCK_HDR* origpHdr;
& B0 y% g9 `& u  `. T  D( I- M& M7 Z; |
        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */+ J( r) `4 o! o/ `8 _6 Z" P
        {
) v" g/ |4 N4 U: |4 l                return (NULL);
$ G6 D# K- u5 p4 R        }* K( W3 `& x* V/ U
# l  R# T  f! |0 R$ i; x0 e; f8 i
        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
* o+ U# m* G% c/ ]
% L/ s% a1 d) n5 C: I/ b        if((nWords<<1) < nBytes); p; W% m6 g5 [* q& p
        {( e& i. w$ q, M7 E  _
                /* TODO suspend the task */
; D7 v9 T5 }; ]/ J% o/ b( z. P6 }                return (NULL);7 N' n+ |4 V; g0 u' M/ n  e
        }
$ X# [$ b4 |- G0 `6 J+ Y
" f/ B/ ]; p7 A1 C1 c        if(nWords < partId->minBlockWords)
& z/ y+ ?' D0 J, C        {
( _4 T$ v5 V" t* @                nWords = partId->minBlockWords;8 o, @% w: t  k$ s3 ^0 W5 F
        }
: K" I6 f( L$ O4 s# u: L2 c
: L  ~9 s2 k1 s, V, x0 E/ T. M        /* TODO task the semaphore hear */
+ S. ~- g, C, s9 z  V& Y        semTake(partId->semPartId, WAIT_FOREVER);
: s9 @3 P$ D3 D$ |- Q0 J        pNode = DLL_FIRST(&partId->freeList);
9 j' D8 l0 y! `9 k( ]5 L* I        nWordsExtra = nWords + align/2; /* why? */! r) Q( s6 p1 @% m) j

3 U- ~" q7 I/ s7 i+ Q/ K4 \/ G        for(;;)( E) y6 m$ M3 ~4 k
        {# ^# b7 j4 G. y; X2 {) E% z% b3 b
                while(NULL != pNode)2 |& h1 Q5 _% ]7 i
                {. s3 `# j( r# x; N
                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||) @0 q; x* _, C" c, O2 n
                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
) J/ _8 ^$ ]. Q: E6 z                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
# Y3 D1 r3 F( Y! e: |  v9 q                        {. R) r& c2 [5 n4 h* \7 z: C9 |+ T, F! ?
                                break;; j% R5 e4 i5 |2 a# x
                        }+ z. C% j2 o( j, [- Z, S
% V/ n# D8 u1 ?5 |- M
                        pNode = DLL_NEXT(pNode);7 A8 }# L! t* Z5 ]
                }
. T0 i' c( X( T5 L
% @5 e; ~5 S5 D0 S; e                if(NULL == pNode)
8 Z9 t. D4 ^2 M. z                {
# r% {: r- `0 C0 y$ h$ i* j                        /*TODO give the semaphore */
' r% J% E) o2 e! [& [( [                        semGive(partId->semPartId);$ C( I7 b& x6 z' L* e7 j
                        return NULL;$ e: e- C0 i& r6 u: l' c$ L+ Q
                }
/ o4 F9 o- y$ i) p5 m, M0 i, ^$ l$ ?8 N' g
                pHdr = NODE_TO_HDR(pNode);% S0 m) p5 r1 \8 }) t5 x* U
                origpHdr = pHdr;
* g4 L9 E7 m0 P; b
5 U1 d, K" j6 r2 m5 w                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
  C6 f4 s) i! R) A                if(NULL != pNewHdr)
# q9 o& r* @2 E                {
; y% Z8 ]( a- e  n+ T' O8 A( ~                        pHdr = pNewHdr;
4 J* S- C8 }. R7 e# J; d0 }                        break;
. a  v! I6 d8 P                }
: j! b! m4 m; n2 [2 e0 a# t: @6 \  {
                pNode = DLL_NEXT(pNode);. o$ O& [2 Z) L# P
        }
1 e2 ]: ^  V* E, y: e8 V) H$ H
* W+ W  z9 Y$ _. S" ^0 I, t5 V        pHdr->free = FALSE;
0 T. q) C. @1 f' @; X! x. u0 N- f1 R        partId->allBlocksAlloc++;$ W8 L8 E* |- \5 p1 z4 g' S' b
        partId->allWordsAlloc += pHdr->nWords;# D% p( j, Q- f( u
        partId->curBlocksAlloc++;
1 W( a' I/ e0 r+ N        partId->curWordsAlloc += pHdr->nWords;
" e3 y( ?5 V; T! t3 N8 O* e, |
1 g7 s5 ^( |8 n8 V7 y8 k        /*TODO give the  semaphore hear */5 z! H7 S" J1 u) I! H  W* m
        semGive(partId->semPartId);; m, h4 S8 x  r! g
        return (HDR_TO_BLOCK(pHdr));
) r* U! ~5 n' i& C       
) v/ ~$ T9 }# |% {" E7 g" R$ {( Y}
- Z0 m  F% z' M- ^( N% l0 |
3 _- g/ ^2 r7 E5 j2 B$ ~& y5 I- y, bvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)9 E; L4 |; c# N8 m0 ^- C7 W
{
$ D% y/ |# [$ o  p        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
6 J* k( k( m0 v( i, q' v}7 p* j# K7 W9 {0 M9 P4 b
" {/ y. d- I2 Z: ?2 Y
STATUS memPartFree(PART_ID partId, char* pBlock)
4 Z% |- Z6 F7 d$ [, |7 n{! `& V( Q, P: E4 ^( W3 m+ j
        FAST BLOCK_HDR *pHdr;9 z# t# n* f! E" }5 i; q( |
    FAST unsigned   nWords;
' C+ T  d5 k# P# {    FAST BLOCK_HDR *pNextHdr;: Z8 Z  R- Y1 J' [$ k; D

7 Y$ u4 y( V( \( [        if(!IS_CLASS(partId, memPartClassId))4 _8 D$ z% u2 m
        {+ e  r8 Z; V9 ]$ I* ^/ X) N
                return (ERROR);$ _1 I+ Z/ q8 q# B* }, J' D8 b
        }. T# A5 d9 g: t5 O( z; C% h

4 ]1 o# A5 I  G" _        if(NULL == pBlock)
7 A% y1 Q7 G! }  X/ Q3 p; U        {
2 r  S; ]% L  R8 c3 [                return (OK);+ n7 J! g/ S; `8 C
        }
5 {* d' f; h* @/ C2 ~2 F+ F+ Y# C( }2 L) b# R; u' g( R3 Q9 d( A  T8 u
        pHdr =  BLOCK_TO_HDR(pBlock);5 U3 H& S/ i* d" N
" J3 n* i7 Q* q' x3 y
        semTake(partId->semPartId, WAIT_FOREVER);
* X+ h/ q( k4 S  I: K+ N/ [% y1 }* B5 B
        if((partId->options & MEM_BLOCK_CHECK)
7 e) b" Q% _# @+ ?                && !memPartBlockIsValid(partId, pHdr, FALSE))2 t( W0 {/ Y  K8 h  z4 w: i% m
        {4 {! z6 @' F, W. |4 }
                semGive(partId->semPartId);
- t7 w  A0 J) w8 M8 N                return (ERROR);
- C  [& d2 \# B0 q" T        }
. |5 l9 ]1 g. X
7 [; P% f# _; M+ k7 p5 J        nWords = pHdr->nWords;
* f6 I# p1 |/ t- x        if(PREV_HDR(pHdr)->free)* h; L, p1 j; d' g& t  y7 R
        {/* the prev hdr is free and than coalesce with it */
/ P$ p% J$ o" n                pHdr->free = FALSE;9 ]9 j6 g! M. q4 K9 k
                pHdr = PREV_HDR(pHdr);
6 h  C# f# C. `( @1 G, Q, W& S                pHdr->nWords += nWords;
1 ~( r$ b! y7 M; o* g6 W% G        }
. B' h7 s( n" C! b+ d8 z! {        else
- U6 c2 k% d* e  M: _8 I        {
/ [: K: S" `) C. A: h) R# x# W% q                pHdr->free = TRUE;) e, l1 ^0 b  G
                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
; }6 n) m  f2 x1 `7 w        }# }( a. H* P4 R" Q3 t: \

8 Y  f- k; N+ p+ L        /* check to coalesce with the next */
! J0 M1 h: B  R5 O2 d: q        pNextHdr = NEXT_HDR(pHdr);
3 U6 x4 `$ l# s& `' O        if(pNextHdr->free)) n3 @1 Q: D! ?( e% Y
        {
& V0 t& D9 y- F6 \2 t' f/ A) z0 @                pHdr->nWords += pNextHdr->nWords;4 ]3 h1 y' K# M- ]! j5 y/ U' V
                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
2 A6 v0 h9 z  t        }, q8 g! o3 ~3 c: O0 p  |

$ s! @% R# u& a7 Q0 j        /* cannot use pNextHdr->prevHdr=pHdr hear */
. Q$ q; s! t  z# |& ]1 c        NEXT_HDR(pHdr)->prevHdr = pHdr;5 X! X- O0 a6 |* ^! T" G1 V6 M. U

" [! _9 f; A- H; `& D        partId->curBlocksAlloc--;
; }5 Z5 b. o/ h8 w9 a        partId->curWordsAlloc -= nWords;
5 }3 k) `/ C' G- J* Y! t3 W7 h! {0 q$ B$ e
        /* TODO give sem hear */" X  A% L/ S3 |$ R% X9 L0 S
        semGive(partId->semPartId);
5 ^; s; h, F; q. f! ^% p2 K2 g2 w  b        / u3 Z: i' @' J) S) t2 F
        return (OK);
- b: s6 n* A2 c1 B+ Z: P1 F}
/ x) k& r, N' k! f: e8 O  I, B, ]
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)# {* ?, k& }' p) z1 Y
{* G. _5 ~3 |. F8 J* q. y& Q
        BOOL valid;
# l- \7 l$ w! n/ w* @$ e6 u
) X, K/ G- Z3 `( P3 e( d. S        TASK_LOCK();  V: H* f) m$ W! L! p* x3 J
        semGive(partId->semPartId);
  h6 ^) @$ P/ h* n( a  J        ) Q2 D) w0 {# {9 A8 `6 n
        valid = MEM_ALIGNED(pHdr)
3 e) |: C. Z. }        && MEM_ALIGNED(pHdr->nWords*2): W6 X% ]- l- u' C8 B
        && (pHdr->nWords < partId->totalWords)
# @/ M" X0 f; [4 X; A: b9 R3 I        && (pHdr->free == isFree)4 h8 f( K: m8 _* |6 O* P
        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))0 r2 V, W' S8 I8 I* B( ?2 v
        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
2 Z$ Y% \6 s  t) @# L5 S3 I       
  l9 `7 k6 A9 B: i/ s        semTake(partId->semPartId, WAIT_FOREVER);  A$ S4 K& C" u% R  R5 d2 _+ I- n
        TASK_UNLOCK();# X# V+ {" O5 @% d

; |6 R9 i; C* T        return valid;
: j: |/ P+ ?. s. Z' ~}0 c% E5 [" B, W/ F) U1 i& i! j) N* w

) c0 ]4 W$ o4 T5 v* B5 }static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
; G! O! q2 O  J        , FAST BLOCK_HDR* pHdr' l$ G9 J' _7 M
        , FAST unsigned nWords7 a. J. }& r' r! T* w
        , unsigned minWords
0 m% o4 {" Y" C8 ~        , unsigned align)3 \; k" A; m2 ^1 H6 `
{  {6 C0 h" d1 W2 |
        FAST BLOCK_HDR *pNewHdr;8 h: _3 E! n3 q" A; U
    FAST BLOCK_HDR *pNextHdr;
' {- Z" Y- p# Z) Y, F    FAST char *endOfBlock;
' `( ]3 f) `( @    FAST char *pNewBlock;
: o2 F* `+ X4 \( H+ p2 G$ f0 i    int blockSize;- \, j9 F; X2 }) R  r

/ ?. [/ q, ~* `1 |+ e        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
" `" F- ?& d! [$ ~; J7 x# W" `) P' \) d' h2 s) S5 |- l% ^4 f' K# _2 d( J
        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));' @8 z% F1 ]9 U- X

- X$ ]# k( ^4 V8 |        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));8 J! a- `$ z. U5 }. Q
' H6 {, M& G+ i; ^& H; f  C- O
        pNewHdr = BLOCK_TO_HDR(pNewBlock);) M6 {7 Y* X, _( E5 ^
# O7 j, z4 |  d. u! x
        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
/ Z6 m( Q) I0 o( ]8 m5 @# C+ L! s7 N' ]
        if(blockSize < minWords)
& K' R' V  m$ Q: p" c$ n% Q$ C% w: v        {
3 c8 h+ n( C8 V                if(pNewHdr == pHdr)
; x/ e) w$ s9 O- v* j6 k% `  i                {
) G' o* g+ c5 T! {7 f. j6 I4 @                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));) H1 X, L2 O4 F* O2 G& u5 f4 I
                }
9 |* Z) b8 G  i  [; E                else
7 L4 Z' Y  o7 W                {; k4 W% a' f& _4 U3 C, i
                        return NULL;
  h9 Q, g- F8 }" V6 i6 B6 R, Q% C                }5 w% c- E) U/ c3 p% E! ~$ ^. X
        }6 I" j. \" r9 q
        else
1 o4 v1 x; M5 l4 b0 B8 W        {        /* recaculate pHdr */: d; t* @( D( M/ V4 j  `
                pNewHdr->prevHdr = pHdr;
& Z( |4 L3 H& z2 q# s! d                pHdr->nWords = blockSize;2 u( \+ V' {7 h
        }
/ q/ D( Z9 D( F% ]  u# B  x/ O0 [" G# k) I
        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
- K3 F" R) T, h0 X4 e        {. i- x) m) {+ N  K( ?
                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;# T! e& R- x" D6 R) G& k
                pNewHdr->free = TRUE;, O/ W/ [9 m8 R, Y

0 ]% ~/ [! e4 u$ \  r                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
1 M# J8 ?6 S0 {4 E: M6 k' S        }
, s6 \6 O, o, C! F* O! N1 v        else- e0 i% E' Q+ y
        {/* space left is enough to be a fragment on the free list then */
& A8 f2 s0 X/ K                pNewHdr->nWords = nWords;6 T; e) g. j+ J2 a9 j& A
                pNewHdr->free = TRUE;
3 \- r3 z1 V$ \! A: A; b! `/ h, s% d* C7 O; R  }8 g9 k5 r
                pNextHdr = NEXT_HDR(pNewHdr);
0 B& V/ U$ F+ N$ @5 n8 d  o/ ]                /* words 包括BlockHdr */
* d7 v" |2 G. |# x) a( R                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
3 B3 f$ R! R2 N0 o1 O6 I) Z                pNextHdr->prevHdr = pNewHdr;
  F( N9 s, m! v! u  }# E$ b                pNextHdr->free = TRUE;
4 n. ~' a% S5 ~( d# w/ |
/ ]' k) L: s+ M                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
  f( D' a  D% f; l7 G& u4 _6 Z8 X$ j; _* T# F; Z- J3 S9 Y) T' t9 O. w
                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;' Q9 H# q, P' B, v, d
        }
5 E* g) Z! r% P: [; \. w* L% r) i; s3 {/ R) C& ^) g& v* C
        return (pNewHdr);
" q% u( e! X# j9 {+ w; o. \}
" A0 H1 |+ M! g# ?9 ~2 s: ~& W8 v' S+ w2 Y# K
static void memPartSemInit(PART_ID partId)
& W) V) ~; c9 s, E! c{) E( A* A3 Z5 c
        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);7 I* r, i# {1 ^+ N7 z

2 Q# V" U. ~+ \8 g) D7 r9 U+ j& e+ ?        partId->semPartId = &semMemSysPartition;  R3 R) `+ H6 s! R* O
}
* D/ K* @& A5 D. E9 q+ h+ s
) r% B6 I- y/ M, b& e5 Dvoid* malloc(unsigned bytes)
/ ~& J8 X4 e3 I/ S; r" ~- n6 p9 W{2 S9 b* }0 x* P9 d) C$ A
        return memPartAlloc(memSysPartId, bytes);+ H& Y7 J( h. ^7 k! D4 B
}
. @, c# b0 k. D' q8 a: t% B$ `  l; M7 S9 ?& J( ~* L0 e
void free(void* p)
- M; @! p( ]. M  h- T. ]7 c{9 m, K" T$ S" r7 |# [! l
        memPartFree(memSysPartId, (char*)p);
# R1 N5 L* Z' a7 t4 |}/ U$ o: R) @$ G- \  B, a7 t4 L





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