QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2686|回复: 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++下的版本,更方便调试。有需要请留言; L8 a+ D- j: `9 B0 L4 \/ m

      L) S# U; h. |# D+ P1 l: e9 i9 y) H% c& H2 Y

    " ?  c8 C9 ?+ N8 P *\file
    - `& }+ x# J4 e *\brief                / `4 A- K0 e. V# \7 ^
    *\details       
    7 Z3 \8 D7 n$ P *
    8 ]% w' {, s7 O& g! U *\author        Janson
    9 h" ]) M) G0 b: @3 ~- u *\version        ' E2 V# |; c6 N
    *\date                04Jan12, g8 M: n3 T- v( x* M  m) B% ]  `
    *2 l& m1 z0 H, h8 S
    *\warning       
    2 k; ?, f4 y. ]8 ] *% E. F6 o% w; j
    *\history \arg        30Jan12, Janson, Create the file8 ~, d/ A! s3 e& Y# o  _: d/ U
    *        modify from VxWorks source
    ! ?. P: b5 A5 L! ]2 X *  Legal Declaration: it is for studying VxWorks only.
    . E, U( u& b) N */
    ( a8 Z# ^7 k$ a" P+ G#include "includes.h"
    2 N$ q2 v2 r- t! {) X0 p1 m) t3 B3 u* z+ ^
    /* The memParLib.h file is hear:
    $ Y9 e) v" P" b2 m7 {8 Yhttps://code.google.com/p/vxwork ... rivate/memPartLib.h' ]% f& s. N$ N* X: z
    */: t! `2 u$ E6 l5 S. ]8 o
    ; n9 y' k  [) H0 r  F7 l
    /* optional check for bad blocks */0 {2 `, S6 c/ `3 U, S

    7 N' o' y# K1 h! ~7 s#define MEM_BLOCK_CHECK                        0x10
    + _7 v$ z8 @: q8 B7 \
    * ?! Y' g( M) ~# V" L/* response to errors when allocating memory */
    , u! W1 K% G7 n! H' v2 n
    9 W1 H& e7 W+ o" R+ f( E#define MEM_ALLOC_ERROR_LOG_FLAG        0x207 h: }; d: F3 h) z4 `
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    ) }+ @! z" K, Z9 f1 Y! l( s9 [2 K; A% L& {3 ~3 W7 l$ D
    /* response to errors when freeing memory */
    ; [$ F* h, ~' i( l7 ^, J
    * {" o+ y# q# v4 y0 s#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    " W3 ?0 g/ M# U5 O6 Q$ v#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100- M! `% ?% \( D/ P  e/ i; |, @

    8 Q0 H( }7 ^3 ^8 E7 y#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))0 u  n5 i: ^9 B( e  a9 E
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)8 T8 E, Y5 u3 T6 u, Q
    6 _5 |7 z& r8 m6 E
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))) _1 u* y- N9 B7 T* {
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    ) B' o2 z1 I: M* K7 H                                                sizeof(BLOCK_HDR)))0 m6 p- D) k& E- S+ ~4 g) o

    & }6 Q" @; a! f; E#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    ) b  {8 C' x- q5 u#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    : H0 o4 d% ?% F3 z                                                OFFSET (FREE_BLOCK, node)))3 ~5 a/ a, k8 i+ i

    6 a7 ?6 q- I) S* L2 c$ Y& L+ [' hstatic BOOL memPartLibInstalled = FALSE;
    3 Y8 e7 Q* T4 h* I3 p
    5 B, I  B9 h& G$ Istatic OBJ_CLASS memPartClass;# L/ @$ s* K' d2 i5 u7 A
    CLASS_ID memPartClassId = &memPartClass;
      t! {  ]1 U" J# m9 {% B% Z9 _1 F9 k/ q5 w- C, v
    static PARTITION memSysPartition;9 ?% f; v- Z; V" ?* X
    PART_ID memSysPartId = &memSysPartition;
    $ m% G3 L0 u) U% hU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    ! ?4 v3 o) j, Y  x. P
    1 m3 L1 @! D$ q  h- ]; S2 i/ \static SEMAPHORE semMemSysPartition;- K5 I7 f; \0 x& B8 ]0 j
    ( n3 n& }/ I* z
    static void memPartSemInit(PART_ID partId);* v- P$ G  M% O& I1 m( B
    / D. U! F# k' T
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;7 G" j, J# w; F, U: Y& z; [: E
    $ s) ~( u, j0 }6 `) ]. H3 y5 H: K
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;. Z' u1 i6 b4 C/ k/ o
    8 w( }8 R$ H, w3 X9 {" e) R" Z
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);7 [8 c/ H) i! X
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId- L4 d$ l4 j7 y8 }
            , FAST BLOCK_HDR* pHdr
    , \* P$ e. y" S* t/ ]9 L        , FAST unsigned nWords
    1 q+ }8 b7 F$ A3 _1 u# |        , unsigned minWords
    : a  I( v9 o9 F/ ]* S4 g; n0 g        , unsigned align);
    7 Q/ B' L) J* g; [: ~4 h/ s. r7 N8 A+ p# l2 g
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    0 q1 J+ S7 m  ?$ J+ s6 K; S
    8 F8 S3 v: S, F7 D+ h# w, F; aSTATUS memPartLibInit(char* pPool, unsigned poolSize)' i2 F% I# k% W! i( D; F: u
    {
    1 B& l9 r) ^* Q) p$ L        if((!memPartLibInstalled) && 0 T4 k' l* s9 d1 L' G5 v0 A6 I
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)- L, g: q9 d: x3 A) a0 M
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    # ]0 z$ L' _" h1 ^/ y        {& s* b4 ?: J8 V8 W
                    memPartInit(&memSysPartition, pPool, poolSize);! _6 g6 h! O. }
                    memPartLibInstalled = TRUE;, U& k0 ]- t9 {" p3 |" g/ u+ K. j
            }
    ; V/ \4 `4 p' j! W  a( j+ U- h5 s' Z! y5 [2 }7 |
            return ((memPartLibInstalled)? OK : ERROR);# O# O+ ?2 e  u0 A) N) i
    }5 n. G" @1 [- O8 M* z, V8 A# _

    + U3 J) c2 s; J! gPART_ID memPartCreate(char* pPool, unsigned poolSize)7 Q' u& j5 f. V. S
    {7 J. I6 y$ `$ ^8 S4 p' }
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    : W0 b- c+ `0 `
    : |, N! y! Q7 m; c+ [9 {' r        if(NULL != pPart)
    / a  |8 K" O: y% j; B* ?        {
    ) \3 }' }, ?* A+ \" Z, @) w3 u' q! b, M                memPartInit(pPart, pPool, poolSize);, W9 l- |- F6 b, F
            }
    # L$ L# @' H% n
    ; g+ q" [+ y- J  F1 B        return pPart;7 _. M( x* {" E% ]* q) I
    }9 S5 M4 i9 H( D& _: Z( w

    : n( s9 j$ X1 g! f% ?  rvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)( J  L7 A6 |& L7 e5 m
    {2 E: D0 c" t; @; B
            memset((void*)partId, 0, sizeof(*partId));* g& c! @" E  b

    5 c& g+ K* Y$ A4 {* `        partId->options = memPartDefaultOption;) |, Z- o1 @  u2 n$ h" g' Z
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    ; x6 h4 L2 r- t8 f* f
    % j3 ~5 n8 M$ X- b3 L        (* memPartSemInitRtn) (partId);
    $ \/ x( s4 ^* l$ u4 r4 s       
    4 G- `) }3 H& E: `        dllInit(&partId->freeList);& t$ h% W! y  `, P4 D  O) U) a2 ^8 W
            1 b8 X  ^# j/ U% f
            objCoreInit(&partId->objCore, memPartClassId);
    2 I3 o$ U0 H3 |( o& F       
    5 e+ ^9 V7 q$ U1 p) a        memPartAddToPool(partId, pPool, poolSize);
    , q( ?" H# w+ H9 n}
    # u; E, i5 i* |# k
    ' Q8 |4 K2 H: c0 o% d9 ?$ k% YSTATUS memPartDestroy(PART_ID partId)! {; X' `9 e9 o; v# }* s8 a, D  {( Z
    {6 c( ^  n" L- ]/ x4 d
            return (ERROR);2 K: k+ o$ |% p7 b* O9 \) |
    }
    ' y6 n! M6 H* {' t9 `
    / l$ J/ O0 X$ ?. M2 n2 |7 F1 gvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)' W8 B; O( k3 y' q/ x  ^
    {9 f" q: i( Z" L  A2 N1 h
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);$ N1 q, A. u' n3 X  y  K$ c' J) z- @
    }
    . C! R/ a' f- j* J
    7 k" e; b+ x0 }' z' g
      b6 j1 b, p8 bstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize). y8 {6 p! h" A- u. M) c
    {
    & c: v3 w% s) |% A2 W  o        BLOCK_HDR* pHdrStart;
    / E: {  o0 P+ ^# |) h9 B4 Z        BLOCK_HDR* pHdrMid;
    2 R4 o' `4 d7 e. l" ~& P0 x5 o# B        BLOCK_HDR* pHdrEnd;
    3 {4 L7 a) h3 K6 U. {" G        char* tmp;$ N  }, T& b4 M( X$ O
            int reducePool;
      u5 S7 k, H0 T: Q5 C2 J2 L6 P$ z! k5 Y5 ~2 X0 s2 c% N
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ! J) _9 e1 b+ i  }3 Z        {& @" D" S# l# j5 V
                    return (ERROR);
    8 v6 ]  g& x! s0 `        }
    ! w& e+ z! [8 ]' G/ v
    * s9 ~4 {# x9 b5 k' H  B$ G        tmp = (char*) MEM_ROUND_UP(pPool);
    $ Z; p. ]+ i) k2 P5 N" }3 M% |- b        reducePool = tmp - pPool;
    5 j% Z5 p9 ?- d) F8 N2 s/ a" H0 V$ v' ]" q
            /* adjust the lenght */) A0 A; Z9 y1 Z* J( @3 ?
            if(poolSize >= reducePool)% ]% p% K7 R  ^: }% c( T8 X6 ^
            {2 Q- T% P- S  k7 o2 A$ Q
                    poolSize -= reducePool;
    5 o. j8 b, D' j3 b6 z        }0 u& h: Y; G6 A& X( c- c
            else
    7 e" @& M# r: c' [3 c& u        {. i5 J2 t' w; i/ y
                    poolSize = 0;
    - k: u% L+ B& y        }
    9 a0 P' a9 O6 j2 c6 v        pPool = tmp;
    6 n9 ?( C. Y: a        ! I( i( S- X8 A  N2 i7 r% X
            poolSize = MEM_ROUND_DOWN(poolSize);. ^7 y0 h- @6 t; |
           
    ) ~+ m2 e* M# m7 o        /* at least one valid free block and three header blocks */% k0 Q* ]- K  ~* z% f! s
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    1 S) q& A$ U) [8 U7 x        {5 X) E0 Q) Y3 R6 W! u# Z
                    return (ERROR);5 S% h" R7 C# o0 \' w
            }: H7 `0 Z7 ^+ x/ V# v( ~, N- p

      r8 p- W( _. e& V1 r        /* initialize three blocks */
    ) [4 J5 {# l; U3 ^' i6 F# D7 y        pHdrStart = (BLOCK_HDR*)pPool;
    % l. o3 D. ?% I' N. Z, Q! ~1 P9 t        pHdrStart->prevHdr = NULL;
    # S4 ]- \; [' L4 c        pHdrStart->free = FALSE;                /* never in use */
    # X& L1 d- S% M  O; }        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    - N& ?2 m- X3 g6 K2 f* G. u# F! V0 I% V2 z9 U. v  ?
            pHdrMid = NEXT_HDR(pHdrStart);
    5 v! s' e/ o  E        pHdrMid->prevHdr = pHdrStart;' j2 n# h9 g5 }# K' |& m
            pHdrMid->free = TRUE;                        /* the main block */8 L( r' I( Z4 n% p6 U: u6 n
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;/ u4 p9 R! i+ ]7 p* C7 t1 I6 B

    9 N% f$ p  w4 @( V        pHdrEnd = NEXT_HDR(pHdrMid);) z) g& h$ K7 f  N  U- F
            pHdrEnd->prevHdr = pHdrMid;, H+ V) R- p4 X/ C
            pHdrEnd->free = FALSE;
    ; s+ l5 z- ~9 J* j4 d) R- f) r, |        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;8 o" r& e2 r3 o# z
    ! p, {* a% n3 M: t4 p7 {+ N
            /* TODO take sem hear */3 D/ f- Z% g% c4 b* m8 k( k% X
            semTake(partId->semPartId, WAIT_FOREVER);
    , w* V$ ], a" S) i) e        ( t, Y) p9 l% j% y2 ~
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# p' f$ T& E, p; m. O* ?( A
            partId->totalWords += (poolSize >> 1);3 _/ w+ v1 ?/ J7 d$ `- A0 U; ^

    , V! {# \  H2 u: s& s9 s        /* TODO give sem hear */* F! L' T1 w& ?7 {& N2 Y
            semGive(partId->semPartId);
    3 C5 U( ]+ b; _& u+ X$ E1 p- B9 }# {  d' h" q

    1 {3 h3 v0 ^! e6 U" `        return (OK);: z+ Q# P' D' P! K+ a$ X
    }
    3 l8 ?/ Q% e5 b: `+ x: A8 a) A" c9 o2 `, b$ f% l
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)- t' y6 {& r8 T- u9 @
    {
    + V+ ?# U8 v# q/ S/ Y8 j% ?        FAST unsigned nWords;' d" s3 {! b0 k! Y# J; o- N( X; ?. H
            FAST unsigned nWordsExtra;
    * ?$ t2 ~5 o0 Y4 k7 c: d9 O4 m8 a        FAST DL_NODE* pNode;+ E, K+ I. y4 m
            FAST BLOCK_HDR* pHdr;
    7 [7 p' M9 P. L+ G4 B1 A* R        BLOCK_HDR* pNewHdr;  l7 v4 X4 w9 D
            BLOCK_HDR* origpHdr;
    9 v' I$ S9 `( a, w6 J6 @/ r) d; L( ]) J, U  u
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function *// k/ g  f0 S9 X1 x
            {
    9 j7 x5 }5 v6 W8 Q                return (NULL);. q2 y& ~$ v5 |" ~1 c- L8 @
            }
      _4 f* k, o( R, D
    % [/ K8 J: @) U  _& `1 b# c        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;- V0 B6 D8 V# ~1 G  [# `
    2 X# t4 W& h! A# B
            if((nWords<<1) < nBytes)
    5 x5 ]  P. [0 Q( L        {. d* [1 C" f' ~  }6 E" T1 @
                    /* TODO suspend the task */8 {: j1 P0 ~* R7 R* G: u5 C
                    return (NULL);( d3 p- n. B0 {4 }, e0 V
            }" J. g8 H% m  ]) _+ [9 S2 E

    5 a, B! I) {6 o+ g: I        if(nWords < partId->minBlockWords)
    # ?% }9 b8 p$ s7 ?5 o8 W# p        {
    ) l5 {$ r7 d  v                nWords = partId->minBlockWords;
    8 U9 c# k4 F" m, {$ ~9 @        }
    : d# k! F* \# E3 q
    & I7 d+ H+ K+ T( n* d9 T        /* TODO task the semaphore hear */
    # S/ p6 A7 ~. Y7 C0 J+ f* H( w7 o- t. O        semTake(partId->semPartId, WAIT_FOREVER);% O4 {9 y( {3 L' e/ V% E' e
            pNode = DLL_FIRST(&partId->freeList);8 S4 t2 A" J$ `" y8 D* j% e" o
            nWordsExtra = nWords + align/2; /* why? */( @+ g0 b) q3 j& Y$ ^# _; S
    " D4 j9 |; q1 ?& `6 V
            for(;;)$ z  W& L, E2 f/ O8 \( ?
            {
    5 Y0 n+ Z, T8 a7 l                while(NULL != pNode)
      q8 y- e% I9 @6 O" W                {% @) w# e5 g2 e2 P4 v
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||2 M, k$ f  k/ j- n- s" t
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && 6 b) H: r$ _# h2 C7 N4 M! ]/ Q
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))( a& c, N- V: A6 a: u
                            {- b5 f9 A! v  Q- E2 v8 J/ G8 e
                                    break;
    & E( S1 @- j/ b# T! v5 ~/ K                        }
    3 n. @4 E1 G# I& T4 v% K& D' c0 g2 J: F; ^
                            pNode = DLL_NEXT(pNode);
    , ~1 a* T3 j5 \" K+ k# u9 ?/ E                }# |3 t  c* o: r

    0 k' D" `6 j( r                if(NULL == pNode)
    ' A3 Z% z5 n( K) L                {3 C0 Z& L% w' d2 @9 m6 M
                            /*TODO give the semaphore */
    3 A5 ^) D+ X2 {% ^1 G* a6 w! m                        semGive(partId->semPartId);
    5 E) t; `  u0 z/ B* I/ h* C                        return NULL;  E+ c; C6 `/ f( O/ [
                    }8 s7 X6 q# N- d& G% X& Q

    0 |- e5 ^% O$ k: [% X5 _: q' G                pHdr = NODE_TO_HDR(pNode);
    ( |! A5 J% E  ?+ t                origpHdr = pHdr;6 T' h: \. S' U% {/ Y& x8 ]
    8 K1 H: s; I4 F1 |  W
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);# W8 f: v& P  A5 o" w0 o+ }) X
                    if(NULL != pNewHdr)
    ; [0 d  l& ?6 ^0 ~$ G                {
    1 Z( D& h0 F% Q& |' u                        pHdr = pNewHdr;
    : W7 q) @6 X- s                        break;
    ; M! ?1 p! `* Z) T3 k) j                }3 z$ b. b1 x# Z# G1 N
    + L# ^6 @, T- F8 b$ F
                    pNode = DLL_NEXT(pNode);
    - |1 ?* y+ D6 q) K  e        }
    ; S* m; Q, C) C% Z1 L& G4 C1 v$ t0 o( f
    ' e+ o4 p6 Y3 X4 K        pHdr->free = FALSE;5 m& w. D  j" e, Q
            partId->allBlocksAlloc++;/ t* \' y6 O* y. b+ F9 y( H; v
            partId->allWordsAlloc += pHdr->nWords;
    ' P6 X+ ~( ~9 F" Y. d0 P: b        partId->curBlocksAlloc++;% o" |6 o' W8 c# S+ k) r
            partId->curWordsAlloc += pHdr->nWords;
    ( t! I0 [4 Z$ w' w4 t
    % S: a# T! D! _0 Q" I( e& ]3 j$ r        /*TODO give the  semaphore hear */; V7 x3 k2 Z7 G$ f3 m
            semGive(partId->semPartId);
      h% ~9 C3 L+ A9 g        return (HDR_TO_BLOCK(pHdr));9 ?; S2 o; T, |, z+ p
           
    6 A, J, Q; B- b% U}
    # x% u/ I: S. }
    , h3 G/ i9 J$ Rvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes). w! r% h* q& a# z7 ^  _% G
    {8 ?% B5 U! Z1 @- c( y
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    7 i/ f' Y0 c/ ~4 S. D+ v" n1 ~}4 y/ O; f, A( C0 e+ A* w5 n& ?
    : C9 ^* W% ^' }' J
    STATUS memPartFree(PART_ID partId, char* pBlock)
    + U7 i% r2 m% U+ P* K0 v{# p7 {8 l6 v7 W% X, w3 Y) K
            FAST BLOCK_HDR *pHdr;
    - J0 r$ o' t1 L/ P8 o* F, g    FAST unsigned   nWords;) x  g/ Q" e0 A" i/ ~
        FAST BLOCK_HDR *pNextHdr;1 _1 f4 [% J7 s3 s
    8 O5 ?  M) X* m7 @  |% ^
            if(!IS_CLASS(partId, memPartClassId))9 G  S7 j& e  z$ u& J7 H+ J
            {; a) M0 L; K6 E0 \. R$ h* D
                    return (ERROR);
    ' }$ G$ g" O! J( h3 j4 i        }' c3 Q3 C/ i1 l+ t

    # U  P+ [+ H# L" D        if(NULL == pBlock)! w" X0 Y/ {* f
            {
    2 L/ U  W  I4 H0 x                return (OK);
    7 C' P8 z( D+ K0 }3 [" x/ n        }
    9 R( \! \5 O, x  N4 B5 }7 b6 B" M' M" |" f  ~
            pHdr =  BLOCK_TO_HDR(pBlock);- [) G1 H/ N" ]  D  v. ]' v$ R5 B
    $ }7 P# d6 u$ l9 h
            semTake(partId->semPartId, WAIT_FOREVER);' G# S$ C2 F  v  H( b' _0 a1 Q2 I  O

    . n! P8 h% H5 |. v- l5 [6 N        if((partId->options & MEM_BLOCK_CHECK)
    9 |' d; y9 X5 K- @# O. h& z                && !memPartBlockIsValid(partId, pHdr, FALSE))
    2 f! `) S1 p* O        {
    3 o+ z. |. I5 t/ g& q. g. y                semGive(partId->semPartId);) D  Y; q% n' e! R4 {! l
                    return (ERROR);
    % H7 A8 o7 m' u7 {: W3 _$ s        }
    . D- g' A' Q& p- }& x, ^1 E
    # K% N% {6 Q* D- K! |) o        nWords = pHdr->nWords;
    + P. E& O5 {5 T6 H, u  g7 g$ u        if(PREV_HDR(pHdr)->free)
    9 m  X5 H  h5 f        {/* the prev hdr is free and than coalesce with it */
    % H" L% M' g' V                pHdr->free = FALSE;
    $ L/ E; e. ]  ^. F                pHdr = PREV_HDR(pHdr);$ U! C, r& \& e3 p5 X4 b0 [
                    pHdr->nWords += nWords;! v5 @1 H1 n7 T9 z$ V
            }$ m0 z. O1 L2 [* a+ S3 A7 u, X/ d
            else) _, Z- u& |" K5 T8 r9 Y( M
            {8 x$ N1 r& ?, M: c" P
                    pHdr->free = TRUE;
    . ^5 H4 E2 M; i  v' b" E                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));: {' n) E! |5 T
            }; X% G: w  `% l) y: @

    % C, v  r2 K- G  y/ Y# o3 C        /* check to coalesce with the next */
    $ }% U! a4 D% V2 V& y$ |( B/ D+ s) p        pNextHdr = NEXT_HDR(pHdr);3 a* f6 W3 \; q7 u( W
            if(pNextHdr->free)* u5 I, Y% s/ }1 V
            {, k" e5 V3 i" i  h; L" V
                    pHdr->nWords += pNextHdr->nWords;
    & x, I  Y- ^3 V8 L7 g1 G                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));5 u* j$ ^$ }" n' o
            }) ~/ ?6 E" F  V9 V+ _8 K: R$ }+ I
    # O6 s, _1 Q/ ]- z+ f
            /* cannot use pNextHdr->prevHdr=pHdr hear */1 E  a- W/ S  c. i
            NEXT_HDR(pHdr)->prevHdr = pHdr;5 g: g- H! H2 i9 T* }3 z8 P, A

    0 O3 ^7 S* ]6 T        partId->curBlocksAlloc--;
    ' J0 q, l, Q$ v, j        partId->curWordsAlloc -= nWords;2 S# ]/ w9 _9 ?$ o" ~
    7 I8 ?0 F8 [- k& O4 q5 [' o
            /* TODO give sem hear */
    & L  F) W, I" h        semGive(partId->semPartId);
    " Y( Z9 Y; {& o, f. E        # A  y6 h3 Y% O1 s# ^& K2 _; H
            return (OK);
    . c" Q) z5 ^" ^4 r* H3 I0 C$ m}
    * H; \9 h0 K# F8 i
    ' Y: {: @1 m/ c, ]* p' r9 x2 Fstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)' C  {# ~: m4 R* x7 |, F" j6 T
    {
    % n3 i+ Y* h5 f$ _; G/ c  [        BOOL valid;
    " t0 |! e+ ]  _  O9 b# ~( V! g0 g: v8 [+ q
            TASK_LOCK();
      |8 l$ a) Z- S" F) T% ~( o        semGive(partId->semPartId);0 g9 _! P1 R" l9 R. z
            # S' `/ q3 T" g+ t( y3 v; E
            valid = MEM_ALIGNED(pHdr)8 Z! ]+ @" m( H' E
            && MEM_ALIGNED(pHdr->nWords*2)
    & K5 v# I+ h3 Q: c        && (pHdr->nWords < partId->totalWords)
    4 o9 C! {; P/ t5 _% {        && (pHdr->free == isFree)$ |1 O4 n* ?; _6 W" M
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    . i/ E7 D5 d# F4 @) p        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));; `% D& c; y6 S, o5 `
           
    1 [' k5 q- D7 G" R, L/ Q        semTake(partId->semPartId, WAIT_FOREVER);
      n& a- ]* x4 ^" R& F0 L( O        TASK_UNLOCK();0 _8 J2 [" O& d; o8 I6 A, U4 u  ^- n+ h

    * t0 T" J* J; K% s1 q2 o        return valid;; J. `! J0 Y8 P
    }# {7 C  ]" h# L" T

    1 [2 I$ O8 G8 t  }# D" Mstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 V4 p( L- E/ ?
            , FAST BLOCK_HDR* pHdr
    ) I$ s" E' O9 H7 h$ z        , FAST unsigned nWords' r$ A- A, i  ]
            , unsigned minWords" H6 O+ S( m$ C" @
            , unsigned align)
    " h) U  M* T7 l( q; b% s; B2 s4 `{; g" f4 Z  ~5 h5 N2 [: g8 S, ^
            FAST BLOCK_HDR *pNewHdr;! m; p3 L* Y8 s9 B
        FAST BLOCK_HDR *pNextHdr;
    3 U: ?' G, b/ L2 [' w  J    FAST char *endOfBlock;
    4 q" c0 q5 \3 E5 d- U    FAST char *pNewBlock;
    9 I# @0 x4 d, ?& C# F3 g    int blockSize;
    7 v- r/ _7 V1 w8 y) h/ q2 d
    3 B- i; i5 _& p% r5 A2 C        endOfBlock = (char*)pHdr + (pHdr->nWords*2);+ u6 X  a3 C# V$ N) k" C1 \
    5 i" ?8 v/ I. h, ~
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));' s% ?% {* _' V! [  F; @0 u2 B
    6 ]0 I) f8 G: o% h
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));1 Z' h# y, o. S+ B- C$ k
    , O8 m& n0 O  ?" o
            pNewHdr = BLOCK_TO_HDR(pNewBlock);
    ( O" r, v0 z7 P9 _# v% K8 n" H$ R" c9 t/ \# @
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    : Z) k+ s+ l: f8 _+ R/ l# X* t$ N# y0 A# X4 D1 k* N' j8 t5 a: Q  p
            if(blockSize < minWords)
    4 D0 L# l! `! j/ e% O        {
    3 h' l, ?: Y0 y; u" b                if(pNewHdr == pHdr)* A3 c' H5 _" a) J5 g' z
                    {% Y4 B) X# j7 w/ g" N
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    - Q4 p- }  j$ L                }
    / }/ P# K6 J. f5 [                else
    0 f; Z$ I6 ]6 w5 l9 a* t  k+ o5 E. X                {& M8 A: h" t* `% C
                            return NULL;* g, {; K4 @8 f
                    }; k, z5 _; ?4 f' S, T0 T% q
            }
    . C- h2 K4 M% c' P2 ]        else7 J- W0 N9 ^; y* z5 v# h
            {        /* recaculate pHdr */
    4 t% Q& k- @8 S6 x2 Z7 e5 L- |                pNewHdr->prevHdr = pHdr;4 z, H4 d- Y7 Q& n" p: @
                    pHdr->nWords = blockSize;
    $ W) Z5 ~; a3 z1 K9 _        }4 B& l  Y. m* f, n

    : L4 R, N- e  N, V8 ]1 b1 F$ `) x        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    : ]: m+ N+ ?2 A  ]4 u6 R' n        {
    9 K. v* {* @, k* Y* n                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;0 E# n# v  V' f; p/ R! C2 Q5 @, |
                    pNewHdr->free = TRUE;
    6 P# e/ P0 o: y
    4 b- u, J. g; z  W2 g- z. T, z$ G9 h                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;8 G- W1 l. n$ ]; Z5 w
            }7 V0 _9 X* E2 T! w
            else+ \8 x) w  k& u/ K7 _7 X/ D$ {
            {/* space left is enough to be a fragment on the free list then */, }" A' s9 p! ?( `  t8 Q& O
                    pNewHdr->nWords = nWords;
    3 ~$ l( i% f/ G: M6 W$ @* U% d1 w                pNewHdr->free = TRUE;
    & o6 M# T1 P2 g, G: k" ?$ E7 `& t: f/ [% L- j5 T5 o
                    pNextHdr = NEXT_HDR(pNewHdr);* X) b- u5 E1 C" K/ W
                    /* words 包括BlockHdr */. P1 }9 P' y& _
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    2 u7 \% I  j" N5 x                pNextHdr->prevHdr = pNewHdr;& \4 t& h3 Y7 C* r' L
                    pNextHdr->free = TRUE;! F: @1 j9 r9 u2 W& M
    ) [6 R/ v8 J1 U" l+ f" C
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));' v, @# w0 s$ J% t) @) A

    / {4 ?# Y& C8 t$ c! l5 M. W$ H! K% U                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    , |9 o# ?0 q2 o$ u9 \, }        }3 w0 }- H) B# R4 w

    % s, f- ^$ i7 h5 K        return (pNewHdr);
    $ j8 R" Q7 m" ]: C}
    ; r* T- C# m4 t3 q; ], q& ^' r( p
    5 u" V9 t) S% Wstatic void memPartSemInit(PART_ID partId)1 g8 ~  y$ g3 t. r; B+ x$ n
    {: u5 k- e* Y% s3 C! \( Q  B
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);" e6 m+ L( G1 l, T& [, y

    : g! q. ]  M4 U1 _) }/ q7 @        partId->semPartId = &semMemSysPartition;  J) Y: ^' ^7 I, S$ H2 A
    }
    . \* y& A) ]8 l$ Z$ h1 d3 s6 ]4 _6 ]$ }% n: @4 p- _
    void* malloc(unsigned bytes)
    * I$ X7 x( h- x& y/ ^' H8 P$ u{
    ( k" N9 [4 ~, S0 m/ ~' D        return memPartAlloc(memSysPartId, bytes);" ]+ e# s% \" Y" ~+ V$ {
    }' `; W, }) ]; F5 b  f. C; n

    6 n4 x7 m  r1 q. A! Xvoid free(void* p)
    " @. W  \2 V5 G0 w{! z) K5 C6 W# Z  F5 @- i
            memPartFree(memSysPartId, (char*)p);
    7 Z# `: `4 V- `$ M( o9 Z}
    4 F4 Y, i, Q6 u' g
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2025-8-12 18:33 , Processed in 0.689998 second(s), 50 queries .

    回顶部