QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2838|回复: 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++下的版本,更方便调试。有需要请留言/ t2 p+ O3 k% |1 s0 Q' X4 G
    ' ]. k) p1 [2 h, u) T

    & F* s2 A$ }1 O- [' j+ _. \% P9 F
      ^: t+ J0 Z! A2 d3 g+ L. Y *\file
    0 ~- Q) i% Q1 ?' N5 F+ y4 h *\brief               
    8 I2 s5 ^8 L2 U5 H% z% A* w *\details       
    * k& e+ X* ?" O3 M( Z *! j( n4 v) h7 m) m, O! ]
    *\author        Janson
    : T( M& ^9 p, L0 R. O3 |; W *\version       
    : @( z/ \# r; E3 N: K4 Y4 ] *\date                04Jan12
    % b! m+ Z- Z+ ?% v( n *
    0 T" h% o; L% _6 v5 T* J* U. C* A *\warning        ; M+ P3 a2 t* R0 |2 }# ]
    *
    0 |. \8 j& `  G7 d, C *\history \arg        30Jan12, Janson, Create the file
    * y2 f( r( z3 c& q, y6 ~: L, V( p *        modify from VxWorks source
    - o: Q9 B, _, f1 F+ n6 q" M *  Legal Declaration: it is for studying VxWorks only.1 p$ `0 o/ q7 {
    */: ~+ _8 K% R0 c) k2 v
    #include "includes.h"
    ) E' o8 p" Z: t+ ]2 B) A! S7 g
    6 E  K# y0 [1 [1 i! B! `/* The memParLib.h file is hear:4 x) Z7 V# q0 U$ ~/ C0 ], r2 K
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    + C1 F1 e( k! r' V8 z' H$ E- |; w*/! B9 f* B& G" i( f+ b! d% J

    7 C; }# F/ P8 ^* o+ u! \/* optional check for bad blocks */
    9 P/ i; e2 C1 L2 B' d6 C4 g& e8 A7 y, ?
    #define MEM_BLOCK_CHECK                        0x10, L8 `" c. U# P# K# d( A/ `! {. G# v& y
    : }7 b* p$ b, O, r9 L" h
    /* response to errors when allocating memory */9 ^  D+ }: l1 \' [

    9 `5 L1 K! M$ `6 O/ |: N#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    , R, }2 ?0 J3 P& f#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40- e% I; A' v" h% i7 C& O' w
    3 N! [- I/ A! Y* t0 R. M( P
    /* response to errors when freeing memory */
    ! \  c) t9 ]) I
    " O4 o- ]: K3 h" n) Z$ r#define MEM_BLOCK_ERROR_LOG_FLAG        0x806 c$ a' @5 s8 P% z
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    : W3 J+ q6 E2 ^. V& n7 U5 R% ?
    + ]/ [; {4 ~" j. ]8 O3 S#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))): Z& M3 D! \) e7 Y! ]
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    / w1 Q, R. i4 @+ ]9 w8 m2 g4 z  \9 {7 i: M
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    5 T, ?- |( b1 r" {0 ^! h/ F#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    : I3 L( }( }* h                                                sizeof(BLOCK_HDR))). E7 \* y* d# l( N. ^

    ) F7 x6 g/ e9 f. k#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)8 ^+ i& ^8 |0 \: X  f
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \: o. u# R7 G1 y
                                                    OFFSET (FREE_BLOCK, node)))
    : }7 [# d2 x! i2 I1 f" s4 U  v# m5 U
    static BOOL memPartLibInstalled = FALSE;
    2 d5 C' c3 Q1 z3 Z0 {) a
    6 H! a  y6 e! [( ?static OBJ_CLASS memPartClass;
    " f3 T2 y! W4 q3 UCLASS_ID memPartClassId = &memPartClass;% c% v2 D, x" W# q  E6 r
    6 o- {- r: s9 \
    static PARTITION memSysPartition;, E$ |7 d  J* r1 Q
    PART_ID memSysPartId = &memSysPartition;
    4 c; X5 z+ z$ cU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;5 f+ t9 W1 R# i0 k

    + D) G6 P. Q- E$ v3 O7 u4 ystatic SEMAPHORE semMemSysPartition;6 W3 {5 F* @+ t' k1 D
    , ^9 H  l, b( J. b+ Q- K; g
    static void memPartSemInit(PART_ID partId);
    $ Q( R0 ?4 E6 F2 M
    6 T9 O' R2 ?5 l# T3 {! C* @FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    4 y' U$ Y8 J. i
    1 g! @+ W( u. D) g/ Zunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    6 H' s+ Q% k$ v" z) Y: k, @- Q2 U* t* ]8 W
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    4 Z+ Y/ c+ p3 Q/ G2 V( ]- pstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId0 x$ o5 ]5 l9 G1 H( b
            , FAST BLOCK_HDR* pHdr
    8 e1 s5 @* b' m4 z        , FAST unsigned nWords
    1 n8 B: c3 a) J* C; l        , unsigned minWords. O0 B" h+ G* t% E* Q/ L3 b+ k$ r1 p
            , unsigned align);& B) B' W: Z8 X/ T" d' l

    9 a- i# @. |2 }. J4 o2 gstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);" Y1 n6 M0 l- o& W

    1 g, Y; z) q8 i( h5 F+ QSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    1 g0 b  d3 K7 q2 Y8 }+ b{: Y0 u+ ]# E' G$ h
            if((!memPartLibInstalled) && ; R6 v% C' c) s* L2 D- `2 q8 e
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    ' v7 J" Y! {, d8 N3 ]                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    % E9 \- z' J5 g        {
    7 C0 G7 H2 p; ^3 @6 u4 B$ d                memPartInit(&memSysPartition, pPool, poolSize);
    " X1 j. {, `' U9 m( l                memPartLibInstalled = TRUE;% R1 h3 f. Z& }. f% J' Q% O: F
            }: r( @3 h- P9 U4 b& X4 r
    ( [5 x  {" S2 K; d: r0 w7 D
            return ((memPartLibInstalled)? OK : ERROR);
    & m5 l. p" v$ M/ G! ]+ \; x}
    * p% W$ E- b% G( t6 {3 s# `! @8 L- J2 R1 N
    PART_ID memPartCreate(char* pPool, unsigned poolSize)  P& s$ l0 N9 j" ^# A7 L+ ?. g
    {6 z7 @! R3 m( b9 V
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    . |5 ~0 C( {: J% P9 y8 L. y8 p: ~! s6 K, d
            if(NULL != pPart)
    ; e8 z. ]; @% X: p* N. A) |        {
    3 k* W: Z& O  `8 e* N* H* N6 W                memPartInit(pPart, pPool, poolSize);
    & ]" b( e! S: z  X- W+ V        }* I) x- q" k, W
    # K" \, i2 |# {+ Q6 Q
            return pPart;2 O- I/ U$ M0 C# K
    }
    0 v" Y6 o) f: k% J. a' J# `( t) g( @" x# f! p# T* r3 n
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)( Y; F$ \3 F4 _2 t
    {/ E. G+ R4 ~9 J: U
            memset((void*)partId, 0, sizeof(*partId));9 h  X2 v6 y" |# T6 X

    3 u9 ]: t. k# T+ T        partId->options = memPartDefaultOption;. g: x, d' ~( n2 Z0 N' |4 z
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    5 j! \% c: x2 i; m0 t, a0 ~* v( Z. V$ N0 l
            (* memPartSemInitRtn) (partId);5 `# u8 g/ B* m) a$ h( f
            # n0 \. Z9 b/ {5 ?7 W( V; [3 o' u, W
            dllInit(&partId->freeList);2 S! n, g* E  P: S0 W* G2 s1 ?* Y
            ) J/ G9 v6 W7 h) E# v
            objCoreInit(&partId->objCore, memPartClassId);5 D/ {: F& k3 b% h) l/ o. N: {3 G
            % n( J1 q! C4 o/ b
            memPartAddToPool(partId, pPool, poolSize);% ~& b5 o$ p7 V6 u$ l
    }
    # z: n; @" i/ B. T) h3 M6 z1 R! L' O
    STATUS memPartDestroy(PART_ID partId)  `9 @: w" L. P- [% a
    {% p, o5 [& s* t1 @$ f$ ?, I0 N
            return (ERROR);
    2 M. v  t0 g7 f4 p7 l3 \. T}
    . L- z4 a( w( R: P- {1 X* i$ \. i/ {5 R, q
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)2 _  t8 _# @8 p8 h$ ~
    {
      V  r# Q: L+ F/ B) q& l( H, g    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);0 k  c  j- o6 q! Y
    }
      H! b, R/ g* U, z
    6 w/ M8 J9 u' a7 B4 N& K' \7 O7 W: Q+ C+ Q
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)  q) m4 t, F0 Z+ O0 A
    {2 z( U0 u  ]( u/ ?% B0 o  k  q
            BLOCK_HDR* pHdrStart;
    / I. B4 T- Q% F) r+ p5 p        BLOCK_HDR* pHdrMid;
    0 S+ u3 H% C$ Q+ j- D: h( t        BLOCK_HDR* pHdrEnd;
    6 `6 b3 R3 Q- b; t  h( e        char* tmp;
    6 y$ P' N' z4 d- L        int reducePool;" x" E1 L+ d# \/ U0 Q: k, M

    ) @  b) g6 b; V6 v3 {3 Q2 y        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function *// n5 J+ o/ m) l5 ^( Q: ]9 _
            {& E$ E5 d. g) }9 i& X7 Q
                    return (ERROR);, Y( f! U% E, v9 ?) Z" h% p3 r- K
            }9 i8 i! [" U) H8 h1 }% l) |& f

    * H5 u3 n/ e( N0 w        tmp = (char*) MEM_ROUND_UP(pPool);0 `5 x7 F# I6 ^( a( |( ]$ g
            reducePool = tmp - pPool;7 Z5 }7 h  |; k# Q6 m7 [$ F1 b

    9 f; ^% [9 U# D2 l4 }3 z) M        /* adjust the lenght */, r, C: o/ d& b* |  K3 d
            if(poolSize >= reducePool)
      K2 ~8 w+ G) Q! t        {
    7 C- M& p9 i: R1 x3 V& p! T: ~                poolSize -= reducePool;
    ; u; T0 m, ?! O8 o; |: a        }$ [. x/ e2 b( ^* Q
            else
    * p  X- W: q, r$ n$ V        {, d0 e* R6 M( _0 V8 q9 S
                    poolSize = 0;8 R; [0 I  ?: |) M+ e
            }
    % X" J# U5 B  c8 M, L7 M+ j+ O        pPool = tmp;
    ! f* b- J8 A; Q6 u. j; R        1 m  E* Y5 a' k( Q/ n; l) A, F0 Y0 C/ t# N
            poolSize = MEM_ROUND_DOWN(poolSize);( B. ?3 b2 r1 b0 k2 r
            + Q6 Q4 h9 y' X3 I) O' n4 p
            /* at least one valid free block and three header blocks */, @% r8 D) D7 J
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    9 S; R9 l! U' @0 n        {* _! t4 E  X# i0 @4 F, n
                    return (ERROR);; s) ^: d' z! Y7 z. g, L$ E' K
            }
    % d, ^  C" L- M0 k: N: M
    - i' K3 z  y! d: n7 |* i- `        /* initialize three blocks */
    ( t! i  N) b+ R* F/ K        pHdrStart = (BLOCK_HDR*)pPool;
    6 `" F2 g9 l( z; i7 r, O2 H' R9 W        pHdrStart->prevHdr = NULL;
    0 F" Y% \7 ^2 a8 [        pHdrStart->free = FALSE;                /* never in use */9 W# [  v/ X. F" h7 j
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    * j/ |1 r: c& E% ?$ r
    ) l* g) r8 `) A7 T- G' _. x+ `        pHdrMid = NEXT_HDR(pHdrStart);. I9 d4 V4 o! l' v; {. c
            pHdrMid->prevHdr = pHdrStart;1 X, D# }# s! N' a9 q3 h& L
            pHdrMid->free = TRUE;                        /* the main block */
    - B6 A/ A7 ?3 q9 w7 n% n. o        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;0 c% x% `& C5 |0 d

    # x6 W# R. [$ p3 S7 p        pHdrEnd = NEXT_HDR(pHdrMid);
    1 A. D. c, }2 O$ T4 P+ D% i3 d: N        pHdrEnd->prevHdr = pHdrMid;+ s+ a, W; r; \3 V, ~
            pHdrEnd->free = FALSE;9 I7 J" _1 }- d, H. @
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    " ?1 ^( O2 o5 }( A4 c* j+ R$ X- D4 D2 K" f3 ]% Z- u  k$ s+ P4 s
            /* TODO take sem hear */0 L, y, C% h  L- ~% T: i9 D
            semTake(partId->semPartId, WAIT_FOREVER);
    " K' u4 h4 k1 [' p  U, F2 ~        : y% \  g) T& b/ [: s; _
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    # H3 k, p1 S8 V        partId->totalWords += (poolSize >> 1);
    % J6 R8 n6 f+ c9 y2 k( U: m4 Z* Q
    1 p7 |; a3 C) S        /* TODO give sem hear */
    ( u; f" i& S$ k0 K        semGive(partId->semPartId);4 \6 ^( M: [% O2 |* v

    " o, b' a0 g+ ~% T+ u
    % }# h! ?$ C: A; Y6 L! R2 A" P# }        return (OK);# z2 ]$ e* |  N& x4 v
    }! G3 c5 o3 }& @& p
    # k0 G- U6 l9 G% I- D- C; [
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    * |" [  R, ^5 Q- |: A& Z{: @' E- k6 Z1 C0 J3 G
            FAST unsigned nWords;
    ) B/ R9 X! W) i- q! O* }4 s        FAST unsigned nWordsExtra;) [' v& }5 c7 ?  s. G" {
            FAST DL_NODE* pNode;
    9 M8 G! S8 j4 E' R" P% r        FAST BLOCK_HDR* pHdr;5 R; i6 \3 o8 {7 r. O& Z( x7 X  ~
            BLOCK_HDR* pNewHdr;
    $ }6 C$ K/ _% D: ]+ x        BLOCK_HDR* origpHdr;
    . }" G  e* s" g+ {- a2 f8 ^6 Y; k' }; n! r0 j0 D
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    1 }5 V$ l+ o# c- K        {6 y# I4 ~4 K, \6 Q4 u. ^
                    return (NULL);- X# s. g; g4 r5 c
            }
    , R: ^! G5 F9 w3 M  H+ m0 Z) I# c: h5 i. m, Y* M- O' }$ @
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;9 C, `$ m3 m% R3 }+ _

    7 Y+ ]! B4 V" u* T& T0 S$ x        if((nWords<<1) < nBytes)7 W. U) j8 V! E- W$ Z, w. I# S
            {
    # {3 z% S9 X! J* c2 l4 D0 Q                /* TODO suspend the task */# d2 C1 Q) S6 T% N% n; Q
                    return (NULL);
    $ I* f! u. Q  s; @7 y        }6 H: Z+ s. R; B$ d" o/ c

    4 F4 }# D" j; _5 y% R# @2 h6 A/ ~. F        if(nWords < partId->minBlockWords)% |" w/ n1 O% h( ~$ a
            {7 Q( o' R+ @! b+ r# i3 J
                    nWords = partId->minBlockWords;
    * v7 N! t8 w7 [% E        }
    7 `# Q, h5 K! X# b/ L4 h# }6 @/ a1 a
            /* TODO task the semaphore hear */1 b& p9 _' z- ?
            semTake(partId->semPartId, WAIT_FOREVER);
    ! ]+ H1 N% n' e5 G9 M) X' T) E        pNode = DLL_FIRST(&partId->freeList);# g8 k5 ?7 r5 Q  s
            nWordsExtra = nWords + align/2; /* why? */
    / p  L9 Y, [1 r9 X9 b( m5 L$ n6 P
    % t1 F* v# e8 Z; K2 ^5 n        for(;;)
    5 \7 E+ z$ c: t5 j2 r        {
    4 T! G' j( M& a+ S                while(NULL != pNode). I$ L# V, @/ ~$ W  e* C: I
                    {- ?' V( z/ W4 y7 ^/ S
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    9 [$ }' ]: \. W                                ((NODE_TO_HDR(pNode)->nWords == nWords) && % N5 w$ s2 w: z2 W# s( X2 h
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    ) b2 ~; w/ o! W; P; H) S                        {
    ! L9 h6 S: p4 B4 W                                break;% h0 ]/ w. E* |: K+ ~1 l9 p
                            }
    / T9 B8 \% B; q% U; R4 B" K2 W* O8 |) b* b: h1 W9 d: Q( p
                            pNode = DLL_NEXT(pNode);
    * p5 W3 t* I9 j4 c3 T& U                }$ p) {3 P3 S' ^7 M9 K" j

    - Y# J/ f- g- H0 D/ p                if(NULL == pNode)' g: Y' M! V6 l. Y2 k1 w# t
                    {  ?  J. {8 @( G' j5 t& v
                            /*TODO give the semaphore */, a, W  o7 j7 h. c
                            semGive(partId->semPartId);* V! Q( o8 @( z6 Z! G" A" B7 a
                            return NULL;; \3 s: T- S( ~2 g  x% b+ ^+ c
                    }. j& r. A; y8 {& o" G. F6 a

    8 {4 D% a9 m- q. D1 n8 Z9 f                pHdr = NODE_TO_HDR(pNode);' a! g* j' n7 Y
                    origpHdr = pHdr;
    % g8 `0 @% B3 j0 L  W/ L* L
    # w2 ]9 j$ `- D: @, P! u                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);3 F" a' M6 ^4 {+ A8 N
                    if(NULL != pNewHdr)
      m# b) C" r3 B: q, n! C% g                {5 G. @' h" \8 D% k2 c
                            pHdr = pNewHdr;6 t2 h9 i% J( |! y# v! R
                            break;
    * I: D7 {6 o3 w+ j1 J9 `, c1 ~5 M                }
    + U" g& L( _2 O! a. B4 R! }$ d* [  o
    / ], P, w/ Z* {* L- R/ ^8 L; ?                pNode = DLL_NEXT(pNode);
    ( v7 W0 j2 ]1 G6 K. F- J        }
    / m- V$ w9 V( D2 h; {" k0 K) U" F& u9 F& X0 M/ C# {3 n
            pHdr->free = FALSE;
    2 T( j# f& x( ?        partId->allBlocksAlloc++;
    8 A! b* F2 i6 l% G- s. x; V        partId->allWordsAlloc += pHdr->nWords;
    * U6 D+ n" K4 D8 `% r        partId->curBlocksAlloc++;
    & u* y% \9 z- Q/ B! F        partId->curWordsAlloc += pHdr->nWords;4 X! A! H  |& [) p- x
    ) U! @9 z) Q* n9 @/ B" a, s' S
            /*TODO give the  semaphore hear */# X# ]: ~0 B$ N9 f- T6 J, I, q
            semGive(partId->semPartId);. {0 Y+ B% j. G& E
            return (HDR_TO_BLOCK(pHdr));7 E* o" a, g7 g6 [) I& j
           
    ' }. x& z1 N! Z/ a}1 ^/ _8 z" Z! n! D8 l9 F$ E

    " m0 [. ^" G1 \  _- {/ Kvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    / \* N1 F7 c1 @' c) w  w: Q: R{. b7 {" [: z7 N8 I8 u) z) ~
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    1 c# E6 j6 V4 d& s# S; h2 m" T}3 z5 Y) }" i" p* @4 l2 n# N
    ) p* r7 y/ Y4 R( E# M
    STATUS memPartFree(PART_ID partId, char* pBlock)
    ! y% T5 |& r$ w% d8 c{
    * c( o0 L( b2 {# n        FAST BLOCK_HDR *pHdr;& q8 G1 ~1 L2 R
        FAST unsigned   nWords;
    1 d0 l. s* \! e: ~+ q& a2 A/ r* l! [    FAST BLOCK_HDR *pNextHdr;
    * v+ m( j! z. R8 Y. E
    8 B- o( y, K9 m1 b        if(!IS_CLASS(partId, memPartClassId))0 p8 r4 L, o! c+ E0 F% a: s4 \# A; K
            {
    , P) U8 t3 w% o" B- ^' N                return (ERROR);
    3 k/ E5 {: S8 j        }, F5 {# D2 r1 f! a1 m3 |. [+ x

    5 a* ~  v2 E/ h2 J9 ^4 K' Z* m        if(NULL == pBlock)( _% i& b/ g7 q0 R) G
            {" p  }, N. q& ]  s9 b
                    return (OK);( ~4 n0 C! k( u; G6 D$ R
            }
    % F8 q, d  f7 B; p- D  |& D/ ^' ~( l% ?4 ?% D" i( @
            pHdr =  BLOCK_TO_HDR(pBlock);
    6 I+ K  `: e3 H" R; z; l9 B/ F
    $ d( x# G. |$ ^& l6 B3 L        semTake(partId->semPartId, WAIT_FOREVER);
    . q  E, {% H$ a/ ?2 B
    / E) I7 {7 E+ }4 Q8 w4 {        if((partId->options & MEM_BLOCK_CHECK)1 C5 L( Q# v9 ]% i  h( O' p
                    && !memPartBlockIsValid(partId, pHdr, FALSE))4 c7 c! i- w$ V: W8 N
            {: y. J% x1 h3 E2 A
                    semGive(partId->semPartId);0 r4 g5 l8 A3 o0 C; R, x- Y1 t/ R
                    return (ERROR);# v) T6 `. H4 H2 E
            }
    3 Q& c9 Z0 r2 x" e* B
    ; t( j1 @) X8 n& R+ z3 ^+ Q        nWords = pHdr->nWords;7 ]4 p- o5 Z' j4 s( u) P' d9 g4 h
            if(PREV_HDR(pHdr)->free)
    ) x; r3 `9 \' z; h        {/* the prev hdr is free and than coalesce with it */1 F% p! @; ~, x5 V. r( ~: W: x4 l
                    pHdr->free = FALSE;/ N' ]5 Y) d+ [
                    pHdr = PREV_HDR(pHdr);
    $ Z( q! L2 D7 Y, }/ J                pHdr->nWords += nWords;
    1 d- Q5 B, w/ N* C2 H        }7 c. a: M- u3 _/ o" k2 G2 R" t. m' ]5 Z
            else3 h! c( J: s& \6 D- G
            {
    3 V* ~$ l: c) Y0 c$ j6 t4 L                pHdr->free = TRUE;; k8 s$ ?* O+ F- \3 P# q% l, I
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));7 Q8 U2 V3 {7 k" u4 o- i" \/ g
            }8 D* `: X$ C! s* }( T0 A: {: |
    * y3 ~. J8 I) l* t; d" W: V4 r, |
            /* check to coalesce with the next */
    , D+ n: ~6 C2 P+ g0 j8 h1 Y* ?; _        pNextHdr = NEXT_HDR(pHdr);
    # d0 ?; z5 G+ \) q3 L) k        if(pNextHdr->free)
    " u& R# \5 E. w        {! z5 f+ N# s8 O# {% S
                    pHdr->nWords += pNextHdr->nWords;
    + `1 C1 t% @8 E8 `5 g8 S5 I$ Y' y                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));; M$ M$ z2 b) M+ W) O9 V: b9 H
            }
    , L- q0 r; W' |; t+ _! n
    - ]; ^4 M6 c- }2 `( y' O        /* cannot use pNextHdr->prevHdr=pHdr hear */- U9 _% |" r7 K
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    $ ]9 }" w4 l# d, s- d
    0 \" d$ a# s3 b) ^( P, B        partId->curBlocksAlloc--;
    & B& g& X2 J- G        partId->curWordsAlloc -= nWords;7 Z* K8 j0 A$ C2 u7 z( c
    * f. K7 G+ q  ^5 M7 |
            /* TODO give sem hear */
    ( l4 g3 c! Y4 F+ l' ~        semGive(partId->semPartId);
    : d" I2 |  {5 m) i* p       
    & x( N! F" ?0 h% D7 r        return (OK);% |) A% d* K5 {6 t$ T4 r+ F$ X
    }% {+ K9 v0 K. M) b
    8 q  V5 F, r5 D1 u9 D
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    + a% H: N& q  x& ?! E/ x8 C{
    9 _  t3 y% R' Z0 X        BOOL valid;
    ( D  M" @: W8 U6 G2 i: D7 z9 ~6 U" ?
            TASK_LOCK();, n) Q: _( p/ k: }) {/ r2 w9 ?
            semGive(partId->semPartId);2 @, A: h' {# T8 @3 L0 P
            2 b" G! ^& W( n
            valid = MEM_ALIGNED(pHdr)
    4 p' j9 z5 i* p, [3 [1 m3 K        && MEM_ALIGNED(pHdr->nWords*2)
    ; |. ]& w: U8 r1 z0 i; o        && (pHdr->nWords < partId->totalWords) ' |5 x7 @3 r$ m2 |
            && (pHdr->free == isFree)
    / P* z- w. _' r$ _        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    , c' `- R: m" l        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    , i" ^7 v2 _! s+ D! w/ T       
    " Z. G) d8 R1 `+ i- j6 K        semTake(partId->semPartId, WAIT_FOREVER);8 B8 O+ \' P% g' ^2 r5 B
            TASK_UNLOCK();
    ' E% ]5 t$ ~# y" o+ b: a- L% W. E
    / b6 ~7 m& g# z        return valid;
    ( F) G! [, c  K3 N% |8 d}
    3 \4 |5 b' L: e, K" M! U$ Q. C3 ]% J$ ~$ w3 K% x
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId% m0 u: N9 ~8 y8 V- t$ D5 S
            , FAST BLOCK_HDR* pHdr# o  j; q: ^! H; H6 K
            , FAST unsigned nWords
    . s7 y+ P) N5 [1 D) O8 N( \        , unsigned minWords
    9 G! F  b& D2 ~" w        , unsigned align)
    7 O, t3 b0 F% m/ }+ j! ~5 [{
    8 L) o9 C7 ^- W. U8 Z* z, ^: Z        FAST BLOCK_HDR *pNewHdr;
    1 _! x  S! `2 A7 l0 y9 N    FAST BLOCK_HDR *pNextHdr;' c6 B; q# q, D5 a6 l3 b
        FAST char *endOfBlock;8 h2 C7 `. L3 Z: E% i' U
        FAST char *pNewBlock;/ h# ^8 g8 o; Q- V9 \7 Z
        int blockSize;) {  y9 }' C/ ]- N
    % S- k7 S. b3 w7 _' ^# t2 }
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);. D! A* t4 X% I0 p: E) P
    , k9 d+ @  \+ _3 F
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    , i0 f" ]+ v* S# n4 `- a1 Z; z" ~& }; n5 m  C% R/ b; G
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));* M8 z, o2 `) e; m

    * L7 U5 O% U# l        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    & O$ |$ e9 K/ A4 P0 S/ Y- q8 s2 V4 I9 N: _/ n9 \$ a$ N% U
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;: D/ l3 I6 A9 c/ m  K6 s
    2 F7 i3 H, _$ l1 J5 E
            if(blockSize < minWords)
    1 W! U( j6 b4 \1 d' U        {
    ' |: ?5 K3 O6 b                if(pNewHdr == pHdr)
    0 r6 r# q" {; w. |1 H                {
    0 p6 _2 j- R: D2 W( F# n( m9 q6 \2 A1 k                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    * T) ?) |, M) |$ d+ c' Q                }
    8 J$ h( D4 y3 G; j4 u0 Q                else: x+ z. v) }! `7 ^4 Y9 V' I
                    {
    9 J8 O  Q/ W" q# {, ^7 R$ C- X8 X                        return NULL;0 z$ h! W) t/ i1 _0 O! b6 u
                    }% B; ^4 @1 _1 R+ `2 A
            }
    % V9 d. I/ {% i; r9 n        else
    . c" p9 r, I6 g8 z" A6 m        {        /* recaculate pHdr */7 _7 J% {4 m, }5 X$ z1 Z0 D
                    pNewHdr->prevHdr = pHdr;
    , l2 q; l) c3 m0 u1 K* @                pHdr->nWords = blockSize;  {' p0 q5 K/ |$ W; j, N
            }' z1 k* N; k0 B+ r- j/ x8 Z
    8 G6 n' _; z" S7 ?$ u* s! b+ ?) r9 N
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ( U% n2 r, Y% B* L! x        {* R& @6 m1 Y1 k8 b8 d+ ?
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    3 W5 h+ v3 L( c. N9 X3 t% l2 ~0 ?! L                pNewHdr->free = TRUE;
    : f  n* j) v* ^& z3 j4 O
    - V: o# j9 C3 j. p" e6 X/ ]+ M1 t                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;& A# Z8 ^( T0 ?6 |5 k9 ?% m
            }+ l2 W6 ~4 R* A4 r
            else
    4 l, d9 O: ?0 f/ h8 t* C        {/* space left is enough to be a fragment on the free list then */0 }* q+ t& |5 E. D* q
                    pNewHdr->nWords = nWords;- `: X, T- h4 w* z
                    pNewHdr->free = TRUE;
    * K; D2 x: Z# F! |  |& [
    4 Y& f& F' `0 J4 g                pNextHdr = NEXT_HDR(pNewHdr);
    ) p; ^# `% w$ q                /* words 包括BlockHdr */
    # b/ [; N& p0 }' Q3 j                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;, X  T! l" w8 Q. L( Q. Z
                    pNextHdr->prevHdr = pNewHdr;
    ( z0 j- [/ a2 _: S3 S; [" s* O# m                pNextHdr->free = TRUE;
    5 U% y$ q; K& Z& T8 y7 _+ x& u( ^; z9 l- b( k
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ! B8 F5 R) L! B" U5 K$ k  S2 U/ \0 h; E* ?! f( N2 v
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;7 c( m6 S' j1 f9 _7 U. F) o
            }! T$ l; `) |1 L7 S) B) h

    & `- u6 o+ v/ B$ w& k6 Y! l        return (pNewHdr);* T$ `0 V6 Y/ l' ^! T6 d' N
    }
    . ?) L( i# G9 X! R' C  h# ]7 d! a9 v$ _) N) {" `
    static void memPartSemInit(PART_ID partId)5 Q& f0 r7 J0 `# O
    {* X- E" O7 Z$ k
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    9 _& Z$ x  d6 x: H. d' U0 m1 D
            partId->semPartId = &semMemSysPartition;0 q( q) b8 G& \) g& y# O; X
    }2 s9 p9 u  b) R# u# c
    * W: C  v* F" d$ t( @! T
    void* malloc(unsigned bytes): S% [4 F1 x+ a
    {
    3 f  R# C, m. O( \% r        return memPartAlloc(memSysPartId, bytes);' N) W; g+ T, t4 j2 Z/ b
    }
    " }7 M( g9 K% Z- X) [; D& `( N5 W0 _9 ^- [$ \' q
    void free(void* p)$ y* w8 K) f$ }# h7 R; \. Q5 ?
    {
    4 \1 `3 l, @) M7 F4 y        memPartFree(memSysPartId, (char*)p);
    , r. I+ Y+ d, Y) ~: k: x}
    ( h8 G/ i; @2 ?3 j
    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-4-17 11:07 , Processed in 0.393469 second(s), 51 queries .

    回顶部