QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2832|回复: 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++下的版本,更方便调试。有需要请留言: B0 ]0 Q5 M7 E+ \5 k1 Y

    3 I8 c0 D  W3 K- l5 |0 G
    9 v  \7 H5 F9 c  N0 ]
    ; H# `$ x. Z, v7 s) z. @4 u *\file
    * j9 ?7 U4 ]4 J *\brief                % v( K* \- y) d; Q$ n1 p
    *\details       
    & S1 B" A' g8 Q0 g4 [! n+ Z *+ e1 |5 h- Y# h0 {7 i! y
    *\author        Janson/ z5 h. M7 E7 G0 x0 j" s6 |* ^
    *\version       
    & ^" L: E0 O* U, x  A- J9 F *\date                04Jan12- p( i9 U1 ^& |4 r: B! P# j
    *
    : |6 H% m- Z; U; L) b( F *\warning        ; Y: Q' X% s% o! F
    *
    - D9 z6 D2 E2 z. _% S. f, b) c *\history \arg        30Jan12, Janson, Create the file( S4 ]. W& T% U( \% ]/ L
    *        modify from VxWorks source. L/ m2 J8 G. j3 n% u; y% q
    *  Legal Declaration: it is for studying VxWorks only.( @" ^/ R9 ?2 `1 k1 ]
    */" m0 F- }% J# c# J) @+ A4 y
    #include "includes.h"
    % t5 _0 z' |/ g0 T' q1 X7 T. q2 }
    5 r, d. _! C9 f4 {  U2 m/* The memParLib.h file is hear:' W' N; r* O$ z; @
    https://code.google.com/p/vxwork ... rivate/memPartLib.h! J2 m$ z* ]( R. ]& z
    */
    " l! p0 V  `' h3 O2 T+ M: U% @; O. l0 q
    /* optional check for bad blocks */: z5 z( j* L/ v1 k
    / \' B6 w$ g& I  J5 _% t9 C/ f  P
    #define MEM_BLOCK_CHECK                        0x100 j* u' G% M* m( r2 B4 S

    $ _# N2 c! M6 @) R7 }6 E! M/* response to errors when allocating memory */1 R$ p2 x% q2 \' [
    ! V  T& I, {4 j& m6 U+ v
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    % ?+ M/ ?4 C0 q. N% g" U#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40; K- U, e" D6 U6 k! u5 u0 n
    " Z3 j' \4 n9 |6 `8 b" w. \9 F
    /* response to errors when freeing memory */& c4 ?/ |7 O; G( M, ]

    " O0 M* M/ I+ U6 m# q#define MEM_BLOCK_ERROR_LOG_FLAG        0x80& I. A. E6 r) }+ w# ~
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    7 r/ s) g0 E6 n
    5 Z, V+ W0 w) F$ }+ }! o3 R#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
      C5 J7 r/ }: ~8 q& P5 m#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    7 C+ t: P* }( }8 y: S9 \% i( c8 |8 f/ ]  m8 U
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    * Y6 A! k5 c% _% W" E#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \3 s9 D5 `; Z" O( q1 O$ x
                                                    sizeof(BLOCK_HDR)))) M* K7 N# b' [4 Y8 Y8 y; z
    & Z! E1 A7 {+ Q& B- A
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)! `; k1 Q, P0 |4 \( c1 X1 c' s3 c  C
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \1 t  \. |8 {1 L  e
                                                    OFFSET (FREE_BLOCK, node)))
    ! }1 h* B& w& y0 [8 d7 [5 G5 \6 v! Y5 G# r  B( X, u4 z) v! V9 _; x- S
    static BOOL memPartLibInstalled = FALSE;' m5 S7 F  p8 d, H* W' @

    ! }+ X8 H- L( E& I: qstatic OBJ_CLASS memPartClass;; S0 |1 h. s( l" [: r, F3 i( b. e7 b
    CLASS_ID memPartClassId = &memPartClass;3 F1 q0 X% E" Z

    9 P9 d+ Y8 d1 x: t2 M, y7 Nstatic PARTITION memSysPartition;
    ) d7 {$ h7 T. j$ T; n& QPART_ID memSysPartId = &memSysPartition;
    7 \5 Y+ H. d5 V0 m5 M" \U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    # |2 d1 L2 t6 O6 C8 o3 \$ J0 \- C- a' V8 G5 s
    static SEMAPHORE semMemSysPartition;# E2 K1 B( o6 {: n. i2 S

    * Y  x2 g. j3 x" }7 |static void memPartSemInit(PART_ID partId);3 F" `. c6 V" O3 i* k+ L

    , b9 y; m+ L, R' LFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    5 D' R7 R1 z/ e7 V8 @0 l% Z1 {  I% p5 u$ p
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    ) U' O2 ?  Y2 w- A5 P# X" S
    4 @5 q) r3 C4 Tstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);  a( ]- a: j3 d' `6 I7 C
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId! O3 Q0 i) H6 H7 }! T
            , FAST BLOCK_HDR* pHdr) U) L% d, e) d- ]7 m# X
            , FAST unsigned nWords
    / `! ?& @, \0 G. [& a        , unsigned minWords9 e& _9 _& E9 ]: F
            , unsigned align);
    # Q# c0 _* W+ g6 c4 x; a1 o+ A7 d; ^0 G4 d* H& u
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);' z9 L, Z$ c6 R* |# m

    / t+ G( i8 Z! Z" t  TSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    6 S5 |  A- s9 O1 A( V+ f* Q{
    9 `) ?2 o; O0 v$ _" M  q        if((!memPartLibInstalled) &&
    7 @% S6 i3 \) P' }                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    ) z* m" b7 d7 E1 J3 M                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    % w: E% |1 a9 k0 Z# `        {
    , S5 K9 j9 K, H- G6 ?                memPartInit(&memSysPartition, pPool, poolSize);8 D9 L+ K1 M8 |6 W
                    memPartLibInstalled = TRUE;( I# Z, v- j8 `2 o9 t) b7 B
            }* k+ E  G+ z  _9 e9 J
    * Z( {+ o: r6 ~
            return ((memPartLibInstalled)? OK : ERROR);
    8 ^0 x  ^. S! b2 `8 O}$ k$ r4 K: `( N& o  A$ `

    9 [; ?( n) Q  x0 b2 k* |# xPART_ID memPartCreate(char* pPool, unsigned poolSize)
    9 s" y& ^% T( S/ F{
    7 ^) x8 O. Y- b4 Y        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    7 O# ]  [4 S0 r6 }
    9 V; Y/ G& ~5 g2 c        if(NULL != pPart)
    $ z* O" E" K: G1 {4 d3 V        {. Z# I3 ^: j$ A
                    memPartInit(pPart, pPool, poolSize);; }- `8 d' Y0 b, c0 i3 s  p
            }' U" {, I7 j, t6 [

    . Q: q# S) a4 W2 L7 N- {        return pPart;
    & H5 b  L8 K1 {" T& x* _}
    ) A+ [, H# e" Z$ r3 j* N( d: _( y1 j- t6 C) B& F
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)' U5 h* N& i# Y; ^% I
    {
    $ w! u" f/ Y  Q, k6 M) P        memset((void*)partId, 0, sizeof(*partId));" p& N+ V  }; D3 ]! c8 O

    ) U! C. I' G3 v7 ~3 {1 y        partId->options = memPartDefaultOption;
    4 r3 q9 B7 i# D        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */& z8 v  `" ^9 |( `( S+ f
      b- N8 E( M* s+ a
            (* memPartSemInitRtn) (partId);2 C1 J5 j4 G! u0 f- Q9 e
           
    3 }" C% b  H' a: a: ]9 L" n        dllInit(&partId->freeList);; P. F* T$ [, `/ ?$ ~  D
           
    5 S2 m4 {+ @8 d$ ~, g8 @        objCoreInit(&partId->objCore, memPartClassId);5 P5 A) |1 g0 x, k0 k
            % S( b6 O  N( `0 w
            memPartAddToPool(partId, pPool, poolSize);
    4 L9 R4 m* z3 [  \}+ ^' H: m, q8 N9 U) i' e
    ! I  z1 \% A/ j5 G' I: F# E; Q
    STATUS memPartDestroy(PART_ID partId)
    - d4 |7 d" x# D$ Y0 d. }0 S{$ C* i1 p+ u5 G$ a
            return (ERROR);8 y3 i' J) |9 `
    }0 j* ^! K: d% `

    ! d7 v! }) N9 [! }3 Gvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    9 |/ w* M- L9 z7 I% E7 N{6 B2 z2 u. a# p7 S
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    + Z# ]& D' P' ]1 C. ?9 K& w}
    6 C5 t  ]% i9 N1 R5 A' |+ _, o; C6 B" }: ?; a$ l
    ' h& ~6 t1 g$ E
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    ' j0 W! `' E* u& Y1 p. k) [) W{+ W2 y; x* X, F  {
            BLOCK_HDR* pHdrStart;9 Q* C: I8 I- H$ L6 J$ `6 O
            BLOCK_HDR* pHdrMid;
    2 o. n5 s6 ]! ~        BLOCK_HDR* pHdrEnd;# s, a- r$ J/ M; J
            char* tmp;- F' W1 o" p: ^1 u$ p
            int reducePool;
    ( R$ }% [6 H1 x$ ]0 g
    9 q' A1 t; A8 h% |* `        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */# ?$ y, f! w: H1 Q
            {
    6 N# k  R9 q1 ]$ l- y: }                return (ERROR);( D3 r  a5 T8 M- _# v0 {( E, ?
            }
    3 J1 P- i" c; v: q, \
    1 Y, y" L, q6 b9 |& x9 \        tmp = (char*) MEM_ROUND_UP(pPool);
    & H1 O- S+ ^7 e6 _        reducePool = tmp - pPool;$ ]8 ~& ~9 A, t: \2 j$ n5 x
    % ?& F$ T( J0 G: O! B
            /* adjust the lenght */
    ) @; Z0 r9 v. o. I4 {$ {% J/ U        if(poolSize >= reducePool)
    7 q% J/ y- W( w7 N  {        {8 k, t1 K8 j) k" S; n4 k! {. R
                    poolSize -= reducePool;4 n2 {, v- j- ~$ ~' C
            }7 r' Y/ `; Z# |) c, @3 T) d# Y
            else% {) k: s. ]5 K" h: o
            {" H" @8 G& E% A% t- N
                    poolSize = 0;3 l; \6 I* [; j( v: j# q. z
            }) I! N4 [$ g  _( C7 |* c
            pPool = tmp;9 J! @1 Q- J0 Q' N4 C# B
            2 J$ q9 l' t! y! z5 K4 r
            poolSize = MEM_ROUND_DOWN(poolSize);
    $ A6 d1 ~0 {' I( I& z       
    2 |+ U) G1 l2 k' b* @( k        /* at least one valid free block and three header blocks */# F2 \! E- d, t+ x, V
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)0 p4 W3 K6 L7 i) F" a5 W2 e/ j, Z
            {& k2 L5 A: k3 Z
                    return (ERROR);- h" W: V/ Q1 |8 [$ E( G5 t8 I
            }
    * G* B1 O' J' ~. z- s5 h  M; j" r9 D5 u  A# o9 O" L
            /* initialize three blocks */# y4 U; w  }. w# s
            pHdrStart = (BLOCK_HDR*)pPool;/ T9 A; t: x8 q; E5 h: w
            pHdrStart->prevHdr = NULL;9 N3 a" b* ?6 I+ e; e/ l8 K
            pHdrStart->free = FALSE;                /* never in use */
    + D' v1 C6 ~, e9 e' ]! L        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;* ^; q# I4 X3 m" L8 |0 E. B

    * R) A( J" v) s( ~8 p        pHdrMid = NEXT_HDR(pHdrStart);
    # q# t8 a: i; i. j6 b        pHdrMid->prevHdr = pHdrStart;; C; ~# Q$ W* O/ n0 |: ^
            pHdrMid->free = TRUE;                        /* the main block */
    - i1 G! I) y6 p) S! c        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;. o$ L! X: o* ?, t3 _5 M

    . f' D1 F+ e, f  N" [3 o        pHdrEnd = NEXT_HDR(pHdrMid);9 }8 B, w6 L5 m
            pHdrEnd->prevHdr = pHdrMid;. [5 S7 a5 ^1 ^& f1 A6 n" ^' ?$ P# c
            pHdrEnd->free = FALSE;. U* a0 _0 l( ~, A" U
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;0 n* E3 F  u0 W9 }5 k! P
    7 s7 L8 R( z+ S; x1 v( b
            /* TODO take sem hear */2 e) q5 \2 p( o. ^& Y/ @1 M
            semTake(partId->semPartId, WAIT_FOREVER);
    8 e& H; l4 J% C1 }' U        1 A; T4 ^- M5 \+ e
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));" V/ Q( U8 q1 R* a6 K: |
            partId->totalWords += (poolSize >> 1);
    # F2 _. `) o2 c; A  `& ^7 F, Z6 j( Q% z
            /* TODO give sem hear */
      B/ o% T: b; ~0 g# w  f  Q: b- }: L        semGive(partId->semPartId);
    ) V; [& p; y+ r
    5 X( v- x( D6 J9 E8 Q- M
    - m  g* z7 `' a/ ?' W. ?1 @$ D        return (OK);% Q% B& a' W- x3 g, f  l
    }
    / g6 g- f# ]* C. I% u, [
    2 s+ z7 a- A6 {3 a+ K% S5 Avoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)* X* {0 o. n, m. E
    {
    0 D! A( s" R; Z5 L3 n9 j        FAST unsigned nWords;
    3 S7 B. |$ j% U3 S! c* o( V        FAST unsigned nWordsExtra;/ X4 q) L$ p9 _& i* V( x3 J9 a  U0 P9 I
            FAST DL_NODE* pNode;' }: O: O/ r: h4 }4 k2 A; k
            FAST BLOCK_HDR* pHdr;" ^  T: O0 p5 f& ~/ g
            BLOCK_HDR* pNewHdr;# `+ K$ m# L5 O; O; x6 A
            BLOCK_HDR* origpHdr;
    6 \7 M  N. F% p" w( B
    ; p- _6 p9 H/ m7 A2 d1 G        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    6 V  e; i9 Q7 O; Y7 t; o/ v        {& Y3 z5 s5 p) p; s& m+ m; s9 O
                    return (NULL);' |3 x/ U; Q% ^- w9 l. ^- A" Z0 w( T
            }
    ( v9 Z" r9 `9 `, ?3 a
    " k+ [+ r1 k4 q! {. `* P2 m        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! q! O6 s+ e( k+ h0 J

    , x8 U9 ?" Z: i; {. |2 F+ [, {        if((nWords<<1) < nBytes)" t; m" o  I5 k8 d8 w
            {5 I$ r! T# L  u, d9 ^
                    /* TODO suspend the task */5 @# e" W. d) t. ]. @, K) b0 V: p
                    return (NULL);, o" c( `* `- s
            }
    % x" ?5 J3 X: j' H1 w8 K8 Z
    , \2 |' ^+ J  B* H- S# x, Q        if(nWords < partId->minBlockWords)
    * J' ]5 p! O% e* r: V8 k* [6 z) _        {
      @6 x7 k/ ?+ f8 y2 q5 B                nWords = partId->minBlockWords;
    8 b) t: j  e; j$ \        }# Y2 S# O7 ?9 V' H+ i& ^2 l, ]
    2 v& H8 F* }- o( Q, E
            /* TODO task the semaphore hear */
    " X' Y! O; p# R% H- W( o        semTake(partId->semPartId, WAIT_FOREVER);
    0 b1 Q/ ^) m" U        pNode = DLL_FIRST(&partId->freeList);4 L8 c* S: g% i4 n+ U. r; m& w
            nWordsExtra = nWords + align/2; /* why? */7 [/ x: o9 Y0 O3 P) @/ M" `& G" W* q
    / \' t7 C5 C% ?5 v, L4 X. d
            for(;;)/ C$ {1 d- @. [7 _6 e
            {' i/ B& l' h9 S/ L  X
                    while(NULL != pNode)5 B0 {9 G; l0 A% A; \1 [' _
                    {
    " u  {) v& v& d+ Y                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    ) y$ G7 V; Y) o7 R2 I                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 5 A" n  c! ~" I+ F0 R
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    - S8 i0 W2 C% T  N, g* r: C                        {6 Z5 B) b$ e1 c( \4 L
                                    break;
    : y3 M$ ~+ I/ C: D                        }# r$ i6 m+ P) ^4 r. w/ ?
    6 V% }6 h' P3 U( @5 C+ z
                            pNode = DLL_NEXT(pNode);
    " r$ u8 h  Q1 b/ e; I& [2 r3 q                }
    . T# \  {0 o# W0 _6 U. t+ h; A' j# d0 U( m; E1 g" H
                    if(NULL == pNode)  u" N7 d6 H# ]- [7 R/ C
                    {
    8 D  Y7 N$ a8 T+ W                        /*TODO give the semaphore */: E, g6 W  U7 b0 E' @
                            semGive(partId->semPartId);
    ! d. g" R. h  R0 E% I2 F                        return NULL;, s5 Y2 s' s- o# t* Z
                    }! `4 `% S4 c0 K! H$ |

    # o9 Q: v# C( Z) F/ u                pHdr = NODE_TO_HDR(pNode);8 W) _2 R) L" V: z5 w
                    origpHdr = pHdr;/ i! e( w" a2 c" R2 \& d
    $ J1 p7 K. Y: E# o* V
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);' ~& {+ P: d# x
                    if(NULL != pNewHdr)9 W5 R- P( }2 |" t0 o- g* v3 A4 [6 x
                    {0 N1 ^7 [6 K3 X: d, Y1 k/ X$ H( C
                            pHdr = pNewHdr;2 G6 B4 x( o9 t8 a+ Y- C3 t, f
                            break;
    $ O0 S" d! @& B" e                }& {8 j1 n; u% u6 a. `( ]1 R

    9 E' e- q% u/ w- B: B- x! a                pNode = DLL_NEXT(pNode);
    9 v, B* A" ~) r8 t9 x        }+ I! l' I/ g' u
    5 z/ j1 v% R4 M+ Y. k: }
            pHdr->free = FALSE;0 n5 ~' n) g$ o+ O4 C% X
            partId->allBlocksAlloc++;
    . ]) `* y% e1 o% O: ~$ l# o        partId->allWordsAlloc += pHdr->nWords;  Y' u- C" W" ?7 x
            partId->curBlocksAlloc++;
    & Y& l) U) R  f2 b2 n2 i6 N        partId->curWordsAlloc += pHdr->nWords;3 y4 w, S8 N! M3 L& {

    * ~# i* S5 o' y9 I" Q; |        /*TODO give the  semaphore hear */( A: S4 a# K6 a# f
            semGive(partId->semPartId);% i  m& g  @7 `0 a1 p  i) U: S7 v
            return (HDR_TO_BLOCK(pHdr));% A7 ^- d2 j% A& r3 l
           
    2 ?  ], D& ?0 ]& W  s$ c* v2 S7 P" Y}0 [8 l$ g0 Z( {* I: x3 T

    9 z$ f9 |* O9 z" \9 Uvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)- K, \5 q, W4 Q: }5 N: ^
    {  U4 C5 I1 \! i
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    , u: x  b" f3 M}
    6 y8 h) H- H4 [9 b& j. t2 p: e$ g! J. c' Z  J8 J( d. k, T* F
    STATUS memPartFree(PART_ID partId, char* pBlock)- C/ C0 c# D/ l8 o( }6 K8 J% u" R
    {
    . d' a9 d2 P: o  j" ^4 i        FAST BLOCK_HDR *pHdr;
    * b, y- \  l0 U! ?* f. v    FAST unsigned   nWords;+ ?" H4 h2 M, u1 i
        FAST BLOCK_HDR *pNextHdr;
    & a+ d. @. B8 N+ y; W' o4 `8 d  h8 J! E. I: s( o% Z
            if(!IS_CLASS(partId, memPartClassId))9 d0 |: c0 l" ~1 n
            {! ^# f( D7 l$ [4 V- H& Z) P
                    return (ERROR);
    5 @0 h0 M( s4 y% h4 x& l- n* L        }. l# S. O4 i6 H
    ' d$ [. r! D, Z+ Y2 h$ C3 @( ?
            if(NULL == pBlock)/ v  L" `7 ^% L
            {1 Q( u4 I( G" J
                    return (OK);
    8 p+ C$ d5 v3 b5 H& z9 `; G# J        }
    7 x$ K' v& \! |* d% Q. }; n- b: g# {: N7 ]0 k8 k
            pHdr =  BLOCK_TO_HDR(pBlock);
    " @3 V# a( c+ A, D* c, z$ j$ ]" j0 t# T+ [
            semTake(partId->semPartId, WAIT_FOREVER);
    ' R2 u2 R9 b& r: _$ f  g* U
    , g* R# r! J9 N% i. r4 ~( l& r4 ^        if((partId->options & MEM_BLOCK_CHECK)2 {* T1 f$ }; O* i$ P* W0 D1 ^: P  M
                    && !memPartBlockIsValid(partId, pHdr, FALSE))* ~+ ]7 ?/ D% b% D) @- V
            {: V& g' w! |2 S! Z( m$ Z: o
                    semGive(partId->semPartId);
    - f  t$ e) \7 _: R                return (ERROR);- [$ G- x4 I9 c/ T+ }
            }  e# U' p! L2 R2 g! l

    4 o4 e  q6 `1 W$ G2 F2 Z- e# ^        nWords = pHdr->nWords;* r/ L1 x5 P) O2 E. N! G( S) @5 O/ ^
            if(PREV_HDR(pHdr)->free)
    - d- }8 r6 t5 V9 a% R) [* {) F) a        {/* the prev hdr is free and than coalesce with it */, q7 z0 l& r* D0 |7 S
                    pHdr->free = FALSE;) l' z* [4 I! P2 [% T' Z8 r
                    pHdr = PREV_HDR(pHdr);
    + A* `( y, _( h4 P# _# V1 a                pHdr->nWords += nWords;
      d  S, O- i" q3 c  l' E+ ^        }
    $ A0 t2 o# i. Z1 X( b  R        else6 q; L3 O& y0 `3 G
            {
      \$ D# h- ?) ]) v8 I* k2 V: m, [                pHdr->free = TRUE;
    . ^+ T2 c3 g) L) f                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));  q5 n! y8 _' T5 w) V6 s* v
            }
    ( P7 y8 u" G4 `' m" [0 y0 B/ c: D$ p! d5 }& [% ~
            /* check to coalesce with the next */$ L4 Q& @- ?/ ~) U$ s/ W
            pNextHdr = NEXT_HDR(pHdr);
    ) R: p! B9 \$ n: A        if(pNextHdr->free)
    $ Q; Z2 q7 f: e$ K        {1 E) \8 o1 ]' O' y$ {
                    pHdr->nWords += pNextHdr->nWords;
    ' q0 J* p% \, y  j, d# K                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    . |' q+ A: e6 n5 _        }# E( J: ~  r) E. t( a; N0 d

    4 F* X. T8 a% Z7 D" {3 d        /* cannot use pNextHdr->prevHdr=pHdr hear */
    . r% U0 E2 R7 k& L* _2 O2 ^5 {        NEXT_HDR(pHdr)->prevHdr = pHdr;
    6 P/ q8 P8 N2 I1 a1 `4 Z$ t% {3 z0 Z% T
            partId->curBlocksAlloc--;! W. S" k3 R/ u' u; r% }+ O8 ~
            partId->curWordsAlloc -= nWords;
    8 v/ T8 Y4 B2 {. S/ \6 E5 L, L* ~9 v! r& C
            /* TODO give sem hear */
    9 Y; N$ f) Q9 B  d; [" m        semGive(partId->semPartId);
    $ g$ n/ ?0 J9 F! v4 z        2 M/ J/ v/ w3 y
            return (OK);
    7 Z. R7 D9 o1 S2 A, s}9 `, R, K0 n: t: j
    & E' R" I! l) B. k
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)  w, }, ]& U- C* Y7 ^3 p" e+ _0 E
    {$ H. Z$ a2 q! z  A4 F
            BOOL valid;6 _; E' a" N- |4 R% U" @! [

    . k5 F" T$ y  u: Q        TASK_LOCK();7 M' l/ T( A2 I) H2 b9 g7 S: P0 B
            semGive(partId->semPartId);
    4 K: o) u1 H8 F" W3 b/ p6 q        6 M8 e6 \4 i3 t, _
            valid = MEM_ALIGNED(pHdr)
    9 s$ t7 }: n# @        && MEM_ALIGNED(pHdr->nWords*2): }; f% B6 w# \4 [/ z
            && (pHdr->nWords < partId->totalWords)
    : d3 W" w8 j/ r' |" E  ]$ [        && (pHdr->free == isFree)
    6 Y; C6 i& [' e        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))1 }% q. U; I) N. i
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    0 d3 Y! }+ k( r       
      p  d& G& l/ X  Y8 N0 e8 Y& i        semTake(partId->semPartId, WAIT_FOREVER);& h) `/ ]9 _9 n% C) b2 Q. p
            TASK_UNLOCK();0 _5 e9 _+ Q( _7 Z7 L
    : G4 j% |* L7 R- d
            return valid;
    ) a6 D( z' F! `6 g# `% l}% ^" ]: i5 _- p, t3 f" h  ~

    + M# w8 g8 Q6 y- Mstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId0 s8 v& v/ S% \5 l6 S
            , FAST BLOCK_HDR* pHdr
    ' j" |* M4 v4 [  C& g0 X        , FAST unsigned nWords* K, `! o% C+ k- d
            , unsigned minWords
    , C& ~4 R, x% O( r9 R8 H4 k+ ~0 B        , unsigned align)
    ! K! g# [0 p% x- Z{
    7 p( c; C* {5 ~8 U( a& j, Z3 }        FAST BLOCK_HDR *pNewHdr;
    % `/ ~! d0 U1 r) V( t6 l7 k" S. t1 [- G    FAST BLOCK_HDR *pNextHdr;7 [- F& |( ^# C& K
        FAST char *endOfBlock;
    5 ]! X' S& |% l% T2 e0 k    FAST char *pNewBlock;
    8 C5 `! |4 U4 q$ ?# x    int blockSize;
    / B. L/ J) u; E0 f7 v: R/ ?7 L( A# [& U% z2 \; _
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    : z! ~4 w5 r; @  V: X
    % ]" V  h4 q/ ]& L9 m        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));0 Q& _1 x% F/ S" d/ w+ h) T
    % N) s6 t- t; X& L- J2 N4 a
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    3 k* n2 |+ a& j+ r8 h
    9 Y) v/ y) x1 ~; B: k: ^        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    9 r7 @0 G" s) _3 `* M1 x
    : u. b+ u' ~( B8 b( X        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    ; x2 G) N4 H+ w6 H8 M4 {' @3 m2 T( ?
            if(blockSize < minWords)
    $ Y1 _% G) a9 n. ?. w2 G        {
    8 E' o$ v7 R$ W$ F$ N* a                if(pNewHdr == pHdr)/ |7 v. z: l1 n# ^% ~
                    {
    # m, @9 p- U- d1 G/ G. }' ?                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));+ O" V9 n) j/ W* g2 k9 s) X  f
                    }
    + A' r  T' w4 S                else
    * ^$ u& j' T: f                {6 g. u; a) p5 ?& u8 V
                            return NULL;; e  p# a' J- \7 h* H: Y! C
                    }! @% R$ ~& S1 G% c
            }$ z" R3 S/ |, J; J% Y
            else
    ) w' o1 N" F, h        {        /* recaculate pHdr */3 b" n0 l/ y! T
                    pNewHdr->prevHdr = pHdr;: {* @6 r6 l7 L9 C
                    pHdr->nWords = blockSize;
    1 h" x6 p2 j. g9 U! r7 k% S        }) [8 [" d$ a/ ~3 V

    , v7 O( }) `% d0 |        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))8 F, A/ O" `. d. u- P" S
            {
    - O; H  {: r- g7 }, T2 N                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;" u) R2 M# k+ M
                    pNewHdr->free = TRUE;4 v: K" H  |1 k. P

      V  D- W; h2 E  c                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    ! x' e  x1 l4 T. U4 m' Q        }
    - T: ~% C. Q- [, Y) k- h* M% }        else
    ) Q7 n0 x, @! \7 ^* x        {/* space left is enough to be a fragment on the free list then */3 o1 [0 W7 y* r; _7 t) \9 [, L
                    pNewHdr->nWords = nWords;
    " j. b/ q& v) e; Q1 K/ C' u0 _                pNewHdr->free = TRUE;, ^1 z* s; S2 W- m& ^: b7 T1 D

      c! X; _) ~0 u  Z' r3 s% W, I8 S; _/ V                pNextHdr = NEXT_HDR(pNewHdr);" n+ O  J" k- z6 z) U/ E
                    /* words 包括BlockHdr */
    5 o9 f- L/ a" N8 a( \" t                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;& b6 s% _5 ]4 E
                    pNextHdr->prevHdr = pNewHdr;+ z$ R  c+ ^/ Q) ?
                    pNextHdr->free = TRUE;
    3 a1 O* h1 [3 N% @& G: z
    & R0 t8 \# h# l5 y                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    3 M6 S! s( d$ l! s* B# q& f( z/ [' V2 A$ M$ g
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;' N) B" x& u; q5 S# _3 D, j8 Z8 @9 ^
            }
    ; U5 Y( x6 m  h* m8 g( V0 N6 ]) e  `8 }! q4 P6 F& z
            return (pNewHdr);
    ; X) B$ A& }/ V9 n, o; F4 y; O; m}
    . s2 y" P0 [8 c% Y& ~9 i
    3 i. M* Q! c8 Q; Ostatic void memPartSemInit(PART_ID partId)
    * W8 J9 x( x0 v! [{
    ; W  [( |4 S- `  z5 F1 i7 K        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);  C+ P2 R, [; h' c- f

      D  Q7 c  K) ^9 y        partId->semPartId = &semMemSysPartition;
    ) v5 o" ~* B9 m" u}0 i$ V$ d; M. ]

    ( A2 \0 ~$ c; ^) H3 J8 mvoid* malloc(unsigned bytes)9 V( N- Z  S! D% x4 T9 y' `& z8 d
    {
    ; n3 U& g5 Y0 a6 c: H+ G0 R        return memPartAlloc(memSysPartId, bytes);
    2 y- O# s3 i1 A+ f% b3 u- O- [}( F* h6 _! O$ [; R9 g
    # l4 `0 U" r' O6 |5 S# M
    void free(void* p)
    - D" e9 Y% ~- T9 p3 \* Z  C$ i- _% F{
    8 y. x2 q  W7 d6 S7 q5 R# L        memPartFree(memSysPartId, (char*)p);
    1 T, U% k2 U/ M5 n) C}
    4 }7 K4 u5 T* P3 J) v
    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-15 00:15 , Processed in 0.394394 second(s), 51 queries .

    回顶部