QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2650|回复: 0
打印 上一主题 下一主题

malloc(内存分配)在嵌入式下的一种实现

[复制链接]
字体大小: 正常 放大

937

主题

117

听众

3万

积分

升级  0%

  • TA的每日心情

    2020-10-25 11:55
  • 签到天数: 264 天

    [LV.8]以坛为家I

    自我介绍
    内蒙古大学计算机学院

    社区QQ达人 金点子奖 助人为乐奖 风雨历程奖

    群组2013年数学建模国赛备

    跳转到指定楼层
    1#
    发表于 2013-7-26 10:17 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言+ s8 B1 A6 b" w

    7 |( e3 G# K# C& \1 F' C; C: ]) z
    8 e5 k  `2 I2 k5 B
    $ R. f2 C# ]" {/ t0 W( N8 i) E$ A- w- z *\file$ |( u- \! N2 `- i" p$ ]# P, X( p
    *\brief               
    9 {# [7 r4 L3 F+ d *\details        ( e6 |0 h/ T' [! P+ h9 U
    *. X9 ^6 M2 r& K  u( |
    *\author        Janson7 ]3 n; t5 f* [9 B0 q
    *\version       
    6 u* g3 [6 z- T* \. ]" R *\date                04Jan12  R4 H% ]% s2 z' _3 Y: J8 ?
    *& d2 r% X" z3 j6 }6 m$ Z
    *\warning       
    1 r; K1 Y* Q- X2 V/ a2 y *
    2 L2 u9 L% c4 @# L) p1 d- A *\history \arg        30Jan12, Janson, Create the file4 W( v1 i( O+ ]( a1 k* N4 Z2 a
    *        modify from VxWorks source
    2 Z( k7 z6 R0 P& O( a' @ *  Legal Declaration: it is for studying VxWorks only.
    ( h$ h6 \# I) V6 V/ l* U */& T5 P: ]! L- M0 j- Q
    #include "includes.h"
    . k8 t! h/ a- F! i" r' w) Q3 C2 i9 K' M- g  D  q: g4 m  J" Z
    /* The memParLib.h file is hear:* `+ k3 I! u1 M6 _6 m$ D. ~
    https://code.google.com/p/vxwork ... rivate/memPartLib.h4 ]; R* J* L5 @" G6 }; g# P6 x
    */
    9 V7 C+ I; e  v( u/ a7 z, R* P$ d) G
    / t, d/ U5 `; L5 h1 H: ^/* optional check for bad blocks */8 O8 B; H3 J. a$ V3 R
    9 H% l2 R. B! Y6 z; c2 d) @  L* g
    #define MEM_BLOCK_CHECK                        0x10
    ! j; s5 h+ E7 c! E/ X# d; w- o$ {) U( w$ F6 q# p; t. a
    /* response to errors when allocating memory */, t  N) w! c) W& {) }2 g
    * H2 I" E# V( u- ]
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    ' u5 x$ H( h  v8 W; o#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    / p( T$ q* K) `! M! E1 B) R& p  ?5 m
    /* response to errors when freeing memory */. I0 `3 `3 I! o
    / R# S6 ^/ q+ A' N! T$ P( `0 F
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    ' ~  E6 W, P6 S+ {+ i$ O, ]: M! K' t#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100  |: V) a) |! V0 i

    1 i* l/ M- i6 E* R; ?  @1 o#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))); Y* ^* _/ C/ ^/ u. G
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr), }+ b5 v5 j$ x9 y- w: k4 {& w4 \

    ! a- b9 X( v1 w7 ~8 j#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))- G; t' f) v  n
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \9 l* W) ^7 Q/ g4 c" D+ ?
                                                    sizeof(BLOCK_HDR)))
    4 m  o* M! t3 W% e" @7 U* o9 e! y" e  i" ~2 j; a1 g3 k
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)- I- [' A" E( S
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \2 k2 v/ g9 j1 A! b0 m
                                                    OFFSET (FREE_BLOCK, node)))5 ?$ ?9 L) Y0 n+ j
    % _, E9 p. W6 p3 C1 C) i* }* }
    static BOOL memPartLibInstalled = FALSE;
    1 k; ?2 z* Q* g- Q  s" ?5 k5 t, j5 T' W4 s. ~  d
    static OBJ_CLASS memPartClass;' ?+ {4 [' c5 T3 H9 j
    CLASS_ID memPartClassId = &memPartClass;
    5 j: z7 h1 S1 D/ {* a- ~* f0 S; _3 J
    5 Z0 o; ], X( @* m5 }5 }9 ^) i, Fstatic PARTITION memSysPartition;5 m- L4 n6 ^2 Q' }* A) _8 T, G
    PART_ID memSysPartId = &memSysPartition;0 \# p# g3 C$ R% V
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;) j% R: i% a; H# ?( R& y& \/ q( X! e

    $ d) H( U% @+ }% J& Qstatic SEMAPHORE semMemSysPartition;. s2 j' R; K4 c

    4 P* _, `2 p$ v3 Bstatic void memPartSemInit(PART_ID partId);3 P/ S. N. `+ |1 a0 Q8 L3 P. N

    7 W# c6 i+ N9 b2 {5 ^FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    : r: R2 y5 L# }2 \/ p. Z: P% C2 ^9 l- I7 U* ?9 H7 F' h: R
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;, v  ]8 I/ p, k- r4 o/ S" i

    ; x( l  r' u( I% Pstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    + U, g! N( Q+ N- hstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 y  `* w) @, r
            , FAST BLOCK_HDR* pHdr% W$ {4 z' j# b6 q
            , FAST unsigned nWords$ r" S; t" f( l+ I
            , unsigned minWords: G, V- h" C% w
            , unsigned align);
    ! ?8 M2 V4 D0 `8 N7 n/ [. C* z5 B: I/ U# L. x# ~, T, X
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);' G1 `, j" T8 [5 j
    0 `- f$ v% y' H6 {
    STATUS memPartLibInit(char* pPool, unsigned poolSize)) w9 b+ Y* K7 W' A, K( n
    {3 Y" O( h0 n9 o0 C4 w8 u
            if((!memPartLibInstalled) &&   Y* K9 {) w. D& C6 O  z: B2 b
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)4 g- g0 W+ a9 r8 x0 [8 V3 z6 c
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    . c8 j5 o+ m) A% k- E' }" j) C; p        {
    . e( ]8 u+ h. |5 y                memPartInit(&memSysPartition, pPool, poolSize);
    ( B. G& a5 D% Y. }+ B/ W                memPartLibInstalled = TRUE;8 |3 A! i+ \, f; U* Z; h
            }
    + T. o: A. J* P7 p0 S  |4 _- L  ^
    0 O. o$ z' r" _; ^* n( @        return ((memPartLibInstalled)? OK : ERROR);  N2 I: j$ a5 C
    }
    + j, L5 \- A9 f3 N5 v4 Y  j8 k
    " C2 Q- q$ g: D/ I8 ]4 V9 UPART_ID memPartCreate(char* pPool, unsigned poolSize)
    . u+ `5 f7 Y1 ?9 Q% {{
    ' P" g: D3 E0 T1 }5 G1 [        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    . n7 }* j  ^6 ^/ U' F4 e. d$ i- n
    ) k4 _- c8 f- n8 u. F4 k. K: U        if(NULL != pPart)
    4 o: f5 a, R8 h+ ]; Z* R        {/ k& T2 V3 w/ P4 R
                    memPartInit(pPart, pPool, poolSize);
    3 S3 T2 L8 T5 r. h  @        }
    . V+ a+ _+ ?0 a/ n( m4 K7 _5 _7 j) P5 j4 u& e
            return pPart;
    # Q8 L% O, }$ d* E( F}
    5 G( f" l4 e! @% t6 `1 k% g3 K4 |" y. b; H( F# n1 u2 B1 ^3 M: n
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    ) Y0 ^: A  R. k1 O3 p, ?{$ t4 j& W7 k/ g4 l  W' \
            memset((void*)partId, 0, sizeof(*partId));9 r8 A6 h$ ?% m; d5 _8 [5 j% c

    7 L! o0 S0 \. K  n) f7 O2 H        partId->options = memPartDefaultOption;
    * X, L( n0 T# |  Z0 O4 g5 B- z        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */9 E! d3 U8 I7 o6 \0 p
    / o; D# o' B8 Z
            (* memPartSemInitRtn) (partId);
    . {4 O& ]7 g# o        # p- X* v! `& g6 O& Q% f
            dllInit(&partId->freeList);
    8 I1 F& Y& u  K0 F# I9 f       
    . k# o9 `' J: W" _        objCoreInit(&partId->objCore, memPartClassId);
    5 k/ p1 q+ g$ {  t6 T        $ l: Y- g1 A1 Z6 y. ~
            memPartAddToPool(partId, pPool, poolSize);
    $ {. t7 E9 [9 e  N  U* K% {% i}: w5 S6 w8 {, Y5 @& _) Z% y1 R
    6 i) \5 N& r$ w. |, J6 r9 }. ?/ Q7 T
    STATUS memPartDestroy(PART_ID partId)
      ~, C) ~) s2 z{
    ( Z6 @/ |# b' y        return (ERROR);
      ^: O; t1 [9 \5 E+ F" C# B}; F/ o/ Y3 u! X9 z& ^, B, H$ I

    9 J5 U0 S9 Q0 P6 Y7 E7 Lvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    # k' U4 o$ Q  F% j{  J5 ~6 J* ~- R  X" x- L
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    # e2 ?) Z+ O) }}
    7 M- u, l+ H% m& r- |, M( S
    % \* M" X( E8 P. h8 ^$ H+ t0 d5 v  e; g: s* b
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)3 o# v% [. ?; _" G6 ]. x# {$ O6 h$ P
    {, y9 s/ J" c1 \8 L+ T3 I& y
            BLOCK_HDR* pHdrStart;5 U- Q; |6 \. N3 x5 [% _( r" F0 s
            BLOCK_HDR* pHdrMid;
    , G' f* I# X& w- S        BLOCK_HDR* pHdrEnd;
    - u. B- ^% x  ^8 w+ A! E. @" H        char* tmp;
      B" S$ a1 Z+ m+ ^4 O        int reducePool;
    4 G2 p. v& ]1 H; }
    $ j. I4 ^" M$ b  ]* R3 U3 m' O        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */7 ^2 {2 X' {4 p. D$ n/ H
            {+ t+ y4 `( r2 z0 ^5 S0 @9 w
                    return (ERROR);0 M/ K: S' O% k7 C$ z1 M
            }7 w1 M& D+ @7 Z* h) e

    . f5 N; G- x; s- L+ G        tmp = (char*) MEM_ROUND_UP(pPool);# U- b( M1 l3 A: n- _5 k9 a& @5 ^
            reducePool = tmp - pPool;
      A( p  a0 j1 Q1 ]5 i- X& g8 v
    1 J/ t3 q( C& Y9 e4 i! d  i        /* adjust the lenght */
    7 f9 U* q7 U. Q- u# x        if(poolSize >= reducePool)! y) w: N3 K5 E0 _: w8 M% F
            {9 D2 K# e- B; W
                    poolSize -= reducePool;6 A5 ^1 \! r' S3 n$ ]. D9 H/ z
            }
    ' c' ^/ s$ `0 Y. A7 n        else  E6 V+ J. m2 H) x
            {
    6 U& @. }$ s9 v3 \8 x                poolSize = 0;9 _' f2 I$ I  t# I1 o" E( O  n
            }
    2 R( P1 T5 R2 J% W5 T        pPool = tmp;
    2 Z/ h( Y- \8 A- Q5 S  q+ r       
    5 t& T! n7 Z3 ]3 h8 s; h8 V  Z" s+ R4 O! u        poolSize = MEM_ROUND_DOWN(poolSize);
    ' W4 E/ h3 h  r& T7 D        ' J2 Q* i2 E8 D# L4 U
            /* at least one valid free block and three header blocks */
    7 F; U# E( c4 }. x        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    0 d/ Q, o* _! b2 y4 j        {
    ! k+ {  O6 \! [( `3 o- P                return (ERROR);* V3 g& E3 l* w4 @- f2 M
            }
    / {- e3 w5 A, r+ U) h, `: k2 v- v6 {: ^  E/ r1 N$ i& m, v
            /* initialize three blocks */
    7 `4 s+ V) P! ~* b& \8 ~' L        pHdrStart = (BLOCK_HDR*)pPool;
    " c+ G/ L/ T2 i/ O8 L        pHdrStart->prevHdr = NULL;
    % Q) E  _9 ^! r; A        pHdrStart->free = FALSE;                /* never in use */
    - L; i' ~0 @* X        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    8 g" C' U7 p& \2 j# n4 v1 u  b# X7 D& M; k3 K2 m
            pHdrMid = NEXT_HDR(pHdrStart);- t% v: ~+ f) C3 q
            pHdrMid->prevHdr = pHdrStart;' u- t0 b/ l( I6 X. \) e& v2 ]
            pHdrMid->free = TRUE;                        /* the main block */! }) N$ j" O" F* C: ]* H' n
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    # |: F( i( o6 p* n# P6 P  M; G, d/ [) t' w
            pHdrEnd = NEXT_HDR(pHdrMid);0 f# d3 R& u1 {* L/ g* S4 D" v. P( Y# O; ?
            pHdrEnd->prevHdr = pHdrMid;
    . {" G+ l2 w& |: ~; J: ]        pHdrEnd->free = FALSE;
    ) I/ {; }! |, O- O$ z- M4 F        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    ! E" [+ {+ m) F2 R# T, `) b/ f! U
            /* TODO take sem hear */) O  _8 Y8 t2 {& x9 N1 C( C
            semTake(partId->semPartId, WAIT_FOREVER);# y* z5 f9 R% n) }" H8 Z
            ' S* u' e& _, |9 f# N9 a
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));- [* V% R- ?# Y) D. T+ T- [( y, U
            partId->totalWords += (poolSize >> 1);: j- D3 y* F* _8 T6 H( E. f0 A

    0 F& Y$ `& {2 h: p9 U$ R        /* TODO give sem hear */" M9 U2 x/ J+ x# I( w2 p, o+ @
            semGive(partId->semPartId);& a0 x& y# N0 q6 A/ Y+ V
    5 `- \8 V* h- S0 ~5 o, Z1 c% l

    ) i! `4 r8 A. [  ?        return (OK);
    4 W& O. v2 L" L- _& `+ X) Q  L}
    . g1 M- U( I! F5 Y
    6 L( H+ r) P5 D: _. Gvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    & C% k! D4 b7 {{
    ( M8 L3 F! R. d7 F5 }% M        FAST unsigned nWords;
    3 v- i: r, Y$ N. X4 g. k$ c        FAST unsigned nWordsExtra;
    ; X" C1 `$ M; j' u7 s0 |        FAST DL_NODE* pNode;
    6 _% `: O4 u4 V  w5 i2 e6 L( l        FAST BLOCK_HDR* pHdr;
    # |: C5 u1 @. _5 ~- Z        BLOCK_HDR* pNewHdr;- r3 o1 h# o& ]6 D3 L% ?% ^/ m% N
            BLOCK_HDR* origpHdr;
    ) s* z$ L7 v1 L% P( t4 t- V" g8 H% [/ U8 s( _- ^, z
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ' k% t: y1 Y4 J! B* F        {$ f9 t1 N' Q6 x! ^) V
                    return (NULL);
    ! A4 |# h7 ~; o9 `        }+ E) Y1 U( ?! E& z7 i

    * M1 r5 x- y, K: L0 _4 F        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    8 q& h3 T% q1 O: x3 n4 b, _# k
    3 [9 r# k" q/ Z$ s        if((nWords<<1) < nBytes)$ P2 |- e9 h9 T3 h, p
            {) D7 }- t* S5 g( ]
                    /* TODO suspend the task */
    " }. W: v9 n! m! E, d) S- B                return (NULL);3 e6 ]7 f/ k1 ?8 E2 N: c
            }
    * C# \- w: q8 W: C9 D9 ?3 k* W, e$ E! e
            if(nWords < partId->minBlockWords)+ ]  d  @( k" A0 [1 y% T
            {  h) R- o! d/ S+ f
                    nWords = partId->minBlockWords;+ @/ s. q/ A% x) y0 V
            }
    ; s. q# B( ^+ H9 X7 g& d
    : \9 c3 Z( [( g        /* TODO task the semaphore hear *// w3 N# ^- ?. N3 F4 z
            semTake(partId->semPartId, WAIT_FOREVER);2 o- p$ n, G  ^3 a! D" Z( n2 X2 T: k
            pNode = DLL_FIRST(&partId->freeList);
    ! p2 L& I1 k" t$ I        nWordsExtra = nWords + align/2; /* why? */
    ! ^& `  v  {4 T; s
    . p7 Y- g% [+ T8 D" i9 }  k  r& q& S  }        for(;;). X3 O, ]6 ~" A( l5 U$ H
            {+ z5 u7 W' n: n+ Q; @$ @
                    while(NULL != pNode)$ \4 j5 O) S- u: V  M# }
                    {! Q/ Z" u: c9 t( K0 h( ?8 @: J
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    ' L9 o: A# k2 K8 _0 Z2 K                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 4 K! Q" N3 q2 H7 @9 a2 s
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))# [/ i! \+ \1 R" m
                            {, d/ P8 }+ g$ k4 S" K& p6 g
                                    break;+ m( C7 R5 ^9 e" `6 P
                            }0 G8 |1 R# H+ b- J4 M* p

    - g7 M7 u- Z7 |" ~7 x% g: b/ U$ N                        pNode = DLL_NEXT(pNode);
    ! F# x; D& ^) v8 J                }
    . P0 _) J1 t. m/ v; ~% K1 F8 a! }5 b3 L* z+ C# W
                    if(NULL == pNode)' [9 z& j4 ]( N3 y( j" u
                    {3 ]6 O" `& F* U6 G1 ~
                            /*TODO give the semaphore */+ _$ v7 u1 C  T
                            semGive(partId->semPartId);$ R; {6 s+ B5 M6 o' z! Q/ }
                            return NULL;" i; a2 k, v) x, e
                    }
    . ?! B- o/ Z& Q/ U1 Q5 ^
    ( ~' J) [& U3 q# D* ?& N+ u+ X                pHdr = NODE_TO_HDR(pNode);
    ( z* b" O- n5 A# V8 e1 X                origpHdr = pHdr;2 R2 r/ k+ D# t% c4 i  i

    + x: |) p/ o3 Y7 Q$ X( N& F                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    * K. R+ |, \# g                if(NULL != pNewHdr)6 y, p1 a7 O( K; M) I+ Y- a
                    {
    6 T# k( u! D/ V: _" B$ n                        pHdr = pNewHdr;" @" z+ s) x7 y/ n& F
                            break;
    ( d  x- `6 P# I! m                }# [' G$ n* {: [4 d/ Z# O
    + r4 R4 J. h& T8 Q! y" Y& ?% _
                    pNode = DLL_NEXT(pNode);. r( R& @) z0 _9 c4 |
            }
    # e4 B7 x+ W& b7 W" \# E! P
    6 o. S% R$ M( Z+ U7 C( w        pHdr->free = FALSE;
    1 \! {7 K6 M% e: g( v8 {# L        partId->allBlocksAlloc++;
    : ^+ g) V0 }; @* B        partId->allWordsAlloc += pHdr->nWords;+ H! z5 K* b0 r* R
            partId->curBlocksAlloc++;- X4 I  v. T( P; b: N( f5 |0 X
            partId->curWordsAlloc += pHdr->nWords;
    6 d" l/ N; X9 u/ d. D5 G' g1 B) {8 @: [$ P/ S: V- u
            /*TODO give the  semaphore hear */" \( E6 |* f3 i/ E3 L$ O
            semGive(partId->semPartId);
    , V: t. u+ r: R3 E        return (HDR_TO_BLOCK(pHdr));
    4 y0 R  `3 d% K: ]$ j5 b' M8 Q        + O% Y- N: {" X
    }
    # `8 T" L* t! K4 I% M8 R/ }7 @0 }3 _' ~# `1 z( f8 F  t4 `
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)+ M8 y  K: W* o
    {% \) t. Z1 g8 S0 D6 n/ }
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);6 X" ~" G4 P2 X& A; V: v$ \
    }, f+ i3 \, b: C, M
    - Q- ]4 `0 ]" A8 o; W: C
    STATUS memPartFree(PART_ID partId, char* pBlock)/ l/ r" U6 ~* n, E, g! n
    {% O4 [5 q' N. q0 A) N0 V/ L
            FAST BLOCK_HDR *pHdr;
    ) Q, V! B+ z. A4 P$ m    FAST unsigned   nWords;
    " Q. ]3 l( g$ z, q2 h  K  g9 ^    FAST BLOCK_HDR *pNextHdr;, [3 |. i& t& o! I4 n+ `( Q* m

    2 v) i, e% P7 g# Z: s. x        if(!IS_CLASS(partId, memPartClassId))
    % r2 u( k% Q+ i2 N; _# z% d        {8 b, W, l+ c4 r. {. @+ C$ n
                    return (ERROR);
    ' x/ g9 U. n! y5 R        }
      C1 r7 z+ Z6 u) p1 [* v( }8 F) v3 m# s2 {6 r. l5 a. u5 E; b
            if(NULL == pBlock)
    - ^  P9 V; C* h) U% a3 _. S7 u        {- L3 S/ |6 L$ H
                    return (OK);: G  A" }  m9 y9 n+ l
            }
    + s! |8 T7 J$ i7 ~% A3 o( I9 ?! Q( _7 W) k+ \- ^  Q$ l  N8 C
            pHdr =  BLOCK_TO_HDR(pBlock);+ U- \( O* K& ]  O

    4 ?+ E& H- ^: L7 j6 S7 |) Z/ K( u8 e        semTake(partId->semPartId, WAIT_FOREVER);
    * a2 L' v+ s" A2 j/ A! @# B5 ?- M) z
            if((partId->options & MEM_BLOCK_CHECK)
    6 i# G' j9 ~5 n* M                && !memPartBlockIsValid(partId, pHdr, FALSE))7 H, g% V% R0 X  o2 A5 {* Y# u
            {
    # x/ F9 C- I: C+ p" m9 S                semGive(partId->semPartId);
    # m! e9 l9 l& S  H  ^. e                return (ERROR);) _) h7 V6 ^9 K& G2 t
            }1 H. ?" s# A1 j$ J, f2 ~+ K5 W

    4 F5 K# I- o" G" {' ^" M2 v0 I# D        nWords = pHdr->nWords;
    % U$ Z3 r) B# }2 B        if(PREV_HDR(pHdr)->free)
    ) d+ F1 a: f% x1 H& F' f, r        {/* the prev hdr is free and than coalesce with it */
    " \: W' R3 ]& r6 Z                pHdr->free = FALSE;: t2 l5 e5 b; G- [9 L
                    pHdr = PREV_HDR(pHdr);
    * p2 C4 A" Y( o, t& |                pHdr->nWords += nWords;- i& s7 D! W9 x' A: B4 K( ~
            }
    & n8 O; q( G6 i        else  ^( R1 Q, M& |
            {) d" T% E) y% M& T5 I) l, J
                    pHdr->free = TRUE;. }1 r8 W2 ^6 v+ N
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    * K( G/ H/ x8 O- t; t" g. G- G        }
    - s% @* ^0 E) e1 Q; p
    2 U, V+ C* {, ?3 R, G7 x        /* check to coalesce with the next */
    4 H% w) b& t5 Y# a4 g0 A' u9 L        pNextHdr = NEXT_HDR(pHdr);; V9 o; {1 `% S- v* a1 A+ j
            if(pNextHdr->free)
    0 P; u* u( K* T/ p0 S        {$ w' l1 d" _! J. l
                    pHdr->nWords += pNextHdr->nWords;
    ( F/ {6 }. l& {% n& d' q( `                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    2 m  Y2 F: \# ~( I, c, |6 a) L        }
    6 W3 Z$ T) y# n- @, N, Y* X7 a$ j, \- l3 g3 I. S) }/ Y8 B
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    % n# w6 |5 Z9 K# o" X3 c; ^( i        NEXT_HDR(pHdr)->prevHdr = pHdr;
    6 a6 H: j  ]) \1 l! B1 M8 m* `4 t, ]# M/ P
            partId->curBlocksAlloc--;4 D/ x6 ]& g( d% `, K. ^
            partId->curWordsAlloc -= nWords;
    * S0 O$ S" ~) ^- v4 @
    + N, H" O9 E2 L8 o( W        /* TODO give sem hear */, U9 y+ y: c& e% g3 u/ v
            semGive(partId->semPartId);
    ' N" _5 _, I1 W, ?; |  E        6 g9 k$ Z, p4 ^7 H4 T3 x7 q0 l
            return (OK);
    * K( M0 {$ W1 E, J) {( _}
    / V9 v+ X: o! D8 L* w* W9 |" Y
    - Z; k( U7 `, C7 {static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)/ {  R2 d/ ?# S
    {3 U. k* L, e4 A5 Q) ?9 U( k: h
            BOOL valid;0 B% j1 [1 x) |6 v
      i0 N9 b7 T) n
            TASK_LOCK();& ~  e8 F2 r. p/ L1 L9 M9 `+ U& ?
            semGive(partId->semPartId);4 D# Y6 ~& J' O
           
    % v4 n7 N" H3 s: \; I) U, r* u        valid = MEM_ALIGNED(pHdr)
    % `' q) E$ U+ _2 N6 o7 e9 ~        && MEM_ALIGNED(pHdr->nWords*2)  j% N" W7 E" f2 E( F
            && (pHdr->nWords < partId->totalWords)
    * X8 e6 w1 b# m  d6 G        && (pHdr->free == isFree)! U# Y  o) E0 h8 n! i
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))) [2 y/ G* B. T
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    1 C9 [2 }! b: b2 p2 ~$ V: h       
    ) z/ h" t& b+ ~% K" Y2 ^, M        semTake(partId->semPartId, WAIT_FOREVER);
    # m" |: Q( d7 K" a# m) d0 W        TASK_UNLOCK();
    $ F! A, S7 x0 h0 N' z7 h/ O& k) h- Z/ V! c/ _/ Z0 `+ G; ?$ x# T& x9 b
            return valid;4 q8 {1 D+ Y$ ^  t/ j) v( S. l: e+ O4 G
    }
    ( d2 O$ E" S" X  j6 R. S# }( N2 ]- ~
      a1 B7 V/ i& z: ustatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    0 T4 U7 e3 N! Y# I( Q/ w        , FAST BLOCK_HDR* pHdr/ J# h+ m1 k7 x, }9 {3 B# p
            , FAST unsigned nWords
    3 l3 m1 _! M4 z) M& C: e        , unsigned minWords
    & |. U6 q+ m0 x' X. Z2 ~" j- g5 |5 N        , unsigned align)
    . H3 k* }5 a' E% j3 l{' E) Y# w/ H; J/ u# p
            FAST BLOCK_HDR *pNewHdr;+ p8 j% ^4 x0 Z9 P
        FAST BLOCK_HDR *pNextHdr;
    8 T# M: s$ E* u& t    FAST char *endOfBlock;
    . q8 ~. K( d3 q! \- F$ o    FAST char *pNewBlock;
    1 N- s/ H/ n& y2 ?# U' {; y: U$ R8 }5 Q    int blockSize;
    ' ^0 u  b: a6 L  E- C
    4 Y1 B( l- M7 P- C- o; v        endOfBlock = (char*)pHdr + (pHdr->nWords*2);3 T/ h+ V2 J* S$ n# T5 e3 J

    ( p& |) ?; ~. B7 I# d/ _& s& A        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));4 b: m  C# ?! d
    ) q# _5 e  i8 N# |
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));4 f- I9 O. w( N! s" e' o: k
    $ ?2 K3 n: \# U8 K. Z! A
            pNewHdr = BLOCK_TO_HDR(pNewBlock);$ j% y; |, ?# {; A8 I5 o2 ]& T* @' |
    , P4 _: m6 F$ d6 W" o. l# H" `
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;* l) J) i# t$ m6 c% c6 s$ n  c- x

    4 v1 _0 d9 C# L" |- g( p  Y" L& Q        if(blockSize < minWords)
    7 K* W! G3 d5 S4 s- E& g2 j        {
    / b  `2 E- i- P2 ~+ v                if(pNewHdr == pHdr)
    ' B5 k8 G: E3 C, O                {% N  b$ B# H" o0 l
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    8 y% w1 \" v1 S5 o                }
    & Q6 M( I* W& E  B7 `) C                else( L! ^3 _2 H6 p/ Y" z
                    {! o, M  a2 x- f% I2 s  A0 }
                            return NULL;
    # d6 Y; d( k9 S. r) [                }3 s* U% _  R9 J! k5 o: l
            }
    # g& B% w6 T6 X        else# j/ N2 F- ?; C
            {        /* recaculate pHdr */
    # Y  ^) N# {1 t                pNewHdr->prevHdr = pHdr;
    . ~6 e7 ~* z+ S* B$ x) |( r                pHdr->nWords = blockSize;
    $ |6 Q* H1 Z) I1 i7 w        }
    5 k: ~$ i6 V) H
    ; n8 R8 i6 Q+ O, ]3 o* R        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))' D* r( s. _/ p0 V% B* [1 O
            {1 Q0 r0 |# r" l+ Q- m" q+ s
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    5 R6 e. L! A. s* {$ W                pNewHdr->free = TRUE;  l5 _8 e) V6 P: Q- Q9 @# `: I

    1 a" {9 [5 X6 @  w                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;4 v. {4 G* ~9 i' z9 i& }
            }
    ' S! @4 L9 g+ U2 |7 N' @        else
    $ X& s7 A* M7 R        {/* space left is enough to be a fragment on the free list then */
    + S$ p6 P0 q; I/ ^3 ]; g! ]9 v                pNewHdr->nWords = nWords;" D5 l* r) z$ ]% ^
                    pNewHdr->free = TRUE;
    ! p7 {$ _0 J% ^1 R6 t1 I0 K2 _+ K2 ?. }6 I
                    pNextHdr = NEXT_HDR(pNewHdr);5 ]7 Y+ n9 |2 H+ H7 v3 V8 p% f: B1 X
                    /* words 包括BlockHdr */
    ( [% q; x! a8 a) a, r                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;/ p# P* f. n; j& t8 R9 h/ Q
                    pNextHdr->prevHdr = pNewHdr;; \! ~, c% E2 J9 I6 j; f. [
                    pNextHdr->free = TRUE;& x: K3 O6 ^$ d' z4 r2 I& z3 ~; ^
    & }3 }# K1 y$ }) \# F+ \, V+ E
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    2 y! t4 {4 A5 F! h1 d$ l- _4 |: ]% [% ~: l, \3 u* b1 w
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    ! ?4 ~3 v9 L9 b  o* B        }+ _. H% K4 E* i! }# K
      A8 T& }0 i) g, j
            return (pNewHdr);
    . ~+ F; p. y4 M& ?" x) O9 J3 v0 m}1 x5 O) s/ Z* U4 G/ k0 ]" Z' @" A

    / a4 f1 u0 G1 V1 a! @, s4 F) }$ Jstatic void memPartSemInit(PART_ID partId)
    , C* x8 X/ Z. ^7 ]- e2 q{, k8 O: b6 _. n+ b$ H: s" c/ ?8 x
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    ' P! y$ u9 ~! L& _6 ^' E  K( G7 b& @9 v) g
            partId->semPartId = &semMemSysPartition;
    + |/ p: ]. O5 \* x4 ?}9 ]$ }; ?3 s' I6 e! f& m; v' w
    5 `/ N+ d, J( j% o, x1 j
    void* malloc(unsigned bytes)# W: N3 P5 j4 }" D: |9 k+ k
    {
    - a; u+ U( d4 O8 o+ \        return memPartAlloc(memSysPartId, bytes);0 ]. p, M% f" `( o, Y& _- K, U
    }; i; D8 ~% z' L. K
    ! n4 j2 U. ]' B  j3 h/ `6 ^
    void free(void* p)8 x2 g$ s) b; t# c. p
    {' y2 w7 g+ L) o/ n8 O
            memPartFree(memSysPartId, (char*)p);# H6 q6 Q1 E+ {& M" d  N+ Y
    }8 H7 V% W% \$ ^# L+ K
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2025-7-17 03:23 , Processed in 1.033301 second(s), 50 queries .

    回顶部