QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2858|回复: 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++下的版本,更方便调试。有需要请留言# M% f. d& u+ y0 g0 \8 ~4 G
    ! D% t' z$ O% x& f, R2 b) ]: b

      g2 S0 O5 }: @; S) J/ `! B2 |& l- p& A& |  T
    *\file. I* y2 q! R$ A+ `9 w
    *\brief                ; M3 Z1 k% Q; m
    *\details       
    ) j9 h; T4 f& q$ L& V: R: F& v9 [ */ M! Y4 `- Q$ d# n
    *\author        Janson" n- E% ]+ V/ u& s1 B
    *\version        / L4 f1 w$ K4 s. J3 i
    *\date                04Jan12* O9 f6 h5 z/ e! b3 F  B
    *
    % _+ U: Q) o$ O# F  R9 O: X *\warning       
    ' y  z6 p2 a% O& g$ }) x *
    9 V1 O8 [8 b) @( b+ Q* | *\history \arg        30Jan12, Janson, Create the file
    , E: G4 q  g5 \ *        modify from VxWorks source
    ' v+ e1 {9 [; [" Z! T+ D *  Legal Declaration: it is for studying VxWorks only.
    ! m9 p5 A3 z( D& g, C( o# K. g */+ I/ x  N" j4 |/ k5 O
    #include "includes.h"
      N- P  ]. n/ n
    8 N. Z+ q7 u8 P! E/* The memParLib.h file is hear:
    ; `/ f# H6 n, rhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
    0 p1 H# q4 Q  Q& v*/, x! f' g$ P8 @, _) G8 @

    4 h8 I9 u' n0 j- }/* optional check for bad blocks *// j+ a! ^4 E& c  D6 ~
      Y( L$ B, k+ H* X
    #define MEM_BLOCK_CHECK                        0x10
    $ A$ F3 O, }( @/ b0 E0 B5 z8 L$ j( A/ G  H2 D
    /* response to errors when allocating memory */; B5 L0 _4 X' a
    # A# _: `; q* O- [! Z
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    " [1 q# w1 }, x9 v, u5 M6 H#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    % v7 A* G5 j6 S$ p8 C$ w+ J) ]" `
    /* response to errors when freeing memory */. N  N' y+ B4 }9 P$ i5 K) S( ~
      ^/ p$ `6 c! w. I: @7 ]
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80" A2 G, j. C. R
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    ( g) r  s- L* g6 z  j
    2 B# ~* o3 H# V7 c" D. y#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    6 G3 A  C/ b* `  j- [#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)' Y9 \  x  @9 U/ i) n9 ]

    ! W/ _3 z( G8 l: r. E# S#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    ; P$ _. K7 h+ T/ _#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    9 m1 ]* A& B) D2 _) N                                                sizeof(BLOCK_HDR)))% B; v9 Z/ D4 z& t
    : R$ {0 [% ?1 E! Q. H, w
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)& m# V6 X) ?/ @! E4 v4 C
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    , W, c8 W5 J: d7 X                                                OFFSET (FREE_BLOCK, node)))
    2 d7 u( N, z# q. @3 Z" e* Q( B5 j$ c. N+ b6 N' C
    static BOOL memPartLibInstalled = FALSE;
    2 m$ ]* K# U; E' o. e
    6 ]/ w; r/ p; m/ \9 H% ^( g7 Gstatic OBJ_CLASS memPartClass;) H5 D: \$ V% ^# T' w3 H
    CLASS_ID memPartClassId = &memPartClass;+ |; A9 Z% S1 t4 h1 Q6 a; o# e9 w0 z
    # U0 B+ o" g3 o/ Q# R/ x' j9 m
    static PARTITION memSysPartition;! \' R" W* p$ o0 Z
    PART_ID memSysPartId = &memSysPartition;
    ( Q$ z% m. R$ _$ V) t. WU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;1 l; ~0 J, m8 G( r

    ( F4 }9 B& O1 ^; M# K" cstatic SEMAPHORE semMemSysPartition;
    + k5 A( G- q. a  r1 z1 |# g+ l
    3 [  c8 Z5 I- pstatic void memPartSemInit(PART_ID partId);
    , g: H8 p5 d' H9 u9 {, {# M0 k, K- J4 y( V5 B9 P; O
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    $ S0 D' ^# `* {( m% Q
    # }- U/ ?+ Q4 |: A$ [4 s# yunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;  g" V- I1 c2 t$ Y; L/ n' b

      @4 d' i- w" H6 \# U( b" V& Bstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);; K- U' X; R8 h5 }( }
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    , I6 V4 q& b! q2 A6 @& N2 b        , FAST BLOCK_HDR* pHdr
    2 |9 e) i, I; c        , FAST unsigned nWords
    : ^1 Q( y/ w4 U        , unsigned minWords
    ; P' Z, d, V2 |, X% k        , unsigned align);5 \4 h' J7 x* {( M( m
    3 Q: [. s0 h' u8 _! G% N3 v! F
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    , ?/ R0 J) t5 E2 @/ o) t. B
    , K6 R" E: U5 [STATUS memPartLibInit(char* pPool, unsigned poolSize)% D* O; @" p3 ]/ A! J- _# D) |
    {( a# Q3 t% f% Q9 V5 m
            if((!memPartLibInstalled) && ' S( f! j0 z7 B7 W+ K- {9 h
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore): w, U+ Q2 D* J8 @: M6 E
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    5 s# E) j! M7 e        {
    ) n4 [4 O- `) ]                memPartInit(&memSysPartition, pPool, poolSize);- B% l, ^) E+ E& \; q- |
                    memPartLibInstalled = TRUE;
    2 M# ^0 F/ ~/ Z" m' [5 @/ H        }
    ) B; J# h+ A; `* d! K1 Y0 u- E2 |1 C
    - z! b9 T  y( I$ b% Q: m9 s0 X! R        return ((memPartLibInstalled)? OK : ERROR);/ n6 M; V9 [9 d2 ?
    }
    2 i: f- T" q% I: J
    6 p! G; C/ L" q- sPART_ID memPartCreate(char* pPool, unsigned poolSize)
    , f2 X% i  N: ]{. N4 J& [) z7 s5 g0 _
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    , ]4 q5 m5 v( b/ K) f. H- @
    - }( _1 y( M% W: C  T8 _        if(NULL != pPart)
    - n0 Y2 [0 M/ A) Q; o% S' _8 B        {* }' l6 \) S6 ~
                    memPartInit(pPart, pPool, poolSize);. w, ?, C& `7 @7 f
            }7 B9 M- G' U+ }% c) B& t. h9 f
    2 c& I3 K* Q1 m3 r% G; Q
            return pPart;
    ) Z5 }1 E2 }* R4 E; Q4 ?}
    ! s: P1 ?# f% d  l
    / [9 q! U/ s5 Y% h' Q# k. Xvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)7 P3 w9 @. ]1 |+ S% O7 s$ k
    {4 V$ v; l8 T5 m" h4 l% ?
            memset((void*)partId, 0, sizeof(*partId));
    6 d" K4 J  Y! d# l. G
    / Z( y' V6 O6 B4 m        partId->options = memPartDefaultOption;
    : ~. U9 V) L; V! C3 c& }$ B! \        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    8 o+ R5 j4 R  C, K3 M  O
    2 S; d4 [) t5 u) r        (* memPartSemInitRtn) (partId);
    3 u* [$ f. @4 Y        / y. Q! t" m/ i# t2 c
            dllInit(&partId->freeList);
    7 J7 k& Y3 n, }2 N! z- h& b. d       
    4 q. f( U+ F# w% ~3 y. z' U% ^        objCoreInit(&partId->objCore, memPartClassId);) o7 ^3 Z: e) Q3 n  Y  `
           
    ( ]/ Y9 d" N' o7 H% I        memPartAddToPool(partId, pPool, poolSize);
    * H* x; J8 A2 ~0 L. g6 V7 w" n+ {' i}1 |2 h* r: I8 P+ B

    ) t0 Z. h/ I4 f5 S+ bSTATUS memPartDestroy(PART_ID partId)) U, |0 `% G. }
    {: u8 t2 A6 _* m! M  z7 ~
            return (ERROR);. @" i7 N& p, r" r
    }/ z6 O2 W7 `; j+ `; C- `2 U

    $ Z+ t) [4 a8 A: k- [" tvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    : f+ U. ^$ i; c" h' T{
    2 C7 A* u  s# U. J6 t) n( `$ z    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);  c* [: j' {- M% h- U" b2 u
    }: a% r2 k/ y9 p% X# J

    * e  C1 Z# k1 s' E6 V: M6 w" V
    * l+ C' p3 `) tstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)  ~+ |& U! ^# w- P
    {
    " e) b' e+ Z- J        BLOCK_HDR* pHdrStart;
    " H# P# B, q2 r- b4 n        BLOCK_HDR* pHdrMid;; N5 B3 B  s- U! Q/ b  p% k; O
            BLOCK_HDR* pHdrEnd;
    : {, N4 S" `6 w- M2 e' J9 R        char* tmp;
    / \2 X' l, ^# h( m# {5 a        int reducePool;
    1 M# k/ m2 K6 A9 m: d- v0 J" S- Z: x
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ' V0 s1 ?  `: I! b+ o& u) g        {& }3 I9 H0 X1 q% z+ z% f: W
                    return (ERROR);
    . k, D* U. ]9 b0 `& [* s) l1 W: W        }, c/ J( {9 u) X& B( e& Z9 v9 ^

    - C) A/ X9 Z6 ?5 \& j( G, Z% I        tmp = (char*) MEM_ROUND_UP(pPool);7 W# X% S; w0 `2 l2 j
            reducePool = tmp - pPool;
    - H1 N) x$ P) v: V
    , w8 L8 }9 n8 }8 z        /* adjust the lenght */
    / k# r0 p3 ]  e' e6 }1 T5 v        if(poolSize >= reducePool)+ Z; L: y# }/ b  O5 M" p; l6 V$ m
            {6 k4 a& l6 y5 v9 _
                    poolSize -= reducePool;/ B$ O" ^9 Z* r" K
            }
    4 ]7 v/ T7 L; v- V+ g+ v        else
    " T1 U* x/ D( J4 n8 o        {
    5 Z9 ~7 a; Z) M* {: u' C2 s' S* P                poolSize = 0;
    $ t  ]" Z% e' ^& _        }
    ; R. z% _" x6 m1 M1 _        pPool = tmp;, u4 m* q% p& t( y1 K" p, ^0 ]
            3 I% h  c$ L1 V# k0 m8 Q
            poolSize = MEM_ROUND_DOWN(poolSize);
    9 B4 q  _) d5 ~; v9 r( _        $ w) s! H& w. z. f& o3 ~  X+ v" z
            /* at least one valid free block and three header blocks */, m, m. x) r  W: M7 `. \
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)5 @1 i- U2 l5 @
            {7 P0 S( |  T  {+ ^1 h
                    return (ERROR);2 m- z, y, k4 F
            }. {- w+ c7 {1 l8 M: H# u: Z2 m
    & b' B1 y# G4 H# a0 B1 q; z
            /* initialize three blocks */
    7 u, d3 J+ ?& _! [" B0 w        pHdrStart = (BLOCK_HDR*)pPool;
    $ D4 I3 x1 y; {* g' j6 R        pHdrStart->prevHdr = NULL;
    2 c1 g" o. g4 a        pHdrStart->free = FALSE;                /* never in use */4 W1 I7 |9 r  e
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;, }8 ~5 @% Z& P! g
    3 U: N& }% |* Q' S/ W/ W( I* ?
            pHdrMid = NEXT_HDR(pHdrStart);  ]% R# O: z% G4 G' f; G9 `
            pHdrMid->prevHdr = pHdrStart;
    3 q$ J! P  h, `        pHdrMid->free = TRUE;                        /* the main block */: y$ Y+ p) a. P6 c  H; ^* h
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    5 J+ b0 ]$ r" `
    ; r0 ?# P$ r9 i! P2 ^9 O        pHdrEnd = NEXT_HDR(pHdrMid);9 @# X1 L2 s5 l- f' n( r/ c% V+ h4 \
            pHdrEnd->prevHdr = pHdrMid;
    $ ^: m9 A1 C* I  w+ Z& t# [% D        pHdrEnd->free = FALSE;" q5 y4 A" C' _4 w: h9 q
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;; S# j8 _5 z9 r7 C
    " `6 u7 ]2 {! W' k
            /* TODO take sem hear */0 U4 N2 n; F7 _' C3 `) K* j
            semTake(partId->semPartId, WAIT_FOREVER);% g2 q% h2 ~' L2 o$ U( A, l
            : k/ p1 Q* a5 ?! M$ ~
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));! m. s' s1 f- b/ S  a
            partId->totalWords += (poolSize >> 1);
    4 D) V, s) H  H" d' F$ O
    - _- Y% j& k' H, z        /* TODO give sem hear */6 c' j5 x9 w$ b, n5 W8 ~2 D
            semGive(partId->semPartId);
    9 S% x" S- d6 O6 `+ z2 L) J, T5 p4 L) p

    ; d; x& d) L  C+ ]        return (OK);3 I7 `+ T- [$ S0 u' r
    }
    $ q; y' k5 {) }7 w% v4 e" g$ F  s, ?+ A' |- {& M/ k7 w0 S- h
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    $ a! x+ B+ `9 G{! _; p. M4 T; X4 v! q8 \6 W; Z  z4 U5 e
            FAST unsigned nWords;6 V! K3 Y, [& Q% t3 Q
            FAST unsigned nWordsExtra;
    / P2 h, T6 a. V& |$ y        FAST DL_NODE* pNode;
      a! W- T0 E' P2 R) m& t& y0 G        FAST BLOCK_HDR* pHdr;
    ; `/ s0 V  I  N" B% P7 k0 m) e        BLOCK_HDR* pNewHdr;
    ; ]4 d* h# Y6 F4 d% h% z4 u        BLOCK_HDR* origpHdr;
    9 g: ^3 e( x1 g% y( E3 ?& U2 h! i! K
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */" `, O0 a2 y5 c  y9 _  H' `6 v
            {. ~# G- a: Q3 Z! m: M; K! `
                    return (NULL);
    ( f+ w6 _+ j0 y9 s7 t        }& |2 d2 ~) Q( N% a& R3 p: H: B3 h
    6 m! H+ D/ p% r1 i
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;9 e/ b. Z1 ]! K2 y" D, Q
    , y( S8 l  h" j$ s  t$ {: d
            if((nWords<<1) < nBytes)
    - v/ O* l7 B1 {5 g, Q9 a; |: ^7 ?        {
    # _7 v% x% N: {' \; u2 |: U                /* TODO suspend the task */
    . L8 p. T  \9 V7 G! \& v                return (NULL);& M# f/ I6 k+ i
            }- R* f8 j; I2 f$ W
    5 w7 S& u' Y, s/ p, T4 T  a# f
            if(nWords < partId->minBlockWords)& w9 `5 _% v/ N( P' S( z' R
            {8 X! n& ]7 N& b' Z* q
                    nWords = partId->minBlockWords;
    9 G2 Y4 S+ ?4 q% l        }% U* ~5 s6 m6 J8 |

    : \/ ~0 Y! ~# L, x4 e        /* TODO task the semaphore hear */
      j0 P5 L1 T$ v1 s        semTake(partId->semPartId, WAIT_FOREVER);
    6 U9 {( `+ q  Y3 D6 v& Q        pNode = DLL_FIRST(&partId->freeList);; h, o2 B* m1 I* V+ [! T
            nWordsExtra = nWords + align/2; /* why? */
    . U& m: q6 O+ s) }9 t* h- p6 F
    - X  B" h$ S3 E% n5 I        for(;;)/ v7 y, y% r5 v
            {
    : G- ^6 t1 J! a) o$ f, i5 h                while(NULL != pNode)/ f; n$ l; ]8 c2 \3 G/ h, _
                    {
    5 J* A6 L* K6 Z7 x& O                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    ' }+ z: t' U, `# j                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    9 u! @! J/ q) _' d                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))) y' Q  C# E" \2 W& r7 u6 h! G
                            {% s6 o" i0 i6 f) G4 q% d. `
                                    break;1 H- f' K( o6 }
                            }
    3 V3 s- x1 Y! b% X0 X: h& r0 z2 x9 ^, s1 E% J
                            pNode = DLL_NEXT(pNode);
    ' E3 ~1 ^7 G! u  {, O0 I                }
      H5 S" A& c. o$ k: K0 \
    7 r& n, S1 b- y, ~                if(NULL == pNode)
    ! ~8 w8 O% c7 b6 f9 R/ q8 D3 w                {
    ( I, U3 P2 C+ r0 x                        /*TODO give the semaphore */
    ( t+ G9 A8 n1 A* c9 w: ~                        semGive(partId->semPartId);
    5 H( \! |: t$ m  D; D                        return NULL;
    $ o6 M3 J3 D6 f' t                }1 [5 R5 ^8 y( G* r* T8 W
    # Z0 g0 A. F; J: K5 R
                    pHdr = NODE_TO_HDR(pNode);1 b' Z+ C! Z3 N2 U- d; u) V# J7 `
                    origpHdr = pHdr;
    8 T. b2 g3 c" ^. B! V. s) S# W" M) x" w& v9 |$ W
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    - r4 k8 N! c) G5 I5 p                if(NULL != pNewHdr)
    ( G+ Y8 x$ d% d8 m) F                {
    : U8 p4 D; U) H2 M* t0 g: T                        pHdr = pNewHdr;: p$ X/ u* r) {" V& L
                            break;0 d" W. P# I5 B& [
                    }
    ' l( R; x8 x3 v2 \: Q# H( K
    ! @9 q. N2 [2 R, U  [8 x, X5 T# |                pNode = DLL_NEXT(pNode);
    5 g1 L$ i0 b4 n) D        }! g0 `, ^) K% g2 ~, J' S# T' s

    ; z4 @5 }7 R/ H% Q! A# r        pHdr->free = FALSE;
    ) Q3 B1 c9 d: X/ I! F6 y; J        partId->allBlocksAlloc++;
    * F# z1 w* Z: `/ l0 F        partId->allWordsAlloc += pHdr->nWords;
    % D; x2 L3 G7 B# G6 O        partId->curBlocksAlloc++;2 w" J8 \. Z- e6 k6 ^' o. k
            partId->curWordsAlloc += pHdr->nWords;
    1 I6 Q5 u+ n1 f9 Q. T- f
    8 @! b' p& `$ B5 `5 M        /*TODO give the  semaphore hear */
    & G% ~+ s- x  }2 ]        semGive(partId->semPartId);# _: a  f! {2 e/ p5 B
            return (HDR_TO_BLOCK(pHdr));* b' z6 W4 Z4 ]2 W
           
    8 }) H2 T  t/ v  t( A' D}
    8 D4 H6 N: ~( ~) T2 V: \- t! X$ n7 I& m* H  f
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    6 y# p4 c: Q" l. e% R9 b, m! D{) d: {* e8 e7 k8 |- M! y
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    - }/ B& h5 F& u}
    ( U. f: d) Q5 s3 f# u! c, w% e" H: k9 O2 ~# S
    STATUS memPartFree(PART_ID partId, char* pBlock)
    9 e+ y1 b' T; C  z1 _{. A+ y+ {1 L! Q: l  r; O
            FAST BLOCK_HDR *pHdr;# }0 L* d0 K( j: O& q* m) ^
        FAST unsigned   nWords;
    # Y$ ?! y* p0 Z5 u+ v8 `8 z    FAST BLOCK_HDR *pNextHdr;
    + d: s) S, d) U% E% v2 b- N2 B  P/ N1 I" [' e9 \
            if(!IS_CLASS(partId, memPartClassId))& W; n( }6 c8 L8 i* Y
            {9 b/ O# \* V. q0 x6 C6 w
                    return (ERROR);
    " Y+ t2 C; O2 L# R        }! X$ v/ j3 j+ i1 y; f2 s
    ( W2 J' L: I+ I& @9 V
            if(NULL == pBlock)
    ) s2 i- H+ v* Z3 M4 E        {$ q& t3 h9 N/ i! ]% \
                    return (OK);
    6 f( `; }: G% [5 T3 s; n        }
      U$ R) o3 G& T# ]1 e9 k; N* Q, s2 I( k- J' N1 D0 J
            pHdr =  BLOCK_TO_HDR(pBlock);
    ) f7 I9 P. L' ~9 v4 \: `1 ~) g
    3 |9 X3 R8 @# g7 p7 j        semTake(partId->semPartId, WAIT_FOREVER);
    3 k- o3 H' G; G' m( N
    5 f2 M# D, U; D* v1 Y' @: f        if((partId->options & MEM_BLOCK_CHECK)
    3 ~# M( a9 A8 O3 R5 u- H7 r. E$ O6 b+ z, P- N                && !memPartBlockIsValid(partId, pHdr, FALSE))
    0 q( K9 V& V" ^; c7 a; S        {- L; d3 N  S9 s2 {; J
                    semGive(partId->semPartId);
    - w9 ~% e0 i- v. _5 y                return (ERROR);
    6 I/ X* k0 R2 S( u+ \        }5 ]  x' N3 L( d1 e' k& v

    ) A5 b6 `- R9 I  `7 ^; Q4 `        nWords = pHdr->nWords;
    : a4 m4 c% M+ v9 q% k        if(PREV_HDR(pHdr)->free)3 _% F8 n- z" |6 }+ c
            {/* the prev hdr is free and than coalesce with it */
    " {* ]0 P1 ?1 e4 |# X* t) A' A                pHdr->free = FALSE;
    6 Q. S3 U! B; A                pHdr = PREV_HDR(pHdr);
    / o# `3 w4 v& T7 u& Y0 \7 e% ~                pHdr->nWords += nWords;
    + l+ Y* u0 Q4 F- K( X        }' u+ j9 b' @$ `4 c9 F. N$ T, }8 q
            else
    3 P' |# m. j. p, T, o, S        {) A- r6 c- ?( q4 B3 t1 S- t
                    pHdr->free = TRUE;
    / C9 y& D$ G: ^1 x( e3 G                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    ! G  Q. k3 T6 b4 i        }% C$ M/ {' t2 j7 h
    * D8 O$ [" e) L5 E
            /* check to coalesce with the next */
    1 H" q" {7 m  T) `6 O( v4 Z        pNextHdr = NEXT_HDR(pHdr);
    ) ~/ m; ?+ M! l& B" I' D& J# D        if(pNextHdr->free)
    + `1 E% g, a  O. k# C        {
    , V' L2 b  e( v- `& r  m4 [2 Y+ M( I0 r                pHdr->nWords += pNextHdr->nWords;* m2 W2 M" X6 B9 E
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    - I) d/ O/ ]4 e' `& l7 |( J        }' A5 ?5 C4 ]. E1 E$ d( W

    ! z5 {. u) n3 M" p! F9 a# H        /* cannot use pNextHdr->prevHdr=pHdr hear */
    8 \/ I  Y3 _( H2 i7 G6 d; ]        NEXT_HDR(pHdr)->prevHdr = pHdr;
    4 r6 o" \, W7 p& ^; Z7 Y3 ~9 ^: O6 u, x) z5 L8 m- B
            partId->curBlocksAlloc--;4 H' ~* X* p6 \6 B
            partId->curWordsAlloc -= nWords;2 I2 H4 ?* b# A0 x* r" ]
    ; S6 ]( a" B. k2 _+ O( g0 n
            /* TODO give sem hear */
    7 ~# u( E5 ?7 |        semGive(partId->semPartId);
    ( e; i4 x$ a' `& c- c7 _2 j- a        ) g! @& G: k6 @/ U
            return (OK);
    # L& ^7 _$ Q0 k( l, V, j}
    , ^9 @7 ~( i5 J. t/ d3 A$ v: j9 _# C
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    # `( J) Z( w5 B, C{: ^- W% J$ J/ s1 C
            BOOL valid;4 Z' c( f# }4 a0 ?/ t
    0 r5 N" l$ x3 n' g- q* g* }
            TASK_LOCK();
    ( u, q8 P* X/ g- Q        semGive(partId->semPartId);
      ~6 @6 l+ J! W+ x; @; {        7 g: G* H% V/ f8 W" ?
            valid = MEM_ALIGNED(pHdr)
    2 g: e4 \4 I+ q- X0 Z" S5 x  O( Q        && MEM_ALIGNED(pHdr->nWords*2)! v( p$ }' K- E( @# W* x
            && (pHdr->nWords < partId->totalWords) ! C/ q0 e# z* m6 K8 Q2 |1 |8 |8 Q
            && (pHdr->free == isFree)
    ; t& V5 n, ^! t4 k" b        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    1 l+ R' _- I! j. l7 S9 O        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));. P6 V. l: A: W- t& ~: g
            7 ^, e' Y4 f9 P3 V
            semTake(partId->semPartId, WAIT_FOREVER);
    2 f8 h. J' C. r$ p6 o6 \        TASK_UNLOCK();& G+ }3 x$ h4 ~: O6 m

    + v( Z& i5 T, \/ Z1 h        return valid;
    + \* Q, T1 s' R" U}; ~) m( u) H7 s" H

      Q. H& ]; d  Ystatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    9 z5 M% x: C# v' @6 o        , FAST BLOCK_HDR* pHdr
    0 N  f4 c* X6 N. Y        , FAST unsigned nWords0 D/ I/ W- |3 C4 k' D! ?; e! ~* U, c
            , unsigned minWords' S3 N3 s  S/ [4 K7 r8 I7 H
            , unsigned align)2 @+ y' ^6 T; H/ l
    {
    + M5 R& ?3 T1 R, o        FAST BLOCK_HDR *pNewHdr;% J0 E+ J$ z- {/ J/ d. H  P
        FAST BLOCK_HDR *pNextHdr;
    9 B  M" j. n. |6 s% b: B4 Z: d    FAST char *endOfBlock;
    # P* }0 k* l- x4 ^5 @* U    FAST char *pNewBlock;
    . e9 ^) _- C5 y    int blockSize;
    6 q6 R5 @# P3 g. I- T6 O5 Q* v6 x; ^" Y  g
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);  ~# m/ I$ z5 G& f! @

    0 o( D. A8 Y4 S        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));2 W3 K! \. H+ U( J  o1 y
    + l- B1 S5 y/ @* K( H1 R0 j: g
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));0 Y7 \+ i1 E, ]7 ]

    2 D7 m6 U* s: b# h' k        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    ( ~8 X% N5 f/ `+ G9 G3 d$ @. |# A2 g& v8 @6 @: d( q" k
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;0 I  e9 C& R% w" p+ `2 Z3 k: A) |
    # i& i) j( G4 c
            if(blockSize < minWords)
    , }, C6 j$ x0 _5 s& u9 y        {
    ; _8 i0 u% \5 A* Y7 ~. T8 o                if(pNewHdr == pHdr)# W4 E+ z( x: B) n  }. b
                    {
    ' c8 @' O1 W# T  Y- T                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ' ~1 n9 {6 q/ n* c                }
    ' s* j; H+ L; n& f% b3 b7 [                else
    + W- Q  r+ \& Z$ @) d                {
    - R1 \) M( \; i                        return NULL;: Q$ W! j2 c, W& H) h9 w7 `; [
                    }8 J3 v5 ^/ [) @
            }
      G( R- |7 A" W1 j        else
    - q$ r* p+ {8 ~8 v+ {0 k        {        /* recaculate pHdr */
    7 _$ l% W+ @5 L4 f' Y                pNewHdr->prevHdr = pHdr;5 H3 g  B0 u- i! b  U% |
                    pHdr->nWords = blockSize;
    9 L3 Y, F7 l& S9 Q# F        }
    * Z$ {. @! x6 P9 n1 L  ^
    ! f4 a0 C# l" J$ O" Y        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    " R- }: T+ n5 Y' ]        {
    " I+ l+ Z. T6 `" a* C& r                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    0 n( q# e6 f: P4 R" o                pNewHdr->free = TRUE;
    1 F& C& P: X6 T7 @  p+ Y# ~. [7 N8 ^2 N" S6 J; p
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;3 S% C5 @8 @& g7 G- N: ^2 d) H% J
            }6 P/ j4 S7 C* p( V$ D2 h
            else$ S8 Z9 K  A+ r
            {/* space left is enough to be a fragment on the free list then */
    # T0 z  O  g8 a9 P* t                pNewHdr->nWords = nWords;
    ; ?8 {8 ?: b: s( \2 H3 J4 ~                pNewHdr->free = TRUE;- @+ ~5 T9 t1 ~; _, W

    6 o) ~' R# _  m% {7 v/ c. ?                pNextHdr = NEXT_HDR(pNewHdr);" k$ O$ r+ J- |2 w- z& p" i
                    /* words 包括BlockHdr */
    4 X0 {: n; [+ w                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    1 a5 w7 O- |7 H  g: \6 k" X                pNextHdr->prevHdr = pNewHdr;
    % K( e  C- ]; l                pNextHdr->free = TRUE;' E3 ~4 L8 B/ }# y1 L; b
    ! w& l1 C+ R" j
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    6 c* M# E6 H8 P8 C  _. q. ]) Z/ Q; n9 s! N
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    / n# [$ i+ U4 e; T7 @% e        }
    6 C! `9 A* P( e) a( C; J* Z4 d& A7 R& N/ e0 E$ F! P, j; C5 k; Z
            return (pNewHdr);) d& @( i: x% }5 h- L
    }
    , F; W- a) U& g1 D; Y  E! L5 L5 S* X7 O. Z" b% U9 U6 y! o
    static void memPartSemInit(PART_ID partId)- d; l/ p& p* o
    {9 E8 x  k5 f3 D# L
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    1 V) O& T1 M6 r* L' X2 D1 Z  f- J$ q% |
            partId->semPartId = &semMemSysPartition;
    ! _$ T; w2 ^$ ]$ }" u}" w, Y. E0 J& w' V

    / P8 P2 o9 O+ X/ Y7 A* Cvoid* malloc(unsigned bytes)& _" ~: i' Y. \: T
    {
    1 }" b; d7 \. x8 b% {( E9 V+ g        return memPartAlloc(memSysPartId, bytes);2 {# B4 }7 {% Q$ T% m
    }) b. N/ b7 Z# x+ }# y- g8 o

    # Y  s) @  }  d# X6 tvoid free(void* p)
    + E/ c3 P# v% ~% H9 Q% ?{
    , \% _3 T8 r" Q3 f6 ~        memPartFree(memSysPartId, (char*)p);
    9 i7 c2 z. O- x* v}
    3 w$ ~9 p" Z9 W4 M! i1 @
    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-6-3 12:21 , Processed in 0.402179 second(s), 51 queries .

    回顶部