QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2903|回复: 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++下的版本,更方便调试。有需要请留言
    8 v$ ~' ]3 R$ g' t1 d) d0 c3 y
    ) H" A3 h' F  w/ p- u! P( p, P0 }% B- Q/ `

    : F  ^* f4 J4 z' F *\file
    5 o. r7 j$ Y6 f# A7 k *\brief                : i2 c8 {6 i+ n* _4 F  m9 \; m
    *\details        0 ?! e# B3 H$ P1 P$ p
    */ q- R% W8 h6 i' w
    *\author        Janson! h/ M, O. y8 j
    *\version       
    4 w6 G) E& `2 w! T: t) S5 M, D6 }1 i *\date                04Jan125 Y$ ^* s+ Q- J! ~5 P
    *8 {* ]7 k; {' |+ d$ q4 L
    *\warning       
    7 `/ Q# Q2 M2 L- _) c* q *' r, t" M/ D  t- p3 N1 `; c6 C5 C5 \: p
    *\history \arg        30Jan12, Janson, Create the file
    7 b0 \. ~1 `# o' }8 }, { *        modify from VxWorks source% O  W" w/ `) f8 V6 ]) Q! A
    *  Legal Declaration: it is for studying VxWorks only.1 r, j/ h% s" o& ?2 M( \) s; n
    */
      ~9 O: L3 z9 @- P' S9 K/ P+ p#include "includes.h"
    : `9 ?+ C5 D. y0 S& d% j, z9 o5 V* B6 F* }, ]; E* f
    /* The memParLib.h file is hear:
    $ M7 L1 c( \4 C, Z1 f" o3 x8 u. ]https://code.google.com/p/vxwork ... rivate/memPartLib.h5 O" U  {" p. e: T9 c
    */
    0 M% ]% ]7 u" n/ v" V7 w- I
    # r. ], ^0 t( w- Q/* optional check for bad blocks */
    0 a2 ~8 b; X, V& x$ i6 M% j& O  w! k
    $ q" H- n, k* m0 N#define MEM_BLOCK_CHECK                        0x10: N( O3 A8 F# n/ E/ V0 E
    3 U4 e2 o0 z8 C* u- Y/ u
    /* response to errors when allocating memory */4 F% W* V& r; w
    * i% u' x. P1 Y# d2 L
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x201 |5 n6 q: z* R! `
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x405 R7 v# N! C. N
    " {5 L" J: Z3 x1 b1 K
    /* response to errors when freeing memory */. A2 g2 ]+ @% f' \# P: |$ R

    / l% _  S2 e. v# n+ ]7 M) m0 A#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    . G8 c. e  D3 v#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100  p4 x. v) ~& }# ~0 V! Z3 V

    5 h# H' N* B0 h#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    8 e3 t& z1 z+ {; _2 R4 Z/ u#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    ! {( e  D" }; Z
    - X3 w; {$ U/ n7 N6 q' |#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))2 V) ?0 r; G% c) m7 X/ e
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    * |  H2 B* s2 \. p5 C                                                sizeof(BLOCK_HDR)))
    : S1 O3 ?3 l, K7 Z; v
    " i1 M; c/ F. j2 [#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)- @  c. l) n4 L$ P! G' G2 b
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    6 x) X: c6 J+ k$ M& g' k5 d' T5 J                                                OFFSET (FREE_BLOCK, node)))
    2 _+ L- k6 X* Z% D( R% A2 L( R- J' R$ K/ O8 _& B, O) N
    static BOOL memPartLibInstalled = FALSE;3 P) C2 r. B& C! w8 p, P, i! ]2 q0 L

    # [/ Y3 E8 E# jstatic OBJ_CLASS memPartClass;
    ) p6 l7 P: F( x2 @; m0 D* H  LCLASS_ID memPartClassId = &memPartClass;4 A& r. E/ [3 U
    9 E! h' T4 s6 ~" [' [  u7 ]8 k& o' }
    static PARTITION memSysPartition;5 l0 E2 Q: S& R) K# p- ]! W$ m
    PART_ID memSysPartId = &memSysPartition;8 K  V2 R. V: k. P% t) M( q
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    # f/ T1 e9 H% T( Z1 Q( e$ ~6 S1 y4 L& F2 q5 d5 @, y
    static SEMAPHORE semMemSysPartition;
    . M& B9 R+ a* Y8 T6 X: f9 @5 l2 |. u5 o7 ]) ^( G
    static void memPartSemInit(PART_ID partId);6 r7 a; J" r% V7 o. @& {
    ( ?: Q& k4 W, {% l7 `7 `9 D" N7 t7 a3 a
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    % Z. b# L$ q$ X% }$ I, A% C5 ~/ p# h7 x! G: j7 W; y
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;/ M) u6 {2 F& d( d4 H* P! \

    $ M( ^! m, }& X+ j  zstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    ( Q. ^+ D: p8 W0 {5 Cstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId8 A9 C- A' U1 d0 X( z/ M, y+ b
            , FAST BLOCK_HDR* pHdr% T0 b/ J, B4 g+ D8 s
            , FAST unsigned nWords
    ' E) y( O  g% t$ p7 \% [        , unsigned minWords! |+ h/ ]2 l- L" q
            , unsigned align);6 F& F# m1 D6 ?5 D: o9 ]# E

    ) H$ K' G$ Q% n; i. b6 q4 xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);1 N8 O& B. N) e4 N8 o& h! M

    . E" j9 n; L! a6 r; A8 RSTATUS memPartLibInit(char* pPool, unsigned poolSize)3 n2 z3 c3 `) W* g* c  f$ \8 @
    {
    3 p- h) H  e- u( b0 M& N        if((!memPartLibInstalled) &&
    ( S( P# ~7 q1 H3 V- V: d& G                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    7 b, p- l4 Y: ], p* u$ D- S2 R  T                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))' _' q7 t0 E1 A3 D  n7 O
            {* m7 W6 i6 y7 q
                    memPartInit(&memSysPartition, pPool, poolSize);
    4 v3 x, d9 M4 h$ R/ F8 h                memPartLibInstalled = TRUE;" g( ^4 c* C2 Z, S: I
            }
    % h# n2 U4 B+ H5 t/ P
    * q: I, T1 e) @+ s2 D9 ~7 w7 q- n        return ((memPartLibInstalled)? OK : ERROR);
      c+ L+ I. c+ K  ?& |% ~1 I) A, A}
    " A  a+ o5 ?! n
    4 z( L  F& I' v: T1 h# V. ^PART_ID memPartCreate(char* pPool, unsigned poolSize)
    0 l- c$ z6 X8 V3 {: z0 g{7 p5 v4 V7 x) V6 P9 g) e$ `
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);1 H2 h, w/ Y  s7 s" r
    3 g8 ?# m2 P; l( f$ _
            if(NULL != pPart)8 L1 S9 S  f2 ]: ]. r6 _( n/ |
            {
    4 n) o% d6 U5 k( V                memPartInit(pPart, pPool, poolSize);
    ' _* ?- O' e; S/ k0 e3 s1 x* U        }* O3 w& T8 C, @+ S

    6 E4 r# m1 H8 K; j0 P9 ]        return pPart;- A, C/ }6 e5 M' q5 R
    }
    + s+ B( F8 ?( h) n
    , c+ q6 p' z. X- hvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)7 g3 p+ j; C& `6 l( J- `; [
    {. r, y0 w/ n* g5 l0 u
            memset((void*)partId, 0, sizeof(*partId));& g2 T) l# e% j) W% p3 \0 ~
    ( P  \. r8 P( q- o7 M. d$ B0 d
            partId->options = memPartDefaultOption;
    & k1 G1 M* r9 C        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */; i2 w: N8 n) b/ w3 d
    % z3 X1 v- u5 l" p
            (* memPartSemInitRtn) (partId);
    4 X$ s/ U9 I8 ]4 I6 a" P% Z       
    3 {* A5 x) H3 i* W5 s        dllInit(&partId->freeList);8 G$ R. [% E9 l5 _% S: T( @4 a
           
    / b" C# I, c2 [8 l4 W3 M        objCoreInit(&partId->objCore, memPartClassId);
    0 ?: I' a' b7 g+ n       
    7 e* L3 r  \' U7 H, t0 D8 e- I2 a        memPartAddToPool(partId, pPool, poolSize);# u3 l$ b( Y6 ~$ G$ J0 y* F  O
    }/ K9 q; S1 F6 a4 f$ V7 T, f
    & Z1 M$ R- u3 T( T  B8 k! n
    STATUS memPartDestroy(PART_ID partId)
    . {7 ?) Q$ M2 D5 x0 l; o1 _- t{
    9 a; r+ \0 k4 d& i        return (ERROR);
    4 @: d2 l$ M/ _6 S' F* J/ N/ r}  K" u! \: v) _9 z+ m) x4 V
    6 {0 b* S% R1 X
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    ) }8 k1 Y3 z5 W  S  `{
    # O2 s" }1 @* c  A' t3 y    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    " R1 n& J$ g* x* y}! U  z% Z: Y/ m

    ) T+ ~% v1 J  l* `
    + h& o1 X7 @* {) Astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    ( s: A# Z- y  \! ?{
    + Q1 P: h( I  W5 T4 T        BLOCK_HDR* pHdrStart;
    3 i& O; B! v7 ^% L1 p; S1 V        BLOCK_HDR* pHdrMid;" s6 p% `) f( w
            BLOCK_HDR* pHdrEnd;/ d( r/ _: _/ |* b; |! M
            char* tmp;
    8 C% g! d- m, V0 p8 n( c        int reducePool;/ s" U8 i! Q5 X
    6 r( e  M0 ^0 z2 }" S6 b! S- l- L
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */- S- F3 b- Z! i$ ^9 ^
            {
    6 ?% D4 X4 W$ ]0 F# r/ X) W" G! z                return (ERROR);
    . b5 U0 D4 f" Z& I0 C        }; O. Z8 X" \& g- Y: s+ s0 C
    % Q- i6 g0 a# q. Y8 J  t
            tmp = (char*) MEM_ROUND_UP(pPool);
      ]& g: a  D7 P/ S3 B# V        reducePool = tmp - pPool;5 l, J0 E3 i- Y- C
    6 i! ^8 m4 k& P0 K7 w, M
            /* adjust the lenght *// U) v8 x' X% h! d# l2 A
            if(poolSize >= reducePool)
    ! A0 B8 Y/ C3 l+ d" M& T8 ~* c5 ?        {% ?6 U0 p) `. v, Z- F3 p
                    poolSize -= reducePool;
    3 _6 a& \2 I" V' H- X# ?- t        }
    2 H' U$ ~: ]7 x- N2 y* [% O) t, N, y        else& p: F" z3 h: j6 h9 E
            {
    6 Z# d  x8 x7 x1 e! p6 g5 S1 T- U                poolSize = 0;
    / P9 B; `3 ?* |; `        }
    - m0 U( j" d6 L0 i+ o        pPool = tmp;; G" c2 I* N8 y  k5 y+ u
           
    - m- j% T- B' Y, p1 d1 v! I        poolSize = MEM_ROUND_DOWN(poolSize);
    ( Y, b; A, e/ g5 T$ U+ v/ M        - w/ ~5 A6 S/ f
            /* at least one valid free block and three header blocks */( k5 F+ z: a! _- q
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    6 J6 n6 P! ]) c4 L. ^5 K        {  ~# x6 A4 \( r/ L7 L
                    return (ERROR);& N& V( t. ?* B9 C! Q- o
            }
    : A# f, W' @  c0 u" I5 G  [- l* x" E8 t
    - a" P2 }5 s9 j$ y+ Y        /* initialize three blocks */2 Y. [8 ^) K2 r$ o1 Z! b$ M- F8 w
            pHdrStart = (BLOCK_HDR*)pPool;
    " c" ~3 J+ u' n2 ?2 r: T        pHdrStart->prevHdr = NULL;
    ; h, j7 R+ m+ w        pHdrStart->free = FALSE;                /* never in use */
    * L4 Q, \9 f" y3 y- K  {- u2 q, u        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;" i& H) ?% s, f" a: N7 }& Y2 y& A
    2 U$ `( x( D: [
            pHdrMid = NEXT_HDR(pHdrStart);
    $ `( d( R4 k) ?        pHdrMid->prevHdr = pHdrStart;
    . j2 j( }9 v$ b: m        pHdrMid->free = TRUE;                        /* the main block */2 Z5 R, ?! p4 p! K
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;2 @  }. i& j  {, b: G; r6 L
    : A! W% R3 t/ [' u% q& |
            pHdrEnd = NEXT_HDR(pHdrMid);( T6 \4 A" s, h1 ^& M' }6 s
            pHdrEnd->prevHdr = pHdrMid;5 u1 ?9 y. ~- U$ l; I6 y: ^
            pHdrEnd->free = FALSE;
    9 z1 B: }1 o! D' k: f% F* P        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    , c. B; O5 N! h) P! N- D
    & j* a8 q7 a! W, o0 J6 ^, M        /* TODO take sem hear */
    ; t- T: r2 ?4 {; L( B        semTake(partId->semPartId, WAIT_FOREVER);
    , t: e. g2 H! W4 e" h        0 t! g* W  ~- x6 S' Z
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));  F. ]( h$ f) s! y" p  s
            partId->totalWords += (poolSize >> 1);
    # w3 }" w" r, l8 D0 D: j1 d/ ?+ r2 }1 O0 b! m
            /* TODO give sem hear */
    & ~) a  H: L# k3 Q" G3 u/ E" Z5 J9 |$ N        semGive(partId->semPartId);% M' j; ?7 U2 D& g6 t7 t$ A3 M5 z

    2 P0 [2 t$ G: S2 o' A
    ' @( ?) b# @! I9 n( ]- R- X( b4 _        return (OK);$ ?$ P& P+ s1 X. v
    }
    9 J" \" h  ~) B6 S& c' ^( _  H' e/ _
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    & t9 j; j0 {! L  c{
    4 b( M* g8 ]/ @4 \# B. A: ]        FAST unsigned nWords;2 E' q2 i: w1 E# I/ H
            FAST unsigned nWordsExtra;: P+ T. ?) K1 J# Y. `) O
            FAST DL_NODE* pNode;# J5 l/ Z) a( h/ A) q% v: ~
            FAST BLOCK_HDR* pHdr;
    ( s0 u# Z( j/ N0 D        BLOCK_HDR* pNewHdr;. f" t' s( [  p  k. N
            BLOCK_HDR* origpHdr;
    2 ?: W* }. s% [- w) }7 Q
    + Q' {+ a+ G4 C" U/ ~4 V        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    : d5 [1 s1 A2 J+ S9 A7 X' ~        {* r/ O( o( h1 I8 w9 ~* E
                    return (NULL);  I# |0 \* H7 {* M/ G) x
            }- n% z1 `  S6 v3 x
    # ~! U1 e* m* t  o' B9 }) C8 z" p
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;9 m$ q! g5 u. K: B; G( T

    2 ^0 s/ P4 ?) y. p% w0 o( V        if((nWords<<1) < nBytes)4 l% _5 S# ~5 A3 Y& B
            {" @" j: b! |* M; u) E
                    /* TODO suspend the task */
    2 j+ F4 M+ J( q' v& m- e, k                return (NULL);1 }( P$ b+ f% ^( ?' j2 ?& A" B4 w
            }
    / o9 V' G6 M! I) m2 y) z( z- ]) z# T& h! y6 n9 R" b5 _" b
            if(nWords < partId->minBlockWords)
    ) j0 f3 V& ^' F% \( n* h. T        {
    5 n6 _. F7 C9 F1 C# T! T                nWords = partId->minBlockWords;
    4 e* ?" s. v1 G! y+ Q/ m2 G; J! V        }$ \2 T& W* ^2 q; X' U! T# P8 d
    7 ^3 [3 S% B. o6 o
            /* TODO task the semaphore hear */
      x) |- T+ D% K' ]" j& n! G        semTake(partId->semPartId, WAIT_FOREVER);
    ; X+ T# `- f2 Q* c        pNode = DLL_FIRST(&partId->freeList);
    ) X+ q, C4 f  C1 ]' x1 _        nWordsExtra = nWords + align/2; /* why? */
    ! r8 s& z& w3 y& Z1 g* K9 S& O2 d/ d; V# z4 H
            for(;;)
    0 |! x9 @# @, Z: a) ?        {9 @% ^8 M/ C+ Q) h4 J! a! Z0 a  S
                    while(NULL != pNode), T5 X8 }; ]* {! k. r7 ]
                    {
    , _% _+ F9 q( z                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    * z4 D# y( L' x' D9 N# v                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 7 ^. r7 c, r7 A
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    . p0 t  j% {7 @                        {
    4 Z( J9 m/ B; I  F: D                                break;
    ! f/ k$ z# [8 ~7 T                        }. g* p5 h1 A  \$ e) j

    & g( x( j2 |' U0 I! }, \9 P* [, C                        pNode = DLL_NEXT(pNode);& D: c$ T2 {8 @& W
                    }  y( z# B* x- Q- [" K" o% n# _
    ; Q* P. s( ~% P$ `8 t& F7 S
                    if(NULL == pNode)! G$ h/ G# i; B/ @) I- L7 ?  k
                    {9 q: @4 S& I8 {2 O. M" X  `' W
                            /*TODO give the semaphore */0 O% r5 U; H/ P/ J4 Q; `8 p& q
                            semGive(partId->semPartId);
    9 K5 X/ h0 L4 ^  `$ O0 z                        return NULL;0 S+ }+ \$ }; m# O5 J: F5 X$ q
                    }
    & j4 w5 H& b+ |# x. x
    5 H& j+ Z, m) H5 B1 e9 |: m                pHdr = NODE_TO_HDR(pNode);' U8 j. ~3 j7 j6 ]3 m
                    origpHdr = pHdr;/ Y9 L; D/ \) O1 l) Z

    . ?0 ^  T* k7 U                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    / |. R6 f2 p. i+ e" n- `( ]% A( |                if(NULL != pNewHdr), F6 T- @" L$ `# Y8 l% |% u* e
                    {5 r& h* q: F9 W( y
                            pHdr = pNewHdr;
    + v2 ]+ f6 _5 [                        break;
    4 H/ g3 P6 J' U                }
    ( L6 _$ \8 R0 N( D* L1 m2 D3 H$ J2 Z  S& d! h1 D) j
                    pNode = DLL_NEXT(pNode);
    2 A& w" k2 W, s% _4 H: Q1 Z        }  U0 X1 a2 x: a5 a1 |3 S
    ) D. k; K" [( V1 b2 c
            pHdr->free = FALSE;" [# [' {$ S' _" M) _6 p8 c
            partId->allBlocksAlloc++;7 M* I3 H2 p% g% e; C' H
            partId->allWordsAlloc += pHdr->nWords;
    5 ^) `: E& L7 |2 f, }( Z        partId->curBlocksAlloc++;; u2 _" p, M) R0 S
            partId->curWordsAlloc += pHdr->nWords;. V# [( d$ {2 `5 o3 A2 _7 t

    3 `3 [( V2 d" B9 k" @. A: y        /*TODO give the  semaphore hear */, q, S/ W0 c0 I9 x1 B. }
            semGive(partId->semPartId);2 d; {) f0 V! T9 e/ B# t# f
            return (HDR_TO_BLOCK(pHdr));
    6 u& Y2 |) ?+ }# o0 }, D       
    ( u, D5 c3 V% `7 }}
    9 u/ s+ D& }/ N) R8 v, V
    . p0 a" N1 c9 \0 M8 U. @  A' ovoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)2 w3 |; \6 b/ B/ a8 A3 A$ A% H
    {
    * }: q0 a* a1 C& }( B        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);# d( t" T, _2 ]
    }2 X* {  y9 F# A+ t$ v
    3 m* w9 n7 N  e3 ?
    STATUS memPartFree(PART_ID partId, char* pBlock)
    ( a+ v0 A% Z. H% }0 i{. n- E# H9 s8 F$ s# N( c1 H
            FAST BLOCK_HDR *pHdr;, p9 P8 M' o; [: m% Z
        FAST unsigned   nWords;
    ( K) c, K, h4 x# r3 ]; }  n. F4 W    FAST BLOCK_HDR *pNextHdr;4 X' ^7 {, m% ^) i% O( k0 D8 [

    . w. w8 Y5 ]" S6 O: N# P3 r        if(!IS_CLASS(partId, memPartClassId)), ?: U# O) ?$ Q! E" x! v
            {
    3 }' g$ K/ R& s# h; m                return (ERROR);
    ) Y" O2 [8 G' P  m5 q& w! c        }1 b( G. [( [3 S: M1 C6 h7 n4 y2 Q
    % m$ M9 f8 `: L6 o4 U
            if(NULL == pBlock)( a; E- G: q* W. p# Q; i" f
            {
    ! \0 s/ o- n& _2 v3 ^                return (OK);0 a4 f3 L7 P1 h2 N% e* [
            }
    ! P1 K5 s7 k5 J, H8 o' Z( ~) k& b5 `3 D! F- p
            pHdr =  BLOCK_TO_HDR(pBlock);
    * _/ Q  [& `1 g1 C  T
    $ s, N4 R  k* p4 Z/ S6 @1 o        semTake(partId->semPartId, WAIT_FOREVER);
    ) B/ m: V* K6 F; e/ q
    . b! e8 w% j; @9 y! o        if((partId->options & MEM_BLOCK_CHECK)- {4 A$ b7 N& V4 m
                    && !memPartBlockIsValid(partId, pHdr, FALSE))4 c  k- `! ^  n. C
            {
    ; y% y0 n4 q+ W& ^2 R, @6 B" V                semGive(partId->semPartId);$ ^# h  h. O2 o9 J
                    return (ERROR);
    : V. K  D% L: p        }0 C- ?$ y$ M2 Q) H4 E. I4 ?
    3 f" n  C) b: y; {4 l  h
            nWords = pHdr->nWords;
    + n' A# h+ m. d* O3 I$ x        if(PREV_HDR(pHdr)->free)
    , m" c% u8 C5 ]        {/* the prev hdr is free and than coalesce with it */
    7 y# c4 A$ ]3 i$ I: \9 A& R3 S                pHdr->free = FALSE;' e" _9 n% c- w' C" Y
                    pHdr = PREV_HDR(pHdr);
    . t$ m2 [9 d6 \9 a% d( Z* H$ ?                pHdr->nWords += nWords;' O( B4 D* K1 l: s7 F' E
            }% f( R* v, w( b7 E' Y
            else
    / u0 A' M: {1 {% }( {; [+ ]        {2 I# n4 w! t* e# Y# }1 Z
                    pHdr->free = TRUE;
    0 S& l7 r% t( T( t                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    # v5 K. v6 Z' q        }
    2 Y2 a3 N* t2 x8 ]
    0 b, i- a: j2 ^3 l! Z: Q        /* check to coalesce with the next */
    / {  B+ A9 U1 i1 H8 |! t+ x        pNextHdr = NEXT_HDR(pHdr);" r0 o2 @: U- l0 i* S) Z* D
            if(pNextHdr->free)) R. M9 W' e% x8 e' u
            {3 ], A  k/ A6 @" }5 ~1 ]) ?. X
                    pHdr->nWords += pNextHdr->nWords;
    " d, K! ~5 S, P0 I$ D# m                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    $ ]' w- Q/ c( O$ X/ S9 G6 A        }5 [8 ^9 c2 z) @3 K/ n3 g5 k
    3 T5 V* X' _/ A; D1 D* f
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    + g% v# A0 H( |' z: P! I- k        NEXT_HDR(pHdr)->prevHdr = pHdr;
    ' R2 y' j6 [- N# H) h, d! h$ W' g& H( c+ p# k  j$ J
            partId->curBlocksAlloc--;% `+ G3 h! S6 u2 h2 E+ g
            partId->curWordsAlloc -= nWords;3 k: P% N5 d5 V
    8 `7 J/ x9 M+ F8 T3 M: L/ H1 Y
            /* TODO give sem hear */+ {2 b7 Q+ a$ J( @
            semGive(partId->semPartId);
    . l3 R( q1 {1 x4 y       
    : g1 {9 Z# {% g6 ~* f9 `        return (OK);4 T+ O& y0 P0 s/ Q  ]0 [
    }
      f2 c+ K/ l; c9 A; F
    % u4 I9 K* e3 Q: H7 v5 h; Gstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)" k" Y3 ]1 s& ?" r+ H+ c( b2 ~
    {8 o3 \1 c8 F# @5 i" g& \; D  ~
            BOOL valid;# I  A* u8 ~7 D0 r
    1 v' _9 s6 j* O9 P$ L" z1 t
            TASK_LOCK();
    " \, c* d6 W! `( s+ X        semGive(partId->semPartId);
    ' z% |' {8 z/ ]  K+ N       
    & M; p: B+ M4 |1 |& a        valid = MEM_ALIGNED(pHdr): L- v, H3 C& q
            && MEM_ALIGNED(pHdr->nWords*2)
    5 K% T# O& P" Q3 h        && (pHdr->nWords < partId->totalWords)
    4 x' U" z3 C; w) C5 g% @" |9 f7 a" E        && (pHdr->free == isFree)6 ^) ]/ x# T6 W- t, h" C1 s
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    ( I2 `4 R" n9 x5 n% r        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    * i$ {) ]6 j- P* ]# n9 t       
    ; j; g5 P: {2 l! a- f2 O0 G        semTake(partId->semPartId, WAIT_FOREVER);
    2 K$ h$ B, I( i        TASK_UNLOCK();
    & }( O5 y& W# O: l  k% H0 m" A
    ; |" G/ K1 I) i) f4 d5 j" Q. q' I        return valid;
    - J+ S: Y! E6 ?- s}
    9 l% O  D( X# E& g1 ^2 ?% n/ v6 ~: t# Q6 F- x
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    : B& w% z0 B1 B" |0 O# \; H# e$ x        , FAST BLOCK_HDR* pHdr/ ]' g& C7 y; ~7 A7 o
            , FAST unsigned nWords, n) @% K4 a  l  q
            , unsigned minWords$ L( G! P( V2 u1 j* X! g2 w5 y* s
            , unsigned align)
    $ B) r+ q! e  }% v- `, K* [: ]{, [# f; B, a# v& A+ x0 N" T' K1 {! P; \5 E
            FAST BLOCK_HDR *pNewHdr;$ N/ D8 w. M* T4 e
        FAST BLOCK_HDR *pNextHdr;
    8 p8 i* r1 H, c% @7 h    FAST char *endOfBlock;
    6 [7 m& o1 K7 O7 l( S    FAST char *pNewBlock;( }& {# q" s9 n+ D' ?0 j; G
        int blockSize;
    % j2 C5 W& n; y) a+ O& _& T0 b- ]: R; R+ |8 y+ t$ k8 f1 h
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    $ P8 a$ j- b0 b3 l# S2 G1 a1 i7 h( [4 m
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    / h  v2 R6 L# e% s$ w
    # j$ }# {. M/ @! B        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));: ~- z$ K( I. z/ y2 h9 q2 P- j

    6 ]. k4 Z: ~6 A3 z        pNewHdr = BLOCK_TO_HDR(pNewBlock);7 M8 h- ~' a( d6 u$ p+ S

    : r' ?& Y6 v( a        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;4 G$ z  v9 |9 T, O' r  v" d) x! b
    5 D) G- c6 D* ^5 @
            if(blockSize < minWords)& G' u# a! l7 r
            {
    8 g2 n( Z: ?+ g* y3 H& U0 {+ R                if(pNewHdr == pHdr)
    , b; F! s: B2 K- }2 }( F5 ^                {
    2 A) d5 O. v/ ?, g" Q                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ; `3 D2 d& _- b                }9 h7 o1 b! l8 s5 o0 N
                    else
    ; r9 }  X* N# j6 d" R                {
    % z4 R8 l) G; d0 I( a( a                        return NULL;4 f3 H8 i( ^# u
                    }2 t4 g* a( K4 S
            }7 A$ x; q+ @. b( x
            else
    ! U) ], S( T! O' v  t        {        /* recaculate pHdr */% O6 H6 @' h9 ^' x# }7 _+ B
                    pNewHdr->prevHdr = pHdr;* ~4 ?: D9 q6 b( S
                    pHdr->nWords = blockSize;1 J* v. J) R  j6 f, b
            }
    / i8 O+ F* a9 }0 E1 _7 ]7 ^1 {0 y) i6 q* `3 F; ~; M( R: h" r0 x
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    * J% O) w: v8 m* K, B# p        {& O# i; \0 v0 L' b5 X
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;5 e' w! O6 R8 W2 @) Z
                    pNewHdr->free = TRUE;7 K' t& L% l5 z5 d! ~
    & e7 B7 F& C' Y% a* U' |
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    0 u4 |8 @# X8 G) Y- t. ^        }" K9 r/ B2 E8 M& |4 O6 f; u
            else
    - D2 `: G  `" w        {/* space left is enough to be a fragment on the free list then */- K; r  M+ V8 \& F4 a4 \0 A
                    pNewHdr->nWords = nWords;! b! s+ o, l8 D: O8 B: b. X2 F0 n
                    pNewHdr->free = TRUE;1 v2 w- A- L7 g' J7 K

    2 l' z+ o) F* |2 N" a; i. F                pNextHdr = NEXT_HDR(pNewHdr);$ @. d/ r$ w. z: |
                    /* words 包括BlockHdr */
    / q# G5 M6 o0 Q/ j$ m8 C9 ^                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;# B$ O3 W( O7 j9 {" S
                    pNextHdr->prevHdr = pNewHdr;
    * w5 ?8 k/ W, G  Y, ?                pNextHdr->free = TRUE;
    2 P- i" s2 m5 J8 m  W( O! J9 }6 Z
    1 @, E$ Y9 O. ]2 V/ L                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    1 Z; W! @! U7 P# J0 K& g" k' k7 c* A( s1 g6 r
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;8 r# S  o- E& X
            }4 ~+ ?. t, i. {

    ) T! O  C, i2 O: i        return (pNewHdr);, `! p- }/ b8 C% _
    }3 e, v" s3 Q1 X& L" l$ k5 l
    $ U2 e) C; g+ _4 b' u
    static void memPartSemInit(PART_ID partId)
    " Y6 x* G, S2 k$ `% U7 o/ n{2 ~; T9 B9 W( C2 b: S
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    8 p2 }6 Q- ?) s. f) J2 m1 f8 H& t) N$ d* E8 p, P0 S
            partId->semPartId = &semMemSysPartition;
    6 j, O" r+ J6 I7 v; Q" p}
    ; S, H+ N. ]1 @" t. k& P6 Z8 |+ i' Z. [1 }0 e! ]( F
    void* malloc(unsigned bytes)
    % M6 Y2 c& `: f* e1 R: D* \: |+ Y{
    - M$ J. \5 K. k5 E% K4 R        return memPartAlloc(memSysPartId, bytes);
    ) E6 }" c" H3 L}' m+ n: Z( a& u

    " A+ G% F9 z  v0 A4 q' t3 Z# Lvoid free(void* p)
    . c* P# |4 L  @/ L$ M{, l& ^- c2 q1 m5 V. Z4 l. a
            memPartFree(memSysPartId, (char*)p);
    " ^9 o- I0 [4 m. k+ B. R}
    8 P7 G+ d7 H& S9 E- r8 f
    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, 2026-9-3 07:49 , Processed in 0.415500 second(s), 50 queries .

    回顶部