QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2904|回复: 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++下的版本,更方便调试。有需要请留言
    . z& E' K9 X% p' L& I- {2 u" |" ]4 Z# v" O# Z; |

    0 S- a" u3 ?5 J) p
    " x+ c2 w# ^; ^# x) B) n; W *\file
    ' \3 W0 D1 _# D; j  Q- Y *\brief                / {' f; {5 @) X9 J4 L( L. m
    *\details        + R; S, E9 e2 `# E4 S- n% Q
    *
    ' U6 l, o6 Z4 H1 h& P( v8 W *\author        Janson
    ; f! ^" \, y  k; m7 X5 J *\version        , C6 N4 y- P! V6 I
    *\date                04Jan12
    ; q( E3 X9 Q# h8 V */ ^! f, W" \9 p
    *\warning       
    ) r9 d8 d. E' M4 }* U! u& n4 b *$ {" l+ M' g+ H; N5 [4 b* o
    *\history \arg        30Jan12, Janson, Create the file! J* g# m9 B7 b1 i- Y' r4 \
    *        modify from VxWorks source
    0 I9 R2 o9 c6 n. R *  Legal Declaration: it is for studying VxWorks only.
    5 B- v6 c1 n; @- M0 J */8 _* C/ \1 ~: G4 _
    #include "includes.h"+ P2 \( U, ?8 X: {6 S
    % `, \8 g' U5 i8 l" O$ u
    /* The memParLib.h file is hear:7 V4 g, g0 t: @: |* }% J& j
    https://code.google.com/p/vxwork ... rivate/memPartLib.h5 s4 L" R# w& p
    */8 \# W8 f$ x3 ^1 n) m0 a" {: c
    7 L3 ^+ k- Z" K: C( r
    /* optional check for bad blocks */7 t4 M/ O7 W2 y, r1 O( N

    ! H- Q( l) Z0 Q  u#define MEM_BLOCK_CHECK                        0x10. a' j2 M. L  d2 N0 L* q3 r
    3 b# E" Z% z6 I4 t' K2 W' I
    /* response to errors when allocating memory */
    & ^: J- I" `; R/ `4 v# d4 _2 i/ I6 H$ l. m- I
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    ! \/ C+ s  m( h8 A; _#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40# c( S0 X* w( j1 P' V# a: S0 b

    ( c5 N3 t0 {* q% U: {3 r. _" L+ f/* response to errors when freeing memory */1 F- O/ {9 g) H( H6 V

    7 ^& M" d9 g& [6 c; ~: p#define MEM_BLOCK_ERROR_LOG_FLAG        0x80" \4 s7 D0 L. q0 j* G' T. O5 d7 ~% z
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    1 h9 Y! @1 ], E1 l- k7 s) q
    ! G) x' c* j  j# [2 w% E" y#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))3 ^5 F  ?+ X5 ^+ ?! X0 E4 V, i, n+ m
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)7 ~/ a6 n$ K$ Y

    6 Z) r4 H( S1 O#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))$ J, Y( B+ r) e" z/ W: f
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \5 c" V4 |6 b3 t9 t% I" h/ y5 V; t. O
                                                    sizeof(BLOCK_HDR))), I) k- M! V, R' g! ~0 ?* M2 ~1 X( F
    $ }: s- ~+ R1 W* |1 U8 M  H. m
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    # p: r+ d% x4 L4 I#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \$ ~' c$ n* Z. l" B0 H( W
                                                    OFFSET (FREE_BLOCK, node)))/ H# B! r, @$ r
    ' R1 `6 r4 e9 ?9 M/ K
    static BOOL memPartLibInstalled = FALSE;& {0 G* J; T: ^* @( ~
    + s6 `8 r4 g% b7 [
    static OBJ_CLASS memPartClass;, b. R. _7 O* Q* w4 ]% q3 j
    CLASS_ID memPartClassId = &memPartClass;( ?6 X3 @- W2 U2 W3 l

    / x8 E1 v4 C( c1 i, |; Y/ W* a5 wstatic PARTITION memSysPartition;$ o; B. B, z# r" Z) |# p6 U: H
    PART_ID memSysPartId = &memSysPartition;' a. P. [% D7 |' K0 x/ y
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;0 t. T  A& n, v/ ]
    / o% ~; p' e# Y5 f+ P9 D+ K' o
    static SEMAPHORE semMemSysPartition;, j& E! ]+ q2 ?1 f
    & L' Z. a3 ?, g
    static void memPartSemInit(PART_ID partId);. G. d+ u2 O1 G% D. R
    ( A+ b( N4 a2 \8 \
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;: C" r; e% }( |( K5 r
    3 ?! g* _' ?% I' ?* `7 g) u* v
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;9 O' S7 a5 F1 [

    , n# k2 }7 Y* @* Ystatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    6 @& j" G1 {* @( Z  gstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId! G$ p/ ~8 B. ?$ U
            , FAST BLOCK_HDR* pHdr
    ( Y1 k- R9 X+ s" t- O+ P        , FAST unsigned nWords
    % Z; X7 J' Q; J; U  X        , unsigned minWords0 V/ L; v  K. _5 U" H7 R/ |  J
            , unsigned align);
    ( ]% P( B+ C  T) K
    6 ]$ r# w( O' J1 k& f* a& M: Bstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    1 I' k* M( g5 j( B- T$ w7 A  w2 x4 S8 e7 O4 `' e( {4 Z
    STATUS memPartLibInit(char* pPool, unsigned poolSize)
    9 I' s1 P% v' p$ @5 y4 |{
    9 q- }! D2 K5 k' k$ `        if((!memPartLibInstalled) &&
    % V" N8 \6 @6 A$ e6 V                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    . X" _& P8 T. @8 v* I2 ^5 H                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    . p9 P6 _. ?# ]& R' x. H        {1 N; d. s2 m1 N0 o! X4 ^2 N
                    memPartInit(&memSysPartition, pPool, poolSize);
    - M2 f4 b8 L* m! z& A                memPartLibInstalled = TRUE;& r1 r) a$ r  d1 h+ V8 B
            }8 S- q1 H7 e' r6 ?/ i5 O
    ' q3 O. p5 w( c9 t: `" h5 l0 t5 C
            return ((memPartLibInstalled)? OK : ERROR);
    + \2 r7 z2 ]2 Y# k4 f}2 }6 N3 V, Q' L/ f+ Y2 ~
    - B% n. o5 c0 ]; n1 ?* g
    PART_ID memPartCreate(char* pPool, unsigned poolSize)& f9 h' o9 I) Z; N; ~) S" @
    {
    / d" p, o* S) \3 r8 ?        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);; Q) O" r! [) p  {2 \2 Y6 J4 I8 T
    2 T8 s3 t9 _, y+ @& Y5 W! B/ v
            if(NULL != pPart)
    / C1 \2 Y: H+ d) S        {: g8 M( Q% Q9 C, }( Z3 D
                    memPartInit(pPart, pPool, poolSize);5 E8 V' K8 d9 K3 [
            }$ @( Y4 i. S" R+ B5 }

    $ R: k8 s3 z& L; Q  U        return pPart;2 l4 O0 A  T6 U- l- g# P
    }
    9 p3 R5 @( _, u
    7 D& U' p% Z" y0 I2 fvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    4 G3 ^$ p& c6 [9 I{
    * e1 B! u" h! W9 o        memset((void*)partId, 0, sizeof(*partId));) K' d5 m% @0 I% N, c$ I$ x

    9 i! ]' Y' p) }3 c        partId->options = memPartDefaultOption;
    - B" x0 w. \% c' i        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */  o2 p) E$ C5 [  \7 Y+ |1 j: G

    0 b# l) `) }) u( q. `: o9 M        (* memPartSemInitRtn) (partId);; [& r% R0 _$ h% \7 P& C  ~
           
    . p  z& ], ]- w  |1 q5 b# q        dllInit(&partId->freeList);+ K3 C' N) ^* X3 ^+ G" R0 h# l
              K4 W; u) M/ g5 R1 U
            objCoreInit(&partId->objCore, memPartClassId);
    # V( j; l8 e  l0 U3 H2 U        6 e/ G: E$ T8 J* M8 ]2 P7 q& ?
            memPartAddToPool(partId, pPool, poolSize);5 u, v. Y  |! Y+ G0 j& `
    }; [5 Y/ L! F5 y; R8 f
    , |) ]6 [& J% _' R, [1 \) x4 i
    STATUS memPartDestroy(PART_ID partId)
    " A9 `  r' c& ~, |{5 w* C5 z9 P" m
            return (ERROR);; y: F0 R1 w8 }, c
    }
    ' w" @* K6 ~9 D. J# q' V& R: y! J) w, X, h* T
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)4 x; H9 P* l7 F( n" `
    {! {( j" [# n8 j  p. Q, F$ f
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    % b9 @  s" p1 M}, G9 V- S6 H2 N/ C; x5 u" F

    9 D  p$ f1 k0 Q) o
    + `5 G: V6 g8 p5 ?1 I! r3 K8 ^* L3 Istatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)2 f. J( m. @* m9 _" U( E( G2 I6 f
    {
    + A0 X1 C1 }7 i; a        BLOCK_HDR* pHdrStart;* r! \" ^6 M: \( N6 J' H: u! L
            BLOCK_HDR* pHdrMid;9 z  Z* J! p1 E% U& \# N* b% @
            BLOCK_HDR* pHdrEnd;- S  [9 V. Y" R/ j- h( T  l- c# E) }
            char* tmp;
    ) z1 r: d8 D) r9 k        int reducePool;6 F. ?% t8 M* e% ]" @$ p6 p2 g0 ~

    & q8 W! A7 c$ d. g8 D        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    # n; Q( [# A5 d7 W5 i2 }        {, I. o( U2 K* U! H) v  W7 v& ~! f; A. I
                    return (ERROR);, O3 V, y5 j/ P$ o- M/ F
            }' j4 S8 e  Q; i1 e& g0 F. x; e
    3 [7 ^5 M9 a9 ^! a* y
            tmp = (char*) MEM_ROUND_UP(pPool);' D2 y+ a& ]' S) m
            reducePool = tmp - pPool;& h* Q) s0 N4 q1 E+ }& W' h6 s

    3 n5 e  W7 s; q7 T0 f6 a        /* adjust the lenght */
    ( n/ W2 ^4 r; H' k1 @        if(poolSize >= reducePool)
    : }3 K( \6 I8 M% o- [        {
    ' k# V+ b5 z& Q  m& \) f" P7 d                poolSize -= reducePool;
    % |  V) I' a( r# W; r        }
    5 N$ S: L/ }8 y- V! i" f        else* ?3 R4 c0 f) p6 t# j( C' h
            {
    " `. l4 V2 t$ `                poolSize = 0;3 M+ g+ [- |% t; w5 i
            }- \& @0 F$ v- J* K+ k# e! c
            pPool = tmp;" \# `5 r* V% w, W& @% L! P  b
            + z! f4 ^" Q4 _9 o- n
            poolSize = MEM_ROUND_DOWN(poolSize);7 b$ ^, Z2 }0 a* ^# n. C3 x
            5 J+ p- z/ D7 s
            /* at least one valid free block and three header blocks */
    * r9 m, L4 f+ b4 \2 X0 {0 o        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    9 M4 u2 l; X1 p        {, O$ U$ Z: {1 B* M# ~  `
                    return (ERROR);
    " X/ H* B. t- N        }
    / F, a  k! N. [! w( `* b
      d& `0 V2 ^2 F6 u2 E        /* initialize three blocks */3 h# E; b+ F3 c
            pHdrStart = (BLOCK_HDR*)pPool;9 H: A' U0 ^/ d1 v/ |+ |
            pHdrStart->prevHdr = NULL;& r% G& V8 ^7 j4 U& y% s
            pHdrStart->free = FALSE;                /* never in use */& X, n! E* }, D
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    $ k& y6 c' g$ Z4 u& K8 A% x' H( y2 n& w, c  @  d( V& D+ |
            pHdrMid = NEXT_HDR(pHdrStart);% I2 c" c; M3 u( Q, |6 C
            pHdrMid->prevHdr = pHdrStart;, U) `0 v* ]) O3 ~3 [# l6 ^
            pHdrMid->free = TRUE;                        /* the main block */7 W( d4 @) d. G2 l8 L$ U" T& i2 b
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    8 u  j- T9 K% U) ^8 K; s
    # |! T( H7 g0 w; ]' h. c. F( d( M        pHdrEnd = NEXT_HDR(pHdrMid);. e7 u5 g. @. T* F& ~3 W
            pHdrEnd->prevHdr = pHdrMid;0 p, a- h3 F/ E0 D  z( [: B2 S
            pHdrEnd->free = FALSE;1 r$ q8 Q2 a& {6 U$ s! w$ Q0 n
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    ) q3 j( c0 w- V
    1 E) `: b  s. U! }7 e        /* TODO take sem hear *// y$ C4 f$ [/ Y. ~' w5 J
            semTake(partId->semPartId, WAIT_FOREVER);; ]& U9 a% j3 O6 K7 k9 w
           
    2 J7 d# o2 j- i9 m        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));+ o. Y- X1 w4 V+ F
            partId->totalWords += (poolSize >> 1);
    9 C. g6 D/ a2 u8 ~" O$ \; X9 G: t( |" y+ X
            /* TODO give sem hear */. E( w% V$ U2 ?3 p2 P- d
            semGive(partId->semPartId);
    5 [  r- q; K! h" A2 ~- Y2 t* _8 h* z$ A/ X; f; O7 x
    ; |) u# z9 [) ?
            return (OK);
    . u; J5 b" C3 J( b# I}+ K5 V: y* p/ v0 s2 q6 I
    5 r% y2 u" L8 e' T' L$ H9 Q: O
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)9 j( r/ ?: z$ j0 U: p& Q8 o
    {6 {1 K& J7 {! }) w3 G: s
            FAST unsigned nWords;6 p3 _+ P( i# W0 G9 K0 ]
            FAST unsigned nWordsExtra;
    8 f) ^7 M, r7 s6 p! O% S% J        FAST DL_NODE* pNode;& }! @: I0 d+ U; ~
            FAST BLOCK_HDR* pHdr;
    * T( ^# R2 E! `! c3 `* q        BLOCK_HDR* pNewHdr;2 B9 }1 t7 W9 `
            BLOCK_HDR* origpHdr;6 R$ H1 Q3 N7 A# K6 c/ u
    - W- A( p* f) ]
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */& P# K% B3 o+ o# H1 n' E) q+ g( H
            {
    4 p. r2 Q/ M! g, X# L                return (NULL);- M8 D: t& U, O$ A' G
            }
    0 r; O3 \) v' {* K. T: }) b0 m# u. O9 ~  a$ R1 }
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! g! Z2 _' \5 L7 H

    ) M6 u* `. W- p  T        if((nWords<<1) < nBytes)) V2 ]8 c8 M4 c9 {3 P0 o* G7 q
            {  p5 h8 X/ z( @8 E6 F
                    /* TODO suspend the task */" b9 x) m* m7 c4 b
                    return (NULL);2 Q% {; o+ x. x& p8 s
            }
    ' }7 _& _3 {+ C0 a* K; }: e- T% ]! Y. w$ B3 a! s2 a5 O5 ]
            if(nWords < partId->minBlockWords)
      S% V* M) \: J$ N2 [. a) [        {) V( W4 x' r0 b* E2 S- V
                    nWords = partId->minBlockWords;
    " K/ l7 P0 V! t* ?) s, l        }
    9 Q7 i5 t6 `# g6 k7 M3 H, S$ H9 U2 D& |3 [1 ]( G: x
            /* TODO task the semaphore hear */
    / O% S" o5 U; w3 H* d8 w( d0 e        semTake(partId->semPartId, WAIT_FOREVER);- F- M5 ~" X% e3 g
            pNode = DLL_FIRST(&partId->freeList);$ t% a+ r7 \/ M7 s
            nWordsExtra = nWords + align/2; /* why? */. r6 d/ r1 r; t% Z- q9 ^+ y
    5 F* E2 _& w$ b6 H4 u8 ]
            for(;;)) M% k! L3 y3 Z
            {
    6 b% a! w  L4 ]. p" X4 U+ _                while(NULL != pNode)
    7 f; ~: Y, f8 `+ T( p' J5 p4 h                {8 e0 v8 k3 G; O0 L
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    4 a3 c, [/ z( B; @- Z8 G                                ((NODE_TO_HDR(pNode)->nWords == nWords) && & f9 C& z! u0 U" t& G
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))3 F: _! z8 n( L& S
                            {
      \; G1 Q- N# w, F. G2 T: t& a                                break;% l- V2 F) C8 j8 Y/ o
                            }
    # o9 B* E0 Y( |6 [# H
    . w) u, N0 n) @7 P% X                        pNode = DLL_NEXT(pNode);
    ( U# z* f2 U" v( _                }
    9 J5 A* T* R* h, N2 c
    - v  ?% u) o  d! ~. O; ~' ~                if(NULL == pNode)
    " Z# n' j7 u& G1 C$ x                {# x: T1 ?  M- F! w2 e  Z
                            /*TODO give the semaphore */0 }- [" @) H* U0 C' S8 F2 Y
                            semGive(partId->semPartId);& B# B( v* ~. C8 W' k: z- E9 i
                            return NULL;
    8 X, C4 m' q2 O& ?# x: X& n, L                }
    ! Z3 B' F0 Q+ x8 |0 T+ a
    # S" c) C: ^& d3 a  M                pHdr = NODE_TO_HDR(pNode);
    8 z1 s" n, S( j1 l: ]/ Z' ?1 i                origpHdr = pHdr;# B; |2 x- U6 U
    : ~2 X% W  Y( z5 X) _
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    3 ^7 S- ?, C+ P6 K8 e6 ?( n/ ~                if(NULL != pNewHdr), a" z( m! o# ~1 X- }9 F1 {
                    {; C. z; z+ U8 C6 Z) }
                            pHdr = pNewHdr;3 r; s6 q8 @! j6 C! e7 h' f
                            break;3 [/ d) K8 e; {9 F) j  E+ N" e
                    }
    % O, A7 h( O4 @( \! |! k
    + }7 y2 ^3 B* M8 _( E* V: U% p                pNode = DLL_NEXT(pNode);7 h, k8 W$ `) l6 w8 p. z  |0 S- o
            }# R9 [4 g: `3 n' z) P4 p
    5 E; z3 N4 _' R1 A5 D
            pHdr->free = FALSE;
    & c+ e" [" a7 h. O. V        partId->allBlocksAlloc++;
    ( f' ^- A( ~, @. S0 R  x/ C" z        partId->allWordsAlloc += pHdr->nWords;# S8 j- N( A* P# p" W
            partId->curBlocksAlloc++;
    * ]* N- @8 G6 T% U) p$ p/ i3 z        partId->curWordsAlloc += pHdr->nWords;3 Q' C; w4 m$ v3 Y+ ~' E- Y

    % D; ?7 p1 E' k5 X+ Q        /*TODO give the  semaphore hear */: B: [4 r+ O% b) e9 w" }
            semGive(partId->semPartId);
    9 Y2 R5 r( \% e& `        return (HDR_TO_BLOCK(pHdr));
    # F+ R$ L7 a$ i) Z7 \2 S! Y( I       
    8 j6 T0 b8 E5 `1 y! l3 q}
    1 r+ o) v& R- S8 w# X  C; Z) [* n" W8 z- @, Y# w9 C3 L- a
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    3 i6 E9 ^* O& `! Z0 y  Y' |0 A' u{' r6 K8 p$ C9 m. m* K5 s
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    1 N& j+ f  @3 N4 ^+ G}
    ) \- @8 b) P$ r9 V& ]  ^) I7 H' d5 |
    STATUS memPartFree(PART_ID partId, char* pBlock)
    ( _, u1 u1 S0 h7 ]* M) f{
    ; u$ d3 E) b4 c: ?- [9 |        FAST BLOCK_HDR *pHdr;  ~5 S% A, M9 Q5 D* J$ `3 {
        FAST unsigned   nWords;' N7 A3 [/ m" a) B
        FAST BLOCK_HDR *pNextHdr;9 s3 c+ Z4 ^$ I: J8 J

    4 C& o7 B' e; V8 D9 E+ R7 t        if(!IS_CLASS(partId, memPartClassId)): I. X6 s9 {/ X
            {
    ' b3 ^1 ?- D/ X4 ]6 Q) q4 N                return (ERROR);+ U: d) F" R& @, l% N4 {* o
            }) s; ?% T  r% a. ^* y
    ) W5 B+ j! F) F; ~4 q
            if(NULL == pBlock)7 T# ~0 a) [, H' h5 U
            {' {7 E: a2 Y3 ]6 b2 }
                    return (OK);
    2 Y8 X; T# X: F1 O  S        }& b; b7 L% \8 y' p- s
    1 I( g7 s6 O% b3 [: a2 h( ~- }4 s
            pHdr =  BLOCK_TO_HDR(pBlock);
    $ B. o1 V: N% P9 h( s: `! q) v8 r8 E4 d1 {+ T* H. ?) X% j
            semTake(partId->semPartId, WAIT_FOREVER);; ~) {2 A. O% R: \

    - g4 L" ~8 \( ^  a3 s        if((partId->options & MEM_BLOCK_CHECK)
    ; i/ o9 j2 v  f: p' L) F! D9 a                && !memPartBlockIsValid(partId, pHdr, FALSE))* Z8 v* f7 M+ \& H% y, W
            {
    0 y3 o* f5 ?0 Q1 x+ _( I                semGive(partId->semPartId);
    2 I. Y/ m7 a7 x! p                return (ERROR);
      {0 e7 l& u2 R; L1 h( a7 t        }3 H- [# o' W+ T8 o5 T+ _
    . m4 l, ]; C1 m8 d" Y0 h, u
            nWords = pHdr->nWords;
    1 S% P. e+ N- o4 |0 k        if(PREV_HDR(pHdr)->free)1 ~* C/ B1 ^: w0 {3 l& e
            {/* the prev hdr is free and than coalesce with it */( i( o( R5 i8 Y  g  v
                    pHdr->free = FALSE;
    ; {8 l7 Q3 |# G. T4 G0 H( ?; R6 y- j                pHdr = PREV_HDR(pHdr);
    ) [; x5 y* i0 F. V' ^) N! k                pHdr->nWords += nWords;
      |0 T4 l2 H! P: P0 m        }
    ( r7 ^0 u; w  G# V, B5 _+ K        else
    , |4 S$ S) r( R        {
    / ?# ?6 [# I& t& q& l                pHdr->free = TRUE;
    9 W- N) ~& _0 p% \  I                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));: S/ @" r0 ^# ?
            }: _' A- f  v, x
    + s2 R' n# J1 H+ X& N( G. l
            /* check to coalesce with the next */' j6 g9 y9 `+ U! r9 x6 Z0 Q
            pNextHdr = NEXT_HDR(pHdr);$ y9 b( u; |) G; |. O
            if(pNextHdr->free)4 d4 R9 E; \3 ^0 A
            {
    5 h7 c" [# {' t; B                pHdr->nWords += pNextHdr->nWords;
    4 K& j2 j* l. C1 J( R- e                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    - z. _4 h" N) ~7 I        }  ]4 \' J) T- B: `$ v0 X
    * q1 n# p5 S, m! v
            /* cannot use pNextHdr->prevHdr=pHdr hear */3 G5 `# v1 K6 L% t
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    4 ?5 f/ C" I/ ~) K& n( E# p  v+ p* g4 h. s
            partId->curBlocksAlloc--;% f; b6 W% @+ m* _0 P
            partId->curWordsAlloc -= nWords;
    % F- G7 B, b9 b# w, c9 H. @
    2 u2 \: W* F! j+ n( J8 Q        /* TODO give sem hear */
    2 q6 }) ^) S' [; M" h% e' I& X        semGive(partId->semPartId);1 m4 U5 I' F1 T. F" r8 Y% {
           
    : G0 P9 x$ K3 K  V3 L# c9 p        return (OK);
    2 K; @( u5 X/ p/ U$ F4 b}& r# x) j& Z9 f4 g

      ~# o- Y2 J& F( astatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    : Y7 m# x: S' f& g{
    $ Y" g3 k( E3 n1 z) h" E        BOOL valid;
    7 a# R$ g( ^# _6 N* O
    8 ^3 @4 l0 [! f# T2 |        TASK_LOCK();
    3 \3 q0 d6 j/ D9 P; ?" S, u  u: y        semGive(partId->semPartId);1 g7 m6 R  i: l9 V3 t
            " d7 T; P& s' v; \  o) D8 n
            valid = MEM_ALIGNED(pHdr)
    ) m0 Q  {* ^/ ]5 a: s0 A% W        && MEM_ALIGNED(pHdr->nWords*2)7 q: [$ v9 J# e( h# U" Q' W
            && (pHdr->nWords < partId->totalWords) * b% K- l3 ?1 [8 `
            && (pHdr->free == isFree)- ~1 G# i, v& m" y$ V
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    ' d: r$ ^8 m! Q- t# L7 T1 u        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));# G' |, z8 j  {6 q7 F  K
            1 m* V; o' H" d5 y  A
            semTake(partId->semPartId, WAIT_FOREVER);8 _9 M: ]* P' ^* A; n' u- W
            TASK_UNLOCK();
    % g0 E* W+ B" u. r/ w: L/ e
    & t$ X# M7 ?. f' n, b+ F        return valid;( M& N4 ]$ M. o# F
    }6 ]- |! W7 l0 }% Q/ h
    , F$ F! Y( L1 a
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId6 R- K) Z& x7 U  H9 y" _
            , FAST BLOCK_HDR* pHdr. D) [. v; H' e' {! }* L! U
            , FAST unsigned nWords
      a7 c" x6 T8 R1 p; @; }3 d! |7 a, i        , unsigned minWords) d! ]% F, W/ A- j3 X) E& w  G
            , unsigned align)0 H( \+ }# c4 n* |+ T
    {
    , l, U& d+ J0 W% x8 z! H/ [. d' g' o        FAST BLOCK_HDR *pNewHdr;
    + H" H* x; V2 A/ `) x( @    FAST BLOCK_HDR *pNextHdr;
    " R, X* G8 g4 L) f- i    FAST char *endOfBlock;. ~  ^% |0 c  K4 D% ~% p! J- o
        FAST char *pNewBlock;9 j' }$ A* n8 S' N
        int blockSize;
    7 p& r: B& L. v. d+ V
    + y7 `; X. l+ p# W/ ?9 v        endOfBlock = (char*)pHdr + (pHdr->nWords*2);3 l; R; Y# u7 \  X6 ^& t
    # h' Y2 g. `) L  Q
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    " u5 d2 b5 ^/ H9 Z% X9 r
    9 x1 o2 i. @2 f        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));: E- Z+ x% y) W  t& `; [- w3 x

    & P5 [0 |2 J5 M& ?& Z. d        pNewHdr = BLOCK_TO_HDR(pNewBlock);# `) I# R; |$ H9 P. r* t/ N
    + i6 P7 b, Z& X5 A
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    ( ?- D$ r% t% c$ i$ t1 E; l7 T0 X
    ' t' E% d5 c4 ]' w' b        if(blockSize < minWords)
    3 x/ g: w/ M/ x$ y! o% u        {8 c! T& }5 d( a% m
                    if(pNewHdr == pHdr)6 _4 e0 l: q) v  P
                    {2 n7 T7 S- G' L9 z4 u# ]
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));/ I9 W4 f9 o" {1 ?3 i# x
                    }+ W9 I7 \, k* f/ Z" L" Q. K# @
                    else
    , J+ {3 M' Z5 _9 E" ]* b' w                {; p2 E3 C8 N; B6 g3 V2 h* t
                            return NULL;4 }7 k& z3 c% c: q+ z- L" s
                    }
    6 P6 Z3 b# e0 G, u; V6 N        }4 A( z9 `6 q8 G: @9 v
            else
    : ]( P7 X1 J; o4 }) x  X        {        /* recaculate pHdr */
    ) n5 F' U* ~6 b+ U" V                pNewHdr->prevHdr = pHdr;
    0 j' k( O0 [7 l; b3 ]  ?3 F# q* I                pHdr->nWords = blockSize;
    . ]. G: b' F4 D" V) L: Q        }1 V" C$ I) D: f2 s: p9 V

    2 C: o; p4 e6 _  P' }        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    1 X- z( Y3 b7 o/ e        {
    $ p3 M. I7 L. E" `/ W+ }                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    ' D& j" G. h( R3 q. B; ~                pNewHdr->free = TRUE;
    5 V' q( @% d) F4 D* _/ S* u5 H/ Y5 p" d3 ?  i
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    $ I! K4 M* {( j1 G- f; o6 ^        }
    6 W- b# \+ S  G        else5 z3 |! ^( ~# p- ~) z
            {/* space left is enough to be a fragment on the free list then */
    ; W. ^& k. _( c" H, U                pNewHdr->nWords = nWords;0 {0 [; V" |1 c+ W3 _
                    pNewHdr->free = TRUE;
    1 q2 B5 d5 V* V
    0 |5 W! Y  ]9 j" J& {                pNextHdr = NEXT_HDR(pNewHdr);
    : v7 k# j8 f# v8 }. o/ Q2 @                /* words 包括BlockHdr */4 k5 X5 B# i- R1 i/ a2 B1 v' L
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;  }; N# B8 s6 {' f( Y4 k
                    pNextHdr->prevHdr = pNewHdr;
    + V8 E" }" B6 R' X" d                pNextHdr->free = TRUE;1 ^; Y4 w( u  B3 s
    ! A8 d7 ?/ \/ m: g5 n6 {( g9 z
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));! l" b  T" Z1 f) Q% A- t
      q  M1 G' ^2 X' [9 M  l" y
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;- M; F7 m( k* \4 o! F9 D
            }8 o) e7 F- u( y1 S

    8 b3 r; e" p4 e4 W4 t6 @# F        return (pNewHdr);, l$ W, J* O: a0 R  _) y) I2 e
    }
    & O. Y+ i  x5 D+ l( F8 [) p1 O) [4 x1 A7 ^2 C/ u1 C& P
    static void memPartSemInit(PART_ID partId)
    6 X4 m' m2 {( j  c. q5 q* i{1 Z6 s! S8 x. m7 D/ w5 t; U
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);( c. ~+ N1 q- |( [4 o
    8 |) n9 X, A) R( _' U7 o" G- j
            partId->semPartId = &semMemSysPartition;: c2 f( g2 C8 ^' z, C  T
    }
    3 K6 t9 O4 S$ C) C+ W" f) Z. B) s) v
    - m5 I5 l! j1 ~9 |% p- z7 r/ jvoid* malloc(unsigned bytes)
    9 D3 w% t* i  N{" D' Z8 i5 `/ J3 b1 B6 n& J
            return memPartAlloc(memSysPartId, bytes);* D& \- o- `- r# Z$ t  e
    }/ h6 O5 w4 ^; A6 I( P
    ( X5 W$ k; }. D) W( F& E& o
    void free(void* p)
    3 r* k/ e$ I- g& U{
    4 [7 l- _% X, @% `* N' F) v        memPartFree(memSysPartId, (char*)p);( \5 _& Z9 m7 a
    }/ r+ _3 u, D, d$ Q8 q/ h& a
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-9-3 07:52 , Processed in 0.374730 second(s), 51 queries .

    回顶部