QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2856|回复: 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++下的版本,更方便调试。有需要请留言
    % [" z1 V/ F1 w1 o8 S/ W4 `, R2 G/ z1 V6 f4 k- G4 n  a
    ; R+ }* m4 p3 o
    : S9 s5 u+ o4 ^
    *\file/ u- Z/ G7 M9 N) L0 c# v
    *\brief                9 o7 m$ [3 f! s
    *\details       
    5 c8 d6 a  j# Q4 V, h) ^( Z *
    7 \' W5 m" S! j: z, \8 d6 t *\author        Janson% j6 H( x3 z' ^6 t1 R( t0 ?
    *\version       
    3 j3 \& X5 x6 P2 | *\date                04Jan12- u7 X5 F/ O, X
    *
    % I" C' s, d- `3 s0 r *\warning        0 b0 p* t/ u5 f1 n# t
    *
    ) \  N7 k; \3 t0 Z6 e *\history \arg        30Jan12, Janson, Create the file
    % n1 o! a* h! p2 f9 d2 P1 W/ y4 u; o *        modify from VxWorks source
    , \% g" v! t8 @; p *  Legal Declaration: it is for studying VxWorks only.- R9 f. Z& a: e: q
    */
    : s: I4 Z+ {# W! v& h6 b#include "includes.h"2 @) X; d8 ]+ Q- i  Q5 X
    " |! l4 \7 ?# n, o1 X
    /* The memParLib.h file is hear:) p- j0 U3 y$ Z+ N$ p7 \  I# N
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    - w# Y8 F& B$ p  C. w1 f3 r* k*/
    7 |! M. |- R# e7 \  [, |1 @. Q( d& P0 k7 q* D5 s1 C
    /* optional check for bad blocks */4 ^9 b8 h. r, Y5 m

    5 R0 H% h) |1 {0 Y' D9 r#define MEM_BLOCK_CHECK                        0x10
    9 L  @" u$ V# p; M3 I$ Z! Q% C2 `, d/ h( k
    /* response to errors when allocating memory */! w" D+ H/ m; z0 k9 }8 q) |' `

    7 }' {3 B5 j% Q$ s' S$ v#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    6 i& x) [) \  ]& _#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    5 \* n  A1 _. I$ k$ \, D
    1 t- M5 J+ }5 u% S/* response to errors when freeing memory */- A! n1 i) U" n- j* C

    ! _1 C0 R/ o/ o. m0 F#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    " d! H: Y/ _6 q$ E#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100  y* r7 H( \$ P3 U6 o0 B3 k
    : Y  t+ e6 G6 m
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))  f) X& e+ _9 J' t3 J% A
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    2 C0 w# L' ?: s6 [& v  }
    ( A" ~0 z5 a) I! q& H2 r#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))% \0 j  @7 b2 ~5 a- G. r+ {
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    . \: r7 K! Q: S: k" U                                                sizeof(BLOCK_HDR)))
    6 m2 _0 a3 ~# j2 C( w: ^+ e1 T- m+ @+ t$ ?7 T$ q
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    $ M, s% G3 I" b) q#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \! I& Y/ T8 F$ K& N1 Y1 v/ D
                                                    OFFSET (FREE_BLOCK, node)))
    & I3 @- K0 ~! z4 ~# A
    & \& |1 P. x' lstatic BOOL memPartLibInstalled = FALSE;# i3 k* l2 Y! ]
    , G# T; [& ], T6 h1 p$ p
    static OBJ_CLASS memPartClass;; {9 E/ Z- f* S- B2 C4 I
    CLASS_ID memPartClassId = &memPartClass;+ ^( E3 d# M  Q' c% e
    ( ~3 X$ _. P" M% {! J8 s
    static PARTITION memSysPartition;9 M- j, b7 Z% E8 g
    PART_ID memSysPartId = &memSysPartition;
    " b9 I$ L& H$ `( r& S; DU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;, s$ M# s* @, r, M/ Z1 c
    / s! h( N7 M6 ]* G
    static SEMAPHORE semMemSysPartition;3 V8 k0 D( A0 W1 G
    6 o4 w' s+ u7 L+ R3 A+ Q: r4 m8 d: _' A
    static void memPartSemInit(PART_ID partId);8 K8 K' P& D( B) V# D
    / |3 C* p# M* V% e5 o1 p
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    / l  v- ?& J$ b/ q5 C! l% _
    & P, o! i$ W8 |+ z' ?# P6 _unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;. M% t8 r" v% v6 l
    " U2 R1 D' u6 y1 Y' J5 \: d7 K
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);2 i9 Y& S. X) n6 r* j1 f) f& E6 P
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: l$ {5 ^# B( Q. Z3 d
            , FAST BLOCK_HDR* pHdr
    . G; p# }" @9 Z+ _        , FAST unsigned nWords& r; `9 ^+ H+ i5 z
            , unsigned minWords4 F* y$ p$ \8 Q- \0 i
            , unsigned align);
    / F+ q8 I/ w3 w, n- R, a: N; o
    6 Z1 K1 d$ y' D7 E0 |static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);: R! [3 Z' @* E9 S( n
    3 D, E! g2 v2 Q" K6 X
    STATUS memPartLibInit(char* pPool, unsigned poolSize)& z% g& K5 {. O2 x/ x4 v# X
    {
    / I7 e" e6 ^- q  M        if((!memPartLibInstalled) &&
    2 u+ z& X$ _* |( O5 U$ ^3 c                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)/ `/ v6 C5 K! k& h- N+ D* W" u
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))# x4 _1 C3 N& e$ h* I, n, T- }- m
            {
      O1 y1 r7 D4 [8 V6 U0 x: b+ |8 F                memPartInit(&memSysPartition, pPool, poolSize);
    0 ]( d- N' u0 M9 T0 q                memPartLibInstalled = TRUE;, v5 S& \& {& _; M6 Q8 B( Y
            }+ h& g" l0 e/ h' ^3 u

    9 ?8 T9 b* \; J# O. T% o% E; u        return ((memPartLibInstalled)? OK : ERROR);
    : w4 m% q  g3 Q5 S/ _}
    . G) t9 W) ]0 \( j4 j0 N. Q! ]( ?$ d* w2 W8 j
    PART_ID memPartCreate(char* pPool, unsigned poolSize)$ a0 W- w# @! x8 t0 ^/ a9 ]
    {
    % Y1 X1 g& Y1 ^+ p        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    # Q9 N* w! v6 v- {
      v9 z5 l2 K# Y! s% p0 |8 U        if(NULL != pPart)
      H9 d; I* k: R; T5 A9 L% H        {5 H1 G- K4 B7 v
                    memPartInit(pPart, pPool, poolSize);) y" b* `1 h3 n
            }
    $ Z7 r$ m7 H# s7 M: N6 Y
    . U$ j- J: c9 }* O- j        return pPart;  R3 d. j  P5 `7 d4 B% [
    }
    % \( S/ ~6 m2 L& M, `  x" Z
    1 R: |- v6 F0 Y3 n" Hvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)  ]+ _3 x- Y, O7 `
    {
    0 R5 j: [" l; h4 E; ]0 g        memset((void*)partId, 0, sizeof(*partId));8 {! W3 ~/ a: }  w4 s
    3 F! L2 G" b3 `! b
            partId->options = memPartDefaultOption;, Z) g  p3 r) b0 ?' L* T
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte *// P/ F0 I) n9 j5 v) D

    4 d) m* p8 q" v, _0 Y+ I        (* memPartSemInitRtn) (partId);$ }+ Z& X$ @; f& T7 h& q6 J! C
            # r* {1 e6 k2 ]8 W; Y( S
            dllInit(&partId->freeList);+ F4 B  s( o! ^: n' H2 X0 e( t
            5 [, E* R1 J2 B5 t4 N
            objCoreInit(&partId->objCore, memPartClassId);
    - X, a( D% Q) ^- a( z: j4 R       
    ) _1 [0 b1 @0 V9 K        memPartAddToPool(partId, pPool, poolSize);! ^/ `3 }$ `9 i  u
    }  Q/ X2 X  H8 }& z- ?
    ! a! Y4 z0 |5 `) `5 b
    STATUS memPartDestroy(PART_ID partId)% {& ~2 L8 J6 [
    {' c9 J7 X2 u& F- |! p) W( X
            return (ERROR);
    ! Y  ?) p& Q  E2 \* s}
    ! n" E5 r! }7 G) l2 u/ O  S3 K- K& O0 z$ e" ~9 g
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    : ^- E% f) t9 H{
    ! s0 R" ^7 q. O2 u4 a# Z    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    * t4 g7 t4 G5 G& A6 P}
    * Z4 J0 a0 N" @% [, P3 P. u. X7 y  A3 R5 @" i- b, ]3 [

    ) L- g$ [' s, \. E! Ostatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    , d" R: j) P$ [. ~/ _% W{: z' g# o* s" h" P3 J
            BLOCK_HDR* pHdrStart;& t# k- D4 U, F, d
            BLOCK_HDR* pHdrMid;
    ' B! g5 i8 [' S  N, ?        BLOCK_HDR* pHdrEnd;) N& w) g+ c1 i) q* X/ @3 T3 W
            char* tmp;
    , E8 k* x' r$ ~7 C; z        int reducePool;
    0 v4 l  x' e) n) y" I
    * J+ m5 N5 P  q9 y/ c* l        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */  E: p6 a1 Z: ?
            {' ~/ a; {! C; t8 [; k1 t
                    return (ERROR);2 L/ k2 {! j4 u$ x) W. U
            }
    4 F: R6 U0 o! S" Z; n1 ?& m2 ]. O% `3 O: O) a0 e
            tmp = (char*) MEM_ROUND_UP(pPool);3 ~' ^: O8 ]# N+ e( O. U
            reducePool = tmp - pPool;
    # W( X7 }  S' [. E! }' W, h# r  v" J. j# J1 ^$ _$ \: s/ Z' `
            /* adjust the lenght */' y. R' F$ @6 p+ V! {
            if(poolSize >= reducePool)0 Z& E' ], o  R: p
            {
    . g, V1 j! N; d                poolSize -= reducePool;
    6 s' Y# q* k& H& @3 M  e0 u( {  ^        }
    + Y6 v3 C9 ]" a        else  g3 K5 J* L# @
            {
    ; a4 Z6 M$ R8 r+ w% k+ r7 ?* U                poolSize = 0;/ y+ ]0 I1 [* N. ^8 |8 G# b
            }
    + W# P& e4 v7 ?        pPool = tmp;3 w8 s, L: s" U/ g6 R# R$ `
            % [; A, Q9 l' |+ e6 V& ]# a2 b* a0 f
            poolSize = MEM_ROUND_DOWN(poolSize);
    1 Y) u! v' n1 _3 m  i' _6 C/ b1 I        ) d# e% {% T2 M) u# _" m
            /* at least one valid free block and three header blocks */3 Y( `2 G- {" |! i: f8 x; c
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    1 X+ `& c' L" i$ E        {% t0 m+ P: `& G  N, Z4 d
                    return (ERROR);
    % {. C& B2 X  R  L8 F: P  w        }
    , N! ]% ?% Y! Z. c/ J* \5 p1 t$ P6 W7 }5 I# H% n$ p. I
            /* initialize three blocks */
    & X6 [1 s: A  {- {- ^        pHdrStart = (BLOCK_HDR*)pPool;5 ~5 K0 Y( i; q) Z5 H
            pHdrStart->prevHdr = NULL;. M2 Y9 W8 X0 s2 t; Y7 s1 p2 Z1 C
            pHdrStart->free = FALSE;                /* never in use */
    8 U, r& P1 R% M1 b9 P        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    + i* m, ?3 Z' l3 r
    4 m5 U( O1 z; ^% u8 `        pHdrMid = NEXT_HDR(pHdrStart);' n4 X& p2 J! \4 _7 x0 J) T/ q
            pHdrMid->prevHdr = pHdrStart;
    1 I5 ^" U6 ?( p( X0 Y        pHdrMid->free = TRUE;                        /* the main block */
    / t& ?) [! \, }3 B" M/ \$ |        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;+ y3 B9 p+ Q8 W/ v4 H6 x1 Z( b* ~
    2 D7 j2 ^# A  Z  n3 s' P
            pHdrEnd = NEXT_HDR(pHdrMid);
    - l( a4 {/ b1 I2 z+ W+ K        pHdrEnd->prevHdr = pHdrMid;
    + l+ C# n2 U8 E( q6 S5 l8 _4 m        pHdrEnd->free = FALSE;
    8 @8 r( w" P2 w9 c, ?: V        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;  d9 e7 {' c3 x' ]7 n/ ]$ \

    & x6 a: Q5 X) `# C2 l        /* TODO take sem hear */
    5 P+ @* x/ S/ X0 o6 R5 V5 |        semTake(partId->semPartId, WAIT_FOREVER);
    . F  E$ L2 A8 y* Q% @1 x        . N4 p, @+ ^  }7 Y+ X+ I3 ?' p
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));4 m' m" Q0 ]& I8 i/ i; b
            partId->totalWords += (poolSize >> 1);
    9 M: e$ M+ A, [3 A2 U) h, |% i+ @
    / o1 G  A- a) N5 R8 J1 {        /* TODO give sem hear */' D. }0 x% u- D$ l
            semGive(partId->semPartId);
    ! ?& y+ C  I2 ]4 q  f/ u! {
    - Z$ e4 L3 r& L* Q+ }: Y$ u# U
    + l" R7 M) f# n& H& j        return (OK);
    5 G7 o& ]: `( Z+ _}
    , T$ v4 }% q1 r$ W' V( s- t, ^6 Q* g  G( q3 ^  ]. Y/ v. u
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    & V! c6 ?- W, N3 p: T2 |{2 p' E( z; d1 |: }; t7 c  M+ c
            FAST unsigned nWords;
    % g! e" f1 i" K. j: w. V$ ]        FAST unsigned nWordsExtra;
    ; a0 u9 D  v. g0 j) W" `        FAST DL_NODE* pNode;
    1 s& ]: t6 s  r% D3 Z) j        FAST BLOCK_HDR* pHdr;
    5 F, N* M& }, Q7 _/ a9 {        BLOCK_HDR* pNewHdr;
    ( ]9 h- H9 _0 K6 e- C        BLOCK_HDR* origpHdr;
    % A2 w3 S* H: h3 v3 l1 I- @3 P: b0 p& {# }
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */5 W5 f" Y  `4 K7 L7 b/ j- a5 g
            {" i2 G, w: P1 [  u( y3 ?% ?9 Y8 h
                    return (NULL);2 J; U" Z( Q! Y- Y
            }
    ; v# u+ @+ d4 [' T$ r9 K% G1 Z+ D8 K8 C' Y! F# U9 y6 }/ B3 _
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;$ q+ X2 E- X& L

    : K! t" D' d2 |6 E3 ?$ Q        if((nWords<<1) < nBytes)+ L# y* X% t/ g2 u) U: W$ C- X
            {# \7 }( O7 |. u( @3 e# b7 D* h
                    /* TODO suspend the task */
    ' U+ [8 R& ?0 q. ^. P& Q- A                return (NULL);
    9 ?0 d6 m. m3 s        }1 v  |) s5 L: f9 K

    / X6 B  N! E7 A5 F: f        if(nWords < partId->minBlockWords)
    # ~7 _6 T9 R' ~) d0 p8 R        {
    + h( O: i% G1 `- r0 z( Q( l2 z& N                nWords = partId->minBlockWords;
    9 W3 L! J* d# F% U1 G) x/ N        }+ z) x/ B8 U# m, q  @

    & t: S% b2 \; Z- p        /* TODO task the semaphore hear */
    % H/ }0 T6 [, c, H        semTake(partId->semPartId, WAIT_FOREVER);
    ' c( }, B+ ]* Q        pNode = DLL_FIRST(&partId->freeList);8 {  }" O) ?0 y* |- Q6 M
            nWordsExtra = nWords + align/2; /* why? */
    - U: q: r0 W& U- U5 j8 _
    3 b3 _) E. x# j+ ^9 L) y        for(;;)
    4 r. W* d; g; E& q) ~        {
    8 f, }* l4 y, d( I                while(NULL != pNode)
    1 Q3 G$ ]$ D. w2 l                {7 p3 {( h! e8 m; a# F9 d3 o
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||' u; I. {. U( t/ X
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    " r% m3 W& z/ P. Y* w                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    % `+ J* Q; Z- ^& U4 v+ c                        {7 g+ ]+ R5 d$ ~
                                    break;* ], a! i2 S8 d8 b! r* X) j5 |
                            }
    2 w; A* W/ O: y+ N; G7 `' P
    ; @5 k8 x' |$ x$ K0 C, q& O/ g                        pNode = DLL_NEXT(pNode);
      A0 p" s6 U! t; B# i                }, w" ^- \& O& D  z5 B

    : C, ^( S+ {* U# N8 y                if(NULL == pNode)
    0 L) ?8 X8 {% s& ^/ M0 w                {
    9 Q6 P& h4 Z  G                        /*TODO give the semaphore */4 D- X4 q8 ~4 F) c
                            semGive(partId->semPartId);8 f( U0 t, K! k: V/ O' h; J: D# W
                            return NULL;4 \4 W- o7 B+ i0 U& P
                    }4 \" \8 F% Q: P6 E/ t2 [

    : s2 P. P" o, r  Q7 d& G1 I                pHdr = NODE_TO_HDR(pNode);  ?# f  p' D9 \) a, A! T
                    origpHdr = pHdr;
      k& R4 ?- M7 f% t7 y2 M, Q6 o! I2 Y0 T: ~; p
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);5 ?# f$ r) E' @4 O
                    if(NULL != pNewHdr)0 E0 S8 `: I1 ]8 s
                    {: s) A' l# ?( t8 j+ |7 Q& p( |
                            pHdr = pNewHdr;' G- ]1 ^' m1 g1 ^4 a1 f. d. F: F
                            break;& Z+ D9 w) g  y: t( @
                    }/ K$ X/ D! k6 i3 O8 R: W

    2 o# }* U) L; w* V                pNode = DLL_NEXT(pNode);
    4 A0 s* Z1 m) g" h* ?' n        }+ P( f7 w( F8 x2 t* k9 `" T% z
    9 z8 s7 D/ }: o; [0 w7 _
            pHdr->free = FALSE;
    $ y: z5 y# b' O! [5 N        partId->allBlocksAlloc++;3 L: r) \6 a( I) Z
            partId->allWordsAlloc += pHdr->nWords;
    ! g2 p' Q( b) d  l3 Z# g        partId->curBlocksAlloc++;$ h; \3 \( I0 N1 O$ H! e/ |/ h
            partId->curWordsAlloc += pHdr->nWords;& D3 {* k8 S/ n; c+ N% O9 h

    / z( |* F* q* r5 ?' s        /*TODO give the  semaphore hear */
    4 Z% `6 H9 w( Y& T" I9 c% C        semGive(partId->semPartId);
    # g  a; S4 h* j: T: J* N) t        return (HDR_TO_BLOCK(pHdr));
    ! {; V' p; t7 D( [9 m% ]        4 t" Q# e' n# z6 {
    }
    2 j; N: o( L% S: p4 Q# x3 ]* T' X; m4 ]6 E, }
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    8 h" i; q4 E# Q{
    3 R' D1 h& s8 j. q* }- }+ w+ a: u4 k        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);( E& e, z+ E) ]% \- t, |
    }2 Y( h  A: r' |& U: V) W7 ?& \. h

    2 m4 L, D8 ]% n: \1 JSTATUS memPartFree(PART_ID partId, char* pBlock)
    * _/ x/ P1 D/ `{
    $ l$ v6 H+ ]/ w5 U- W! x        FAST BLOCK_HDR *pHdr;( i% r# U- k1 Y
        FAST unsigned   nWords;
    % [+ B5 S/ V3 P& e6 d" a: L! M    FAST BLOCK_HDR *pNextHdr;/ P& A3 W7 C, O4 ?. j+ z2 S8 b
    ; k& a$ y+ B1 H8 N5 X* z
            if(!IS_CLASS(partId, memPartClassId))7 Y; i% V' N4 Z, B
            {
    2 |( Q5 h! M6 T! Y; k: U4 u- L                return (ERROR);% s# p6 b* T# |1 _8 y( n) e
            }  V  _2 s# z! E1 }  H& a' y

    ( v  N2 g6 ?8 F. n        if(NULL == pBlock)2 m6 N4 u) f% Z/ O' ]
            {
    $ n9 L2 f5 t) A5 o                return (OK);
    * p6 N2 h2 |: b- R8 x- ~        }8 a1 [' U0 ~7 D3 |

    : Z" t  [1 x. [. k  D        pHdr =  BLOCK_TO_HDR(pBlock);6 I  x4 d+ U# h' q
    5 k# Z" _9 a5 G! n
            semTake(partId->semPartId, WAIT_FOREVER);
    5 A0 p( I4 [. v0 L2 S2 d) ^
    ) }2 ^9 U) j' I1 N6 E% H( N        if((partId->options & MEM_BLOCK_CHECK)
    + c3 m  U0 Y  P9 _) r: A( T  I                && !memPartBlockIsValid(partId, pHdr, FALSE))
    / w  I$ W! g2 Y        {
    * D  C8 y; n0 o) x# @* T0 m" W                semGive(partId->semPartId);
    . |6 c& v6 V" C; q6 Z                return (ERROR);
    + H& H7 T; i  r, C' _# O- R        }- c$ A; x$ }0 {
    , U8 ~/ z9 G' m( Q" q" J2 _
            nWords = pHdr->nWords;) U; n, |* k% O& A8 w  V
            if(PREV_HDR(pHdr)->free)' a: B2 t8 \+ \2 ]7 N6 M5 `
            {/* the prev hdr is free and than coalesce with it */
    & o. O' x! t8 l( q7 ~                pHdr->free = FALSE;6 q! N& W- l3 H
                    pHdr = PREV_HDR(pHdr);3 b- `9 u  j* k" I/ V' q5 Z! U" L
                    pHdr->nWords += nWords;
    ! f! w3 C7 m3 l8 k7 T9 o        }1 u" V* [; s9 [
            else
    5 p7 G/ W  o; U        {2 L3 u% l) a, F- M
                    pHdr->free = TRUE;" I3 L6 J8 b7 M/ _4 `
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    + E' t) X5 M" I+ {! P        }
    ( [+ N1 K- K6 W  ^3 q
    7 u8 C; p; ~0 Z2 o, P7 |" N& A        /* check to coalesce with the next */
    . P3 w5 J+ u' L. `- ^$ \# u2 t        pNextHdr = NEXT_HDR(pHdr);0 u0 X; D8 ~5 F' p" f$ y4 s8 M
            if(pNextHdr->free)
    ' S; y- s+ P6 n  B$ ~8 Y. ?        {
    8 y7 k& N9 Z4 P9 A1 I                pHdr->nWords += pNextHdr->nWords;$ ?  Z: p% k# B3 m; ~7 A6 X5 E
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));, d8 T1 m. F5 b) X% |5 Z* N9 o
            }; E& \: P# `: F; f1 Y6 A  n
    / b2 P) C' y; t4 l6 h- w  i
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    ; u) F  c) G- ?% M$ X+ s        NEXT_HDR(pHdr)->prevHdr = pHdr;
    1 `- M) X4 s+ h% N$ S" ^: M4 Q/ D, H. S" m3 M
            partId->curBlocksAlloc--;( A) L( D7 r" Z) c( Z- U
            partId->curWordsAlloc -= nWords;' A2 ~% v, A* R6 J5 Z$ i( R

    3 _4 B+ I8 L3 j/ R        /* TODO give sem hear */
    ! h- B5 m) c0 I2 H2 I- f8 D        semGive(partId->semPartId);
    " J6 @. n8 x6 H3 w       
    8 i8 S0 D. w( a) b        return (OK);& c2 x4 F  C: T$ T. \, _
    }
    / P6 z) ?, F7 T; V/ b4 D# _3 P. U" H8 d' R* c% ~+ D4 n
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)( W' x! G. M) w
    {
    : n1 m$ X1 V: h4 O( y        BOOL valid;
    ' e" U" \+ U. q  ]5 e, y( Z) Z* y$ m! \
            TASK_LOCK();! S, D) O/ u4 L
            semGive(partId->semPartId);8 t& S: r6 V( d# y  e; W  }
           
    ' U- H* Z' I$ m$ N+ M7 k; [        valid = MEM_ALIGNED(pHdr)
    * a: I& n7 B5 p- B2 M' y        && MEM_ALIGNED(pHdr->nWords*2)
    & r5 I( ^- {, M, J* t# p        && (pHdr->nWords < partId->totalWords)
      n5 I  T8 F+ U0 `* M2 ~0 T        && (pHdr->free == isFree)
    ! _* g  O& S- v: Y" c. o        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))! T3 e! s/ L1 }
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    ' w& d2 y8 x; L. }       
    + N. V$ A/ M5 G: _# \- o        semTake(partId->semPartId, WAIT_FOREVER);+ z5 c2 q' H2 j% _# }
            TASK_UNLOCK();" r; q4 U! C7 Y- v2 s- h, m$ Y

    # W6 Y* G$ D: @! H. j/ @        return valid;. v8 V$ M; F1 l6 G# @! u5 z0 a5 M& p
    }: t& n5 g, E# L( `0 y+ e

    8 n3 y; f' Z5 c( D: q* i) ?static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId6 Y( c& Z5 s! S; `3 a+ V& {% f/ a2 j
            , FAST BLOCK_HDR* pHdr( ~* O/ i5 u( L+ T' Y) I
            , FAST unsigned nWords" l* r( r& l9 b- @
            , unsigned minWords7 p1 o0 s/ K) R2 M" O& m( E! n
            , unsigned align)- e  R+ j/ `! ~
    {
    % R8 a* f7 o: d# |/ I. k# p        FAST BLOCK_HDR *pNewHdr;
    0 Q8 m0 s) x" W! o    FAST BLOCK_HDR *pNextHdr;
    / ]9 v5 m" g+ n4 L! r; F    FAST char *endOfBlock;% y1 t5 ~5 P- i* P1 n  g  k' E) ?, X
        FAST char *pNewBlock;
    " F$ y+ _+ {' E; z$ k$ }    int blockSize;, Z5 N; h( W, Z6 P% H$ m$ Z
    $ ^% B1 H& b$ s) h! q/ l6 n2 g
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);- z) |) V2 p0 G

    6 K2 i3 e; Q0 ?        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    7 @) w& s6 ?8 V& Q8 Q0 T
    * T# F+ O' ]7 s* m5 f5 ~        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));9 h' ^2 b$ A( a

    ! g  x$ Z$ W, v) c        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    6 A, R+ J" E  Z9 \5 N4 ^4 a8 R( E' s* \1 i* |# v) S( L. }
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    - H- y8 g. O  Y' P
    6 [- i( j4 N9 `0 J: \0 a1 `2 r; ]4 \        if(blockSize < minWords)3 D) d( J& V; z( j- p& c
            {) n, ^& [" |" s2 J- R% {4 L& e
                    if(pNewHdr == pHdr)
    # f( w8 ^5 U# a' T% c                {+ z; H" d! Z2 U2 i
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ) |& V" l6 b2 a$ g0 k' T+ I, @                }
    5 O4 |6 }9 w9 Y# ]                else
    . b5 g9 \6 |6 ^0 ]. |( P' e/ \! {                {& s0 N7 K0 f6 `1 F7 B3 ]) i9 r( n; H; x
                            return NULL;
    # F9 O- y$ F( q! ^                }
    + G8 D8 @( m+ R+ @7 g        }
    2 v' [# J8 M4 w        else
    4 y- N. J1 j9 M% P; k4 Z, c        {        /* recaculate pHdr */
    5 h8 m# S6 ?4 X                pNewHdr->prevHdr = pHdr;: M4 `4 c$ R2 c9 U. d/ t
                    pHdr->nWords = blockSize;& D! K- d" e$ ^% `4 i8 a9 h: g
            }* r, e" z( l2 N7 f/ }" L" w  Q4 W
    4 x* Y+ G/ g. |6 H8 l7 m5 B
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ; v3 K5 ^/ e- C7 V4 r5 h, a) D* s4 ~, E        {
    ! H& y* U& r6 K' J+ e# b- X2 ]8 r                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;8 W% \* o: R2 }0 j. u( l
                    pNewHdr->free = TRUE;
    ) o* n: Q, M% P& o/ @: I8 k
    - O3 v& l( a1 M. P. N( v1 S2 r# [                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;2 W: q8 e: s8 O' Y
            }
    & {% ~: q5 d9 s- D        else
    1 K& R3 c0 d  [7 Z        {/* space left is enough to be a fragment on the free list then */% R' e  ~3 G( L+ b: P4 Z
                    pNewHdr->nWords = nWords;  g7 F- m5 {6 L5 K+ M/ {, I* u! R! Z
                    pNewHdr->free = TRUE;
    5 U: }6 c- X6 j5 u2 G  q  w5 c+ i
    3 B& `# T/ a( |; }$ d                pNextHdr = NEXT_HDR(pNewHdr);+ I% K" o9 l# g6 g9 g* d9 R8 G- G7 Q
                    /* words 包括BlockHdr */' k& a- g0 w6 H2 V
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;9 f+ W' n! K' j( r0 l7 y. ?! n  l
                    pNextHdr->prevHdr = pNewHdr;  W- S% o9 s& U; J3 j
                    pNextHdr->free = TRUE;
    ) j; V* l! q/ ]6 S& }! N0 e1 k# V6 l5 u
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));7 W/ p8 ]3 x* A& y2 c. x
    & X! H# X0 }% K$ y
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    4 a& V4 ]2 U3 _  H7 p8 f+ o        }
    9 b" o- J* a2 `6 U- |7 l! y9 A. H9 {9 _! h2 b
            return (pNewHdr);* {/ {7 Q* ~# C; W8 A1 [
    }
    % ^" K% e1 S6 {. @- T8 b8 v& _8 f6 G
    static void memPartSemInit(PART_ID partId)5 m7 c% }4 B/ t% S( X
    {
    2 a: P' U) r4 ^- c! T        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);! j" i) ?; I: R% f) l% K/ a$ c
    9 r7 k- D. v% S+ w7 B0 h; l
            partId->semPartId = &semMemSysPartition;  C  e3 L6 O& s$ N
    }# B+ a2 w/ l5 ?# \

    # w& C! l2 E$ M  dvoid* malloc(unsigned bytes)
    % F) T- S; q+ [2 M5 n0 |0 o* }' K{7 c6 y4 P! x( Q4 h7 a+ ~: [$ A
            return memPartAlloc(memSysPartId, bytes);
    , m# M- v$ y& F# ]$ x}
    / a; F, ^* f$ [9 X( {6 w: g6 e  X3 Z
    void free(void* p)9 z+ {( ?: i6 A+ i
    {
    . D9 ]) @" \5 P6 ]6 w* g        memPartFree(memSysPartId, (char*)p);2 T4 [3 N) o3 D9 E0 ]* S
    }8 c0 `/ d1 Y  W( |% ~3 e
    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 11:24 , Processed in 0.479981 second(s), 50 queries .

    回顶部