QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2901|回复: 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++下的版本,更方便调试。有需要请留言
    2 [5 i0 c  R% @: @6 M, Z* O5 Z8 _+ _& J5 v. q& D) K
    4 m2 J5 J3 R$ @
    2 m- Q# m2 P+ \$ m3 |! {  n$ E; B
    *\file" |3 o( b8 O3 K7 c5 U- [' T  ?
    *\brief                9 y) f6 i5 I& S9 D
    *\details        7 y5 `* c6 {8 J8 E
    *  g% P- L7 j/ V* W+ S
    *\author        Janson
    ! {  A6 y" e- Z( s. Q( \& {/ g *\version       
    9 W+ b2 V2 N- \* }: i *\date                04Jan12: k+ G, {8 u( H+ Z( b6 I# u
    *& ~; r- t6 X2 D
    *\warning       
    % i" i- p/ |5 e1 F2 _ *
    # }8 E+ t9 Z- Z$ A *\history \arg        30Jan12, Janson, Create the file' Y! V" h4 _# Z: G; I( J0 w
    *        modify from VxWorks source1 R+ D0 R. N" K
    *  Legal Declaration: it is for studying VxWorks only.
    / \* F" m! z7 m9 {/ @/ w */6 N, k0 n1 \: ~1 R
    #include "includes.h"
    & o& w# U5 @  O( n) c+ d: }" ~* j: V' M- z. j2 F6 e% h
    /* The memParLib.h file is hear:% S2 N2 o$ P1 `) C1 |& L" J
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    / b( f2 b0 m6 h4 k! @*/( e1 \( j3 o  H; ^+ o
    ; w' I& T8 |2 \. Z2 r4 d$ t- Q
    /* optional check for bad blocks */
    ! d& \, [, k. v6 E+ Q) X
      E- L8 Q9 x! H#define MEM_BLOCK_CHECK                        0x10* j( |8 c& ?" X% K" O5 o
    $ T+ }- m! w, |8 x0 z6 X  D
    /* response to errors when allocating memory */. n+ \$ X2 w$ `; y0 R! k% s

    , k* G7 H( U7 \; [* |% }#define MEM_ALLOC_ERROR_LOG_FLAG        0x20* Z' j3 u2 z. H0 X$ M& V
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40/ j; U/ F0 E/ I% _
    9 e0 J" o0 ^& h* G  y1 k( s& c
    /* response to errors when freeing memory */
    - E7 r+ l6 `7 F
    6 L" G) Q* |: ~, y) f  w% W#define MEM_BLOCK_ERROR_LOG_FLAG        0x809 T( ^7 I+ {& e1 B
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    ( S( z9 }# v- L$ G4 M. b7 B! l) i, P
    / h' r' w; _9 \+ h! Q1 F#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    + l2 \7 C1 K& i6 t  r8 k  T. s#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    1 F; Y3 X; m( O- T0 ~* P6 Y) B1 C# }+ U' n6 ?
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))' F% Q' @1 Q& i1 }2 N" s
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    . ~/ C( N( X5 A. l                                                sizeof(BLOCK_HDR)))/ ~0 K3 N5 h9 c% Z# f! g: ?; R

    1 P8 H3 O, j( N( h% T6 C6 x: p6 [#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)4 _" Z  x# Q5 J" P8 Q) _9 B, z
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    7 g' `( ^: i" e1 w2 F                                                OFFSET (FREE_BLOCK, node)))4 O6 X9 v( j8 d# [! }# k- z% X
    $ V9 l/ A  q) R# p
    static BOOL memPartLibInstalled = FALSE;
    ; U* W. z0 N6 `$ d6 i' h! C0 E. M! a3 r
    static OBJ_CLASS memPartClass;1 R7 H7 l# P4 d& O) q3 S
    CLASS_ID memPartClassId = &memPartClass;
    - E) `2 W; |9 ]6 Y' H
    ! E9 G1 _# t( l" Nstatic PARTITION memSysPartition;! n! g& P! }5 i% \
    PART_ID memSysPartId = &memSysPartition;6 ^8 z/ L1 i9 z4 E% N
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;4 d9 j6 d2 r; ]; K% b! b
    - _5 L! b; k2 [. b  @! G" }
    static SEMAPHORE semMemSysPartition;
    5 N/ W1 n" x% J' X7 C( J* x
    0 C4 O: D, y- W( Q6 ystatic void memPartSemInit(PART_ID partId);2 L) Q# D% l1 h5 b. }" T

    8 }  L" J& a, x$ r3 \4 WFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    ! P- \  C% M. B8 i
    + ^6 e. F2 y$ d& d2 i3 t( eunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    : R2 H. o1 [! z, g; h! ~5 r9 y$ g' w9 d8 e. F
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    . @$ n3 \) G' D7 X) ^! Lstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    4 l9 L# {1 E; N+ Z2 y0 [        , FAST BLOCK_HDR* pHdr
    3 v3 B, x1 o- o) {9 x& r1 `% Z        , FAST unsigned nWords
    ! h0 _# G2 o6 N! X, m$ W; a5 U        , unsigned minWords
    9 g5 K& o6 U/ n+ I& u& ]        , unsigned align);# G& T# _" x; i; I! f3 r# t+ i
    / D, `/ d. h: i& G
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    " x! {+ A# L" n. C: w4 }+ b/ W: Y: p4 D' y" ^9 [
    STATUS memPartLibInit(char* pPool, unsigned poolSize)9 r' ?0 m7 {; b! {& D) ]
    {
    2 e3 P% G0 q5 G( }        if((!memPartLibInstalled) &&
    ; `5 D: n" X6 [- \                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    7 V- ]: Q& R( r/ Q' \5 D8 X; c# R                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))+ @5 k$ i5 S! _9 s( n
            {
    : L+ s: y1 R* g6 W2 g                memPartInit(&memSysPartition, pPool, poolSize);
    ! \6 ~9 h) |- m/ ^5 o                memPartLibInstalled = TRUE;
    4 `$ y0 [/ G  b+ ?& y) M        }2 O- J4 M& f% e
    : _6 n! y( F- w% `% V
            return ((memPartLibInstalled)? OK : ERROR);' T$ R! s+ C8 M" b% h2 q
    }
    2 w7 S/ |4 a8 E/ I: V
    $ Q& N: n5 s# y( CPART_ID memPartCreate(char* pPool, unsigned poolSize)
    + d! x8 T- {8 G{7 W9 K0 k% x: f& c/ r4 `
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    " q* K1 N- X% _0 i! w) a/ U
    / \" H" Y% R" Y        if(NULL != pPart)
    & r- t# ]- g' P0 k% L        {
    + c0 [; x& w3 P                memPartInit(pPart, pPool, poolSize);
    $ u! U6 ^, w: |; D  s0 |% K' h        }
    2 h3 g0 J1 z1 j
    6 j" T  x9 l; ]( ^) ?. U$ {        return pPart;: d# X5 W  i! n% v3 R% D1 {- ~  S
    }
    " |9 f) s  o3 p" {0 U' Y) A9 l9 K: i! q  c8 w: \3 O' ^
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)5 U" S5 q: a  ~1 I( l
    {
    / ]. L' ~  X$ N4 B$ j( M        memset((void*)partId, 0, sizeof(*partId));
    " V) @7 v: M% u8 g4 K; Y# S- A
    0 [$ h2 i8 }' c, L7 I% ~# j0 z+ Y        partId->options = memPartDefaultOption;
    * T/ c: U* D" {8 j* o2 G) E& Q        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */3 V% D. i( K* [  F

    4 f) p% U- m  q! y3 _, `        (* memPartSemInitRtn) (partId);. N- I; ~6 i: G4 K  g8 j( I
            . I0 R$ r- U/ V
            dllInit(&partId->freeList);, h7 e3 f: x: g: _6 ~5 g( {- T
           
    ( h, u9 W5 C  Q  |: J+ y        objCoreInit(&partId->objCore, memPartClassId);  o& b2 t9 |) C7 ?$ ]; s4 {0 h+ N
            - |1 O9 F, T5 S7 o+ n
            memPartAddToPool(partId, pPool, poolSize);
    ( O7 S0 A. {9 X}5 r' Z6 ^# C* o% Q) y  i0 J

    , q. h- R7 {4 ]: f6 NSTATUS memPartDestroy(PART_ID partId)) \5 k) o! s( n  g5 O
    {
    6 E$ X& j) K. U; U3 y- ?        return (ERROR);6 I2 W8 X4 v9 X9 [, b4 O
    }& N" j; d: v+ W9 F

    / Z* _& W# U# v1 P! C& Kvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    : q" {% [/ x5 H{
    . b9 @/ r0 S! F- s    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);$ H: g6 X; G  H4 |/ N
    }+ `4 \2 E$ Z4 t2 s8 X, Z
    & m1 L' a* Y3 g& C0 r
    & t, Q" z. T; J. X$ {/ \. |; i1 g+ a
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    ! r4 K/ w% _/ T3 B& D{' z/ C" I" W3 \+ {
            BLOCK_HDR* pHdrStart;
      S& \; N; b' k4 |/ M2 z! N        BLOCK_HDR* pHdrMid;
    ! b& c0 o: d. C" z: f        BLOCK_HDR* pHdrEnd;
    5 U' U8 c  M, C  `, l        char* tmp;; @4 x4 I$ p: g' p  a8 @/ T6 k
            int reducePool;  e# B; s7 f2 V% m8 ]

    * }; k1 d. X# |. Y6 T        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */. I7 W! D. {0 b5 N" K$ R- J; b% l6 G
            {8 r& O& }* }& S- f9 t
                    return (ERROR);/ n2 E# L- s1 [. ^( b4 S
            }7 M0 |) P. F6 ?/ E" \) _" L

    / n9 ^6 z% _1 D/ O1 g% L        tmp = (char*) MEM_ROUND_UP(pPool);5 J, E8 E  {: G0 ]5 g  q, q
            reducePool = tmp - pPool;" B# v2 j0 x  t5 F7 H* M
    0 C1 @. `, F% @5 t  d* ?$ P4 j9 N
            /* adjust the lenght */
    5 c+ F# b( I5 ~# p% S/ c        if(poolSize >= reducePool)& t9 @7 Y0 F5 E( _& y
            {
    & v6 q: X" s$ @6 R                poolSize -= reducePool;
    9 {/ r3 u  K8 J& g# R" z6 @5 x; O& a& ~) C7 M        }
    6 V9 [) j1 J# V% x        else4 z. r5 X9 H9 b  o' R$ l- T0 g* J
            {; E+ {$ X3 g; Q( d7 E/ e, V
                    poolSize = 0;
    7 x  @% t4 L7 |        }3 v! Y! ?2 A5 o% _0 _
            pPool = tmp;( F5 z* x9 M* w1 T7 ~4 j  T& K( F
           
    5 X) G% V8 ~* R0 {1 _/ W        poolSize = MEM_ROUND_DOWN(poolSize);# a0 C+ H$ I  Z9 G! D
           
    + J* I6 A9 X& Q; v. A        /* at least one valid free block and three header blocks */
    $ n3 @- F* K, w, t# ~        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)1 b& k" P; M# f8 y" Q
            {0 x. H* ?& o4 d+ Q
                    return (ERROR);/ Y( |8 Y' c+ e
            }2 O- G3 d* j# i+ _7 {# m) h. F9 }2 A

    0 c4 O9 S" ?/ _        /* initialize three blocks *// g' F5 h8 K' x' R4 q" K( S6 ?
            pHdrStart = (BLOCK_HDR*)pPool;$ W5 r( E! q, D/ @
            pHdrStart->prevHdr = NULL;4 G. j, C- t1 Z3 Q6 M  x
            pHdrStart->free = FALSE;                /* never in use */
    0 F1 M  u0 _; Q! t+ y        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;4 A! G& O1 e; ^/ j  `
      ?  R& e5 I' N+ z9 Q2 r
            pHdrMid = NEXT_HDR(pHdrStart);/ q: I1 h! P5 ^, t
            pHdrMid->prevHdr = pHdrStart;  P1 D/ M! f  Z/ q" i! G
            pHdrMid->free = TRUE;                        /* the main block */9 ^) W- v3 B0 B, C6 N
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;$ ]. p! K$ X' m4 ?

    : z$ J: Y$ a3 J+ T        pHdrEnd = NEXT_HDR(pHdrMid);
    7 ^6 `+ y/ V! k6 n        pHdrEnd->prevHdr = pHdrMid;/ D0 w/ a! s% `+ j8 W* C+ D
            pHdrEnd->free = FALSE;
    5 O$ s. s% @$ T2 A, c$ I        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;5 @* l; W6 N* u1 I; @: ]

    2 I; Y* }- h, ]        /* TODO take sem hear */
    6 [5 I. ^+ O3 \- `& y+ _# A, y( S        semTake(partId->semPartId, WAIT_FOREVER);: n& ^* }& z7 p. S  o. t, V
            / D, g3 p7 z( ~8 Z2 o: \3 P* \2 z
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));$ D4 E- e3 l# p: s# n: j
            partId->totalWords += (poolSize >> 1);
    6 w0 I1 Q8 v6 P& f0 D. K2 z: ]  y2 Z' }/ s/ c
            /* TODO give sem hear */* `3 n' N* _1 ?- c6 Q/ t
            semGive(partId->semPartId);
    ' N0 ?8 a2 k- S6 A/ R4 i% Z' H. g9 `" O; C5 |; \4 h3 p

    8 {; j0 h+ U! F+ p0 u: _        return (OK);! N2 Z3 }5 e2 W4 Y0 n; V4 A0 v
    }
    # W( ^7 W1 [. c" `. p  ~0 S* J3 Z1 X
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    4 q3 N2 O  _8 P4 u6 g! \! u{
    , `2 Q2 x/ Y% U' ]7 R        FAST unsigned nWords;
    2 t2 d* D0 J) h9 Q/ r& s4 k        FAST unsigned nWordsExtra;* F5 r% z( x+ x7 s: j4 |
            FAST DL_NODE* pNode;
    . j" H4 m9 L% y& M        FAST BLOCK_HDR* pHdr;
    3 O* S( A7 O& a* `        BLOCK_HDR* pNewHdr;
    & F0 i- i1 Z" _: R        BLOCK_HDR* origpHdr;
    $ p- ?6 O0 i7 Y$ _8 R4 D7 c7 x, A7 k$ ~/ w
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    2 @4 |, q8 P3 C. W' j8 ], H& [2 f        {# ]5 S" _, B: m; A
                    return (NULL);! l; B: p. K$ W  n. M- B8 {
            }8 _* ]( f& C0 Q
    % I$ s' k( c2 Y
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;6 E' ~, B! e% E

    ( }7 \/ U- J* y+ |/ N1 Q( B- L( Z        if((nWords<<1) < nBytes)
      }! F5 F7 T1 `0 y2 d2 K. Z( ?+ R        {
    7 D. o+ Z& }0 D* s6 S& d" Z                /* TODO suspend the task */
    6 f, B( \. `: M4 O" B" k6 b                return (NULL);
    % M/ H' q' M3 ]( t7 o; ?( V& G        }
    ( K1 L; E4 ]7 g( V% S
    " m- |% m; Z6 i( |5 H# J) a9 o        if(nWords < partId->minBlockWords)" }& N3 L+ X# v/ r
            {
    ' y( S+ v9 s1 T                nWords = partId->minBlockWords;
      k% g; j; w- l6 ?  L( d+ v        }
    / b6 s$ y" N0 z% R6 Y# {+ O. `  ?5 a9 n# V0 P- B
            /* TODO task the semaphore hear */6 S: N3 ], p+ j' k0 C$ f
            semTake(partId->semPartId, WAIT_FOREVER);
    8 C7 \( K' [4 O        pNode = DLL_FIRST(&partId->freeList);) M- }( E+ `6 L% v; s6 _
            nWordsExtra = nWords + align/2; /* why? */
    ( B4 ?' S; u9 |9 y) s; Y, _4 j' q4 ]& A3 p0 g% I
            for(;;)2 V. }1 Z$ E) _! N. @# y2 K; K
            {
    5 [# Z- k4 f' q1 ?9 }6 V                while(NULL != pNode)0 M  N: A8 x0 i: K" V1 F$ C; H
                    {; g& {9 i+ m) |: q
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    . M* ]; }+ w) N' n8 q7 X* E                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    $ k( a" u- [$ O$ ~4 Q8 a                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    ) [" F& x8 Z" |                        {# b% j8 J: P* ^% i8 n! V1 T3 w, h
                                    break;
    8 l  J% g  _3 q- c8 }. K. a                        }; P6 c# b, J+ g+ I- ~7 t7 e7 P
    ; V! ~5 Z& r$ Q* C1 w: w
                            pNode = DLL_NEXT(pNode);7 V, Y  O9 t' @* {! l' [, m: h
                    }
    " |8 r4 f9 Y) v# Y" ?  [1 F" }" Z/ M
    5 y+ ?# I1 e9 u& M+ y0 o5 p                if(NULL == pNode)7 v/ h  {& b5 g1 ~7 k0 i3 T8 e! x) I
                    {- o% j- o& J0 c% ^8 {6 O& `/ r
                            /*TODO give the semaphore */: z6 R  C0 R$ t/ j( E  I4 b$ r
                            semGive(partId->semPartId);' f# `! s( M  a% }! i+ M
                            return NULL;
    + Z3 |: ~: H' J8 B                }
    : @% |/ \" j8 e, b' Q, V% S  P8 N+ h5 O
                    pHdr = NODE_TO_HDR(pNode);- M& {3 m' v, v; i' m, }5 X
                    origpHdr = pHdr;
    # X/ ^9 m' g' W% y$ |" Y+ x1 L& A2 _' L2 n; g' p
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    3 W2 A. F+ V1 j; F0 d' J2 p                if(NULL != pNewHdr)
    - `* U7 s- E. m2 _/ `                {
    ; v9 m$ c) L1 e. z                        pHdr = pNewHdr;
    # v- |; N/ c; W( x( T6 c0 X% L                        break;% }* l6 m5 S; K
                    }$ V' p6 b3 u' }: y2 u, f
    * K9 m/ @5 N, r  j, X' C/ |# m2 }9 _
                    pNode = DLL_NEXT(pNode);* U0 H. y& J9 `7 m+ y# [; a; R+ \
            }0 F, Z6 G. n- ~

    . K8 t9 x- }  ?5 G- i) D5 J        pHdr->free = FALSE;. L1 G% E5 u9 x' k% z* N' |
            partId->allBlocksAlloc++;
    + G! K* C0 n' h        partId->allWordsAlloc += pHdr->nWords;. J& H  Y3 g4 p6 O3 Q6 B
            partId->curBlocksAlloc++;+ T8 M) p% Q9 V+ ]$ i  z# I
            partId->curWordsAlloc += pHdr->nWords;
    ! u! }# D' D- _( g/ A: }/ A/ @; [, x
            /*TODO give the  semaphore hear */5 w7 l% b, m6 q& K+ u
            semGive(partId->semPartId);# n" m" Q: I& f( B- J* r7 E. v0 x, O
            return (HDR_TO_BLOCK(pHdr));
      C9 c' o# ?5 }9 K+ @$ [+ X4 ~        7 S' q8 g- a7 }5 _9 o8 C
    }  j! b8 y8 m+ P/ q* M. q/ B. {

    - I1 s5 T+ T4 C- Q6 D8 H- l# l6 uvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)- }5 e3 K  P8 q: c
    {# g' u) a9 O( Z# r5 y
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    * f: ~# w4 @7 ^* [% q8 r$ Q}7 X0 {; ~5 @) o3 a8 V7 w6 ^; S3 b

    & f2 K  O. [9 m0 @STATUS memPartFree(PART_ID partId, char* pBlock)
    ! J1 ?. j6 S1 u& g{
    . Y6 D$ X4 Z/ z* Z7 c7 r        FAST BLOCK_HDR *pHdr;
    ( F2 S2 A$ i" m( a    FAST unsigned   nWords;
    , T9 [( M/ Y8 W* F6 W    FAST BLOCK_HDR *pNextHdr;
    - f+ @* [. O6 A$ Y* K( o$ M: ~/ ?" Z0 h" \+ i4 _3 G; t
            if(!IS_CLASS(partId, memPartClassId))
    $ o5 k: H7 H- E" \3 N1 S) l. Q        {( G% h2 b2 B" K1 O" c
                    return (ERROR);
    0 s$ u4 ^2 Z3 o9 W- {        }" U# P1 E8 E1 K# {6 J; Q8 _

    , N2 v. l* k' I" S        if(NULL == pBlock)( H4 U9 `  o% i: a/ e0 _- z( M
            {$ [; e/ U. a: A
                    return (OK);0 O3 W) T7 p# j& F0 U9 U" q5 U
            }
    7 E- O1 Q6 i! ^. ^  l* `
    9 I7 X5 }2 ~% `9 ?. j2 f7 q        pHdr =  BLOCK_TO_HDR(pBlock);# S3 Z* ~! T/ s  Y$ k

    6 _& E" G) G$ ?        semTake(partId->semPartId, WAIT_FOREVER);5 d1 _- t( z9 j" e* @

    0 p: x/ y. n# z/ v7 s: B        if((partId->options & MEM_BLOCK_CHECK)
    9 x: N: W. c* o. |- u  |- {' V                && !memPartBlockIsValid(partId, pHdr, FALSE))+ U7 R* Z8 b) Q5 L: u( ]) t- P" ?
            {* F) N$ r, k4 n! O
                    semGive(partId->semPartId);0 X- ^/ N. U6 t( Y( ^: @, b, m
                    return (ERROR);! j3 r/ ]" z* ^4 W9 l
            }& I- X4 \0 z9 f  d, f
    0 L" t1 ?% Y" I& g9 Y
            nWords = pHdr->nWords;& x6 k. K! s6 s2 S4 c9 Q
            if(PREV_HDR(pHdr)->free)
    8 S/ D+ T9 v. {2 X$ P" Q, J8 U        {/* the prev hdr is free and than coalesce with it */! a) {" |( ]4 b3 c4 B2 d
                    pHdr->free = FALSE;6 y: A" ^) P. U0 Q# D7 H
                    pHdr = PREV_HDR(pHdr);# R: J9 Y, h2 Z0 }/ \5 x) M
                    pHdr->nWords += nWords;; T" o; {! G+ R* J
            }% a) W( m. B+ M% C
            else: w+ ^* |5 u  e$ z) h( h9 O
            {
    ( E# B: K. C  [: s& M" e& b: `                pHdr->free = TRUE;
    7 \' w( X6 }. [9 d) m9 q# C                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    7 H$ c# T; Z, W) A1 `        }
    2 k' I0 d  O# R) x4 N1 y- a3 s, N0 h7 O( ?
            /* check to coalesce with the next */
      i3 A+ V, T) Q9 g9 S/ H- K        pNextHdr = NEXT_HDR(pHdr);( R& z2 _5 `* K5 r0 l6 ^
            if(pNextHdr->free)- c- [8 Z# G2 H9 p- A
            {& t, ~: F0 g. Y! ^
                    pHdr->nWords += pNextHdr->nWords;9 ^4 f1 x7 w* j6 K
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));" `& N0 A" K' @  z, n
            }
    . \6 D2 p4 ?0 e3 `& W- ?' P, P4 r( I+ Y
            /* cannot use pNextHdr->prevHdr=pHdr hear */; \: g& \, f7 H2 S" _- T6 c" v' T
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    ! T0 {& E- M- j1 I& R1 \  j6 l( s( Z
            partId->curBlocksAlloc--;: T2 p* g1 D) E
            partId->curWordsAlloc -= nWords;
    / j# m( K" m, d5 u# t5 d
    0 ?( {! B5 q, c8 d; f        /* TODO give sem hear */
    $ j( e5 g2 a2 R" d  o$ ?6 h        semGive(partId->semPartId);+ Y  F1 K$ y, k- [) ^( f
            7 ?6 f" N+ p; d1 g0 O" c8 G
            return (OK);/ X  G! l+ t4 P# T
    }
    + ^- @' e4 ~  p; V' m
    ! U$ ^( e* U  i. vstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)0 w+ Q8 C0 h% q/ b/ V4 W
    {
    1 ^% T8 G8 p3 m! [7 s; o$ V  i9 z' W        BOOL valid;
    4 Y4 D# A% t) Q# f) T
    ' N; ~' u+ U0 b7 p8 w4 A        TASK_LOCK();
    5 A5 V/ C6 I7 N1 t" }  {* V        semGive(partId->semPartId);/ ?: K( i& {/ K7 n+ K4 r" {
              X' }5 }4 y) R, ]9 [
            valid = MEM_ALIGNED(pHdr)
    ' j; J- d. W/ b/ y        && MEM_ALIGNED(pHdr->nWords*2)3 R' a$ c' r$ f. I* u& X9 @
            && (pHdr->nWords < partId->totalWords) 4 B& O2 F: u/ }1 Q3 K
            && (pHdr->free == isFree)- z8 @6 P0 f6 J
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))8 t& h) {) s* s, f4 E+ I3 j( ^$ L
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    2 H" t9 |7 N6 e8 K7 O       
    ' E( f5 a, B% I2 I: b2 H        semTake(partId->semPartId, WAIT_FOREVER);3 W4 Y+ H, M( o* m; H( \
            TASK_UNLOCK();
    ; ^7 f/ j, ?+ J$ B0 T" a
    & |2 {. b# t0 i        return valid;8 m+ j' w% O# G1 F. ]1 }; n# u; U
    }
    4 M7 C9 P. ^9 R' s* U# ^% |: {& h9 P8 o1 h9 g
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    & B- p  H% e; Q; P3 X        , FAST BLOCK_HDR* pHdr
    - w$ ~* M- z& p5 U        , FAST unsigned nWords
    ) z1 h4 K- o) _2 d& |9 x+ k        , unsigned minWords& j/ c1 O2 N7 {% ]3 z- S. s
            , unsigned align)
    : j# {$ H5 L, }% U* t8 j8 m# D. z{/ N$ Z1 K+ n2 d4 H5 O
            FAST BLOCK_HDR *pNewHdr;
    : w6 ?& `' d% z$ ?5 k9 W4 ^    FAST BLOCK_HDR *pNextHdr;
    4 f9 U3 }' d3 E: {! ^& i) h    FAST char *endOfBlock;
    ( c8 |& e4 ]  a+ b9 V, o% l. _6 y. s    FAST char *pNewBlock;
    & u% `( h2 ?5 [: I    int blockSize;! v. t# N; G: r$ J( r, X' w

    + j- {* w) O! _  T4 u* X        endOfBlock = (char*)pHdr + (pHdr->nWords*2);9 ]/ c& O( r. o& v8 F

    9 T" x" A  h8 ^. f* `* |        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));; _9 b% ?& q& s7 k

    ( T4 L+ u! N6 z; s4 k' a        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));/ ]% X7 O: `/ y- y& c* {, L
    4 j5 y3 G/ q( M5 S: N, g
            pNewHdr = BLOCK_TO_HDR(pNewBlock);5 S; W) {% D. O6 [  h2 |

    5 e* i0 \) S  [  f& {        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    % j8 w8 z4 k9 k! N' n
    6 j! o! A* j$ H7 _  M9 ~        if(blockSize < minWords)
    + s3 S: h1 O; p- x7 v/ j4 i, I$ L/ `        {
    ( H+ H" x/ H; P9 _5 U  b( O, K, v                if(pNewHdr == pHdr)
    6 l8 r0 r% @& w* F7 a                {
    % U9 y+ U! M/ `0 o4 Z                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    3 q' c  p6 r3 [+ n1 z                }
    1 s6 {- L+ P% S  \2 w. P                else
    . m" g7 z' P: h                {
    " X# g3 E, [5 R( M, E  }                        return NULL;
    3 E8 F) S" \( B: U$ a7 }! q                }
    7 ?. L# ^. \( p        }8 J4 |* m$ i/ @' L& J
            else
    0 E7 u' C2 F; V, q  `0 ]        {        /* recaculate pHdr */) F+ u3 Z! j2 N7 ~9 J8 c' ]/ t6 M
                    pNewHdr->prevHdr = pHdr;  O, {0 G8 d: X4 w
                    pHdr->nWords = blockSize;/ B1 l2 {$ q$ A) Z3 t$ N' w
            }
    * N  K6 i, G) ?) `4 \" Q- n4 h3 ~# F" p4 x
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))' L* ?& R- I3 `/ E+ p
            {
    + L0 c# |; D; D) ^+ x& T                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    $ s! F  u8 n) m) V+ E: X3 d                pNewHdr->free = TRUE;5 H& J+ [; u4 T8 K3 N

    $ T0 s' f! U7 T+ D2 m- L0 b+ r                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;5 N) i0 a  o+ i7 M( e; f" {4 t
            }
    , g7 h% t! j# |4 e, E5 G        else( N! t$ ^8 c- c7 G2 E. e. x
            {/* space left is enough to be a fragment on the free list then */( P  @. S, K, [
                    pNewHdr->nWords = nWords;- J& F+ z' ?; b% N8 ]# K4 I
                    pNewHdr->free = TRUE;
    7 k' }/ W/ l3 d- `5 _
    # P# }- ?! \0 `/ A5 X! U: b/ r# o                pNextHdr = NEXT_HDR(pNewHdr);/ G$ C, r) t- x" M
                    /* words 包括BlockHdr */
    2 h; h. B; b7 N) u- G0 e                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    2 m8 Q# K& ~. @& T                pNextHdr->prevHdr = pNewHdr;
    ( ?' y1 O; }- G6 \! C7 G                pNextHdr->free = TRUE;) G0 @% N0 ]# v& D9 Q

    3 O9 {9 s' E3 H+ Y5 N                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));0 N# T9 n8 w: n4 I- k9 ~
    . {! K+ X  a7 H# y
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;3 R% ]6 ]) k" Q& g5 |) K
            }
    4 s/ d0 Q( ~; u# B  b! W% b- c! h. x2 |$ a
            return (pNewHdr);) V7 i/ h5 I8 J3 [6 v. O; ]
    }* M: h: r  n+ b6 ]9 N6 V  J9 T+ P
    + ~- _+ X; X; ~. U' Y
    static void memPartSemInit(PART_ID partId)* X5 X$ {, U- _; T8 N4 |
    {' E( N# [) x, d. x5 O8 l
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);! E; T  Q# P# t& ?* U
    ) w) J5 K4 t6 u& m& p& R' A4 J
            partId->semPartId = &semMemSysPartition;
    + L8 h1 c: K: }$ s}  h/ Y! M! C  N) X# [- {
    8 `& J. m4 |/ k5 t: a
    void* malloc(unsigned bytes)
    1 l( n3 r2 \6 I  u& w% V  ]& o# V{
    & L8 p, E7 K# c        return memPartAlloc(memSysPartId, bytes);
    : O# L3 [9 U# P/ Z! d# {: m7 G}
    3 A) Q& O' f9 I. R7 L# M, }4 m2 C2 x( r/ u3 R5 V$ a
    void free(void* p)* [( w1 \2 D% v9 f" n7 B
    {
    ! x" q0 }9 |. f1 W" l! k        memPartFree(memSysPartId, (char*)p);  K" w: ~/ j( G% U  ~, e
    }
    , M7 d% |; X& w- Q( ^
    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-2 01:56 , Processed in 0.885129 second(s), 51 queries .

    回顶部