QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2882|回复: 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++下的版本,更方便调试。有需要请留言
    9 A1 O, D3 @3 q4 a: j
    : o2 T( L0 o! Y7 `2 M; d, {* ?) S( P" C9 G9 d& y4 ]+ u7 {9 ~1 J
    ! x# c4 Q' N1 T; n8 s
    *\file  U8 F# P' s% ^5 K2 a
    *\brief               
    6 c8 G, e0 B; X *\details       
    5 I% o9 `9 H8 x0 A- O *9 N$ d: a1 K) b. O7 T3 w( v
    *\author        Janson8 Y3 W  l4 |+ Q. Y  ?0 t
    *\version       
    ! N7 i. |9 H% N *\date                04Jan12; Z( N: \* a; A& H# Q- q8 i$ d/ N
    *
    " s: v5 O' y; L6 Q: s4 m *\warning       
    - U) Y6 v  l" ]: I7 T *
    5 S) F0 }' L5 z+ E0 P. O* k *\history \arg        30Jan12, Janson, Create the file
    , y8 D+ R9 L6 k0 U2 J *        modify from VxWorks source3 i2 k0 D7 P2 t. d; f3 k# n
    *  Legal Declaration: it is for studying VxWorks only., F8 x( K3 {- g* p6 W2 Q! |8 G
    */8 |" F, Y+ K; n- }7 K7 [8 v/ K1 L3 U: [
    #include "includes.h"
    ' a% ^+ o) O  S
    * u7 x3 a8 E  E+ W1 G  p/* The memParLib.h file is hear:
    ! m* z+ I' s: x" _https://code.google.com/p/vxwork ... rivate/memPartLib.h
    7 G& e# n1 ~, y. d; ^! \*/! {* @. B3 q9 V" `

    9 {7 S8 b% ^( D- z9 X! {8 ^# `/* optional check for bad blocks */- _. L0 t. S: Q% Y

    3 c& u5 r* w9 R3 Z#define MEM_BLOCK_CHECK                        0x10
    , `& Z2 N* N* @$ D; u& J2 ?. G  V8 I8 y$ C, t0 f
    /* response to errors when allocating memory */
    ) y4 w: m! {) ]5 L) L0 N6 o+ v
    : s0 f5 p* }* l7 b#define MEM_ALLOC_ERROR_LOG_FLAG        0x202 d& j8 y3 Z  C$ K4 P4 E- K+ y5 d2 w. f
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    ; o- Q. w6 g, y0 v2 r
    . W# X9 [9 f7 s  G) J8 g* }7 o' _/* response to errors when freeing memory */0 s3 t$ C9 {9 g$ g% Y- e* a$ q- y" @

    5 o, Y6 n/ G" z7 D  Q#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    $ `8 H$ r& F; L& h0 M6 u6 t9 O#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    : |$ O4 ~% t5 w; I0 `# B& k. u! {) W; b5 Y/ o, e7 ?
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))' p& n7 l, H$ h2 h! }
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    & S1 t0 I5 x3 b( m+ e
    1 s( N3 f2 b! q#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    . Y6 L# Y$ A5 A/ Y" _1 C8 A#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \8 f" m% R7 A5 ^3 H( U& o5 L
                                                    sizeof(BLOCK_HDR)))
    + h" C9 C# _( S6 [6 H& x! }3 p: n% o2 y& Q3 J& ]2 o1 V
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node); K6 F5 T3 L6 @& b
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    : s# W- c/ Y2 C) k$ u3 B1 B                                                OFFSET (FREE_BLOCK, node)))
    + L  [9 j0 w) r# k" F' f9 w# \. b. w* Y
    static BOOL memPartLibInstalled = FALSE;
    $ U4 ~% R" G8 z, x: P8 j
    " `) p( M5 a7 T5 {& D( ^8 Z5 R3 wstatic OBJ_CLASS memPartClass;3 t: i+ K, g+ ~3 F
    CLASS_ID memPartClassId = &memPartClass;" k' O3 f5 b5 `

    8 p& r/ z7 ]- f" y( ^& ~$ qstatic PARTITION memSysPartition;% h" J. t. ^) T/ T: J
    PART_ID memSysPartId = &memSysPartition;
    ) J' ^! J( V. u. ~U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;: f5 l# }! X! A4 q- \" Z- v
    3 W) U' b2 T9 E9 _6 N* A
    static SEMAPHORE semMemSysPartition;( n" m3 H  F8 k. I+ B" A$ C" j

    - \' l; E( w1 u: R% i- v( vstatic void memPartSemInit(PART_ID partId);$ R* g2 X- ?' |" G+ K% a

    ' a8 a: b  H5 r% xFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    8 ]; o2 u! }$ X! j/ [- d0 [0 p
    , J9 Q; M& h' s  b( ~1 K% t! bunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;8 X0 K$ I% x1 W, n; x$ Z$ L

    : g6 D; Z2 o& Z+ Wstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);9 L3 t' X- b1 T4 j
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId$ g+ a6 y* G- a; {
            , FAST BLOCK_HDR* pHdr
    ( l3 k3 _8 O6 C  \! |        , FAST unsigned nWords
    ' y0 j5 e& o8 l% r% b' L        , unsigned minWords
    " U9 V- I2 S$ p8 E. Y2 [        , unsigned align);: I1 y. h* `7 l" H. F6 E) O# \

    $ R3 n' x! p3 c4 qstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);: b! j: r9 y& J* @; _4 t8 v' @
    7 q: G0 `4 i2 \. z2 i" j
    STATUS memPartLibInit(char* pPool, unsigned poolSize)1 x$ ^: ~/ t  S6 |# n( v
    {% |0 g+ L/ U2 a  n* [8 j# j
            if((!memPartLibInstalled) && 4 Y  K. l0 A, l# T1 M8 C0 x
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    6 G  P" P. y% a1 _                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    5 h; a1 F/ J4 a: C+ P        {
    , _( _4 e4 B/ e+ e6 l8 b9 r* n                memPartInit(&memSysPartition, pPool, poolSize);
    , f2 {! Z5 o  h2 t$ \+ i7 J  F2 R9 r% I                memPartLibInstalled = TRUE;
      ^# w. \) D* z! H" t2 u        }
      ]4 V6 F; {7 h" j( A
    ' @( |, ]5 G( ^" r        return ((memPartLibInstalled)? OK : ERROR);4 t  K5 L3 y$ K4 Y
    }' a$ X: T* e  g# D6 p# g( p
    , i+ H% Y4 @1 S+ U* ~
    PART_ID memPartCreate(char* pPool, unsigned poolSize)! [& |9 Q$ k/ S7 ]( ^, |% `( U
    {1 j2 b$ v. z4 a3 d
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    # q6 b: D5 }/ t: [: _+ l& U3 D
            if(NULL != pPart)
    8 g9 L  a, y# |  F; M( @  V  e        {
    & X! ]- A5 s/ p8 |- b4 y' L: w                memPartInit(pPart, pPool, poolSize);
    4 t2 r0 }& B: U- k  c9 _. e. [        }
      H: t$ C: O5 q; r3 T4 E- r3 H# D
            return pPart;5 f5 P# G6 I7 f0 y0 r1 n- D' v
    }' ]5 E$ {9 x+ n) k% B6 e

    " O7 \2 Q; {. [/ w8 fvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    $ j# |  f& D' U+ n{$ _* C7 D* Z! |) v
            memset((void*)partId, 0, sizeof(*partId));% a/ Q  M6 G3 H/ r
    8 `' [% ]& ^; J* C7 i' A3 u
            partId->options = memPartDefaultOption;
    7 r2 M* C) r0 ~) t- t7 Y        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    + a% t, x. @/ q3 c
    7 d- f' c) _6 x) v5 q' p3 c& P9 P" [        (* memPartSemInitRtn) (partId);% ?9 _1 B5 A9 |( v6 v' l
           
    ) O3 v9 @% X5 `0 b) m* i$ V        dllInit(&partId->freeList);3 B# t, F- ?+ H: A% Z  F
            ) Z; p. C) G; l2 `
            objCoreInit(&partId->objCore, memPartClassId);7 S$ t% C6 a- u8 r
            9 E% n) U" L; z: e/ k
            memPartAddToPool(partId, pPool, poolSize);
    4 z- i9 N  Z2 Z' [: m* H}- s0 C0 a; |7 e, J2 A! q6 \- \% ^
    / r! t- v) B4 J6 P+ G
    STATUS memPartDestroy(PART_ID partId)' ?/ x" o+ ?9 l! H9 O& T
    {
    ( D% V: h2 b8 c  N# l& ]( H        return (ERROR);
    , Q* O  {! Y% e" z9 t2 |. u}
    " ?' L1 r( [$ E' u/ w2 }7 {3 m1 B; X$ ^
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)& b: R# _& m$ E9 a# C
    {
    ( `# @7 I2 W1 B4 U2 n# S    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    ( E. i! v) e3 X! }: o2 C}
    9 d3 L0 |3 {& j+ J* W) @, K3 {: L. B

    + U* B$ g+ ^  k6 ~' c5 M( sstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    . F& E9 e4 r+ t" ~{
    8 p& @5 d% v* a4 G8 t9 }9 f        BLOCK_HDR* pHdrStart;' ~: L/ i2 n' R6 U
            BLOCK_HDR* pHdrMid;0 P# ?( a9 u1 i5 R" ~+ _
            BLOCK_HDR* pHdrEnd;5 s( S# F" O) q/ Z! w2 T; N7 I
            char* tmp;3 U" a2 k3 @( D' q* m+ [8 n/ y
            int reducePool;' B! B$ S+ W) h" h- H3 I) e
    9 \$ G3 Z4 m8 Y) X+ Z) R
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */; c# c" X# ?2 Z  n" n- ^' ?
            {
    . S- v7 ?* ~: t4 }; z5 z3 t, |                return (ERROR);
    8 S9 J  Q- i) d' z$ J' C        }
    ) i+ X! C  A. u, @) t7 W8 _- _# B& L/ M& I. l2 S% c! r6 M
            tmp = (char*) MEM_ROUND_UP(pPool);
    0 P% {7 l9 G- [9 R& p- m4 \        reducePool = tmp - pPool;- u2 c: ]1 r2 F

    ' Z& R) j; g( ~' B" T. r        /* adjust the lenght */1 v. _0 a8 \: L% `4 I- ]
            if(poolSize >= reducePool)
    : g; r  p0 Q( m; E        {+ C7 J  A5 G& C
                    poolSize -= reducePool;- I: q% i" G' V! K  M
            }
    / q7 h5 y# ?- d* F! E! i4 c" k        else1 P% ?, ~- q7 b+ i  |
            {
    8 C; _% V8 {9 |" a8 P                poolSize = 0;
    : L7 u1 `9 x* t/ F% Q; s        }
    % x" I7 b! ?9 f        pPool = tmp;
    9 G! ]+ m" r  y. [7 Q        & M  R' I, B4 n1 B+ u# r! `
            poolSize = MEM_ROUND_DOWN(poolSize);
    1 ]) `. R- L* \% \; k8 g' S4 u        " d  q$ ]3 b" X! c9 U' S, P" Y' X
            /* at least one valid free block and three header blocks */
    5 |8 S8 V) C0 D        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    , m5 ?" q4 ?, U2 V$ i0 M3 V! \- x        {$ D( O# S3 H" V
                    return (ERROR);5 a; _$ Q: _4 m% X0 L7 z* _
            }3 w8 }2 u7 @: r  e, C+ ^+ i

    % ~! i7 l3 f; Y  S9 h        /* initialize three blocks */
    9 K2 F) h: q0 L* L0 t        pHdrStart = (BLOCK_HDR*)pPool;
    , I& {2 _6 c$ R: l' \4 T        pHdrStart->prevHdr = NULL;
    ( n) {, c: u4 @" |0 L1 O  C        pHdrStart->free = FALSE;                /* never in use */
    - g' U" N, K) Q  @        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    # T8 g2 Z! V- [
      m% n2 [$ j) e7 y$ P        pHdrMid = NEXT_HDR(pHdrStart);6 b' ^' S; ?3 H" x
            pHdrMid->prevHdr = pHdrStart;/ L7 I$ Z9 V: y7 x
            pHdrMid->free = TRUE;                        /* the main block */" u) B/ ~% L5 c$ G6 r' E
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;2 U6 y4 A2 P; x! L

    , y' c* J5 z$ W7 F        pHdrEnd = NEXT_HDR(pHdrMid);3 t4 T9 t" Y' n: o( E
            pHdrEnd->prevHdr = pHdrMid;: [! `1 A# i3 `- e# [0 V
            pHdrEnd->free = FALSE;  ]$ {) }1 }" V4 ?5 B
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;& Y& Y4 j3 z* O9 }! ?4 H  b9 V" S

    1 u" H+ @' K3 P# @  X        /* TODO take sem hear */) j" |8 c1 T% m/ R  v* R% ]  y7 n
            semTake(partId->semPartId, WAIT_FOREVER);
    ' M% C# y2 g6 U/ R, f       
    . N* f7 w, A# J  l        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    $ p; [  L# a' @" ~4 T        partId->totalWords += (poolSize >> 1);7 @" n: c! N7 i5 u4 ]! R. Z5 S6 y6 r# S

    ! @  Z( k8 K7 G; J        /* TODO give sem hear */" N3 j* L, Z% T! ~$ L) A
            semGive(partId->semPartId);
    - l1 W/ G5 E- e& q) Z/ q8 K
    " H3 y; S5 `7 ]7 i8 {2 X( d  u. v3 b5 D$ ~* @& X8 R7 s
            return (OK);
    6 Z/ r) F$ ]. }' @  b}. k  \8 U3 O9 o0 Q: E" z

    1 f1 A' K; U( B  g. Ovoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)" `9 M% i5 `* Z% V
    {- M2 c8 q. ^+ G
            FAST unsigned nWords;
    ; U: B) L! E8 i: c        FAST unsigned nWordsExtra;9 a% B% C" S- {3 S8 X8 c4 V
            FAST DL_NODE* pNode;
    $ ~# W; u8 b( v: b! j        FAST BLOCK_HDR* pHdr;9 _! a" o3 t1 U+ v: U
            BLOCK_HDR* pNewHdr;
    & k& }$ Q- U9 K* G! ~' s; g+ u8 f        BLOCK_HDR* origpHdr;
    2 q$ {" @! |" Z5 |- K6 @$ _6 B- m( Z4 k: b6 H
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */3 x- M: o2 [. N$ I
            {
    * H: X' ]+ m1 v, x+ s, T3 V2 x                return (NULL);  d7 f+ |) j/ |6 I
            }* `, }, J7 u0 o# R$ B& k# _3 [7 i

    + y, n& `1 u8 E- }& x3 i        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! w: Q5 p6 Q8 v0 I* k& ]3 ^' B
    4 i4 P! p* r3 G0 d
            if((nWords<<1) < nBytes)
    0 h, U: U$ ]% D8 {9 h        {
    5 u* T, E& g2 d  g9 h                /* TODO suspend the task */6 j% j4 J$ q. G, i$ A
                    return (NULL);
    : t3 q- [* t- x% P4 \        }
    , h1 ?* A7 n8 f5 L% e1 D, L
    & M4 H4 l$ b/ |+ o        if(nWords < partId->minBlockWords)2 h- u+ Q; [  G% H0 L
            {
    ; x4 J1 p$ ~! c/ Z                nWords = partId->minBlockWords;
    $ r  [& O# @0 u2 v# H' L) N        }/ N5 ?% y& }7 S6 K' b0 W2 A$ c
    5 z  a% o0 X8 c1 S2 U
            /* TODO task the semaphore hear */' U7 h7 c( l) H, P2 N) _4 ~' {" }0 T
            semTake(partId->semPartId, WAIT_FOREVER);. }5 F- d; M2 G# k
            pNode = DLL_FIRST(&partId->freeList);5 p! s& ^3 ~# J) j
            nWordsExtra = nWords + align/2; /* why? */
    4 M7 O* l5 z9 y6 l2 k, x- G+ c8 X# t, |! n
            for(;;)! G7 a! @9 t% ~3 l" G7 N( S
            {# b2 i5 S. ~9 b0 Y0 @* i: I: E
                    while(NULL != pNode)
    / U7 `5 T( k& u* O" b: E                {
    $ I9 W& b$ X5 J3 Q1 A) @                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    ' \& i9 B& r5 a. x0 |                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    3 W4 ]" u; }8 y& y                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))7 r$ H; G1 t5 y
                            {
    $ O# u( n2 C2 [' _0 R# W8 J- d                                break;
    - R, F! o" `6 q' G/ {                        }0 C# {" N2 `0 C' U
    , E! m) N. D& @9 S( N1 i
                            pNode = DLL_NEXT(pNode);
    2 R4 c+ Q1 E4 N' p) w# m6 U                }$ q+ I" K1 j; c  L% I2 D

    1 N2 L. q3 J( ~( Z0 e6 t                if(NULL == pNode)) r' x+ D9 q' P% [* V  g
                    {+ C, O8 L/ r, m7 ~7 p/ H0 T8 U
                            /*TODO give the semaphore */
    1 w. H' y8 _5 C; a  p                        semGive(partId->semPartId);
    6 U# J$ B* l4 i; z. @8 K  ^  {                        return NULL;
    5 ^+ P6 E' k- h                }7 ^  j4 m" ?  x- N) S/ e$ [) S

    $ V; |  x, r  F                pHdr = NODE_TO_HDR(pNode);
    , y. @6 N# E' N# K8 ?( N9 [                origpHdr = pHdr;& _  @1 V: b( b2 U) l7 K
    7 f3 c' _2 p/ A$ \& d$ c4 ?; N4 e1 ~
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    + q0 V9 E, i5 |. T& N5 P. r                if(NULL != pNewHdr)& ?( r: e0 {- G3 k* [+ A
                    {- r' c$ l0 J0 d) H3 ?4 c
                            pHdr = pNewHdr;
    . Z4 k2 H( P! B& E                        break;+ v' ]2 f( d  a( p  P
                    }
    9 u9 b( _' H/ V6 g; f( n( U/ Y( Q
                    pNode = DLL_NEXT(pNode);! H% c: |; I9 X4 Q6 P  D8 @2 z; D
            }
    % I3 ]/ }1 ~2 E# S1 C9 l
    ' Q9 }; U% Y0 i0 b) `        pHdr->free = FALSE;0 B& V7 T2 @: [$ b, v, g! _
            partId->allBlocksAlloc++;
    * M' ]% K# P& D# C7 |        partId->allWordsAlloc += pHdr->nWords;
    $ t; a. r( |: J% \/ a; ^        partId->curBlocksAlloc++;
    * k  z1 N) o/ Z( P' [0 o# X        partId->curWordsAlloc += pHdr->nWords;
    : r7 F4 L3 R- Q& `
    7 S6 {  ?0 j2 ]$ G" w" }: s        /*TODO give the  semaphore hear */& G* @) r2 `# ]. x( R2 T/ b
            semGive(partId->semPartId);
      R9 W0 c# h( `: W3 J        return (HDR_TO_BLOCK(pHdr));
    + m* r, |" M% P        $ Q6 Z+ ~3 [1 \) v+ Y
    }5 }2 d- _! S  Y5 e( U
    * ?" }+ W9 |+ Z9 s! P( N. D" c
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    * Z6 r, K) `, S{
    ) A# y! Y* b9 o/ H        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    # z8 A7 [; e' S# h2 p}
    3 d& P( o1 z& [8 m$ u6 i5 T; r% x  M3 Z5 f& x7 {% b# K: d( X1 _
    STATUS memPartFree(PART_ID partId, char* pBlock)
    ' k/ o8 s: E; U7 z! i& e1 [{
    0 t' o/ N" j) c) U8 M1 |2 j        FAST BLOCK_HDR *pHdr;$ i/ K( [8 Y" C  ~, N& s
        FAST unsigned   nWords;
    ; K/ ]0 U0 Q$ n$ P    FAST BLOCK_HDR *pNextHdr;
    ; Q3 X* d* S8 l# z
    ) L7 i, B- w2 ~& E6 _        if(!IS_CLASS(partId, memPartClassId)). ]/ `8 n0 \( m- q$ \; T! ~. c' s
            {
    4 |# e0 w' w' v                return (ERROR);. t7 ~7 q4 c3 D6 A* ~0 r
            }. D) q  X3 b3 E2 B

    ' `" c0 @& p: u% Z2 ~: u        if(NULL == pBlock)
    8 F* J0 C" h# I8 `8 G! T        {
    3 k) Y+ z- A! F- S% Q! H6 q                return (OK);
    - p* L8 l1 W% _7 _# Y5 k7 q" s2 T        }0 d: K/ p5 s4 u: ~

    1 A1 N, L3 f, i3 `/ `( H1 H        pHdr =  BLOCK_TO_HDR(pBlock);1 V* G* E; F# A9 f3 N! U7 U6 v; o
    . r/ M6 c4 G. G, j# ~0 x. [; q& K
            semTake(partId->semPartId, WAIT_FOREVER);+ E: S5 \7 y( v( |
    . t" W% B; [. O3 N& n7 o0 |
            if((partId->options & MEM_BLOCK_CHECK)- M+ p2 w( ]7 Z( g% U/ |
                    && !memPartBlockIsValid(partId, pHdr, FALSE))
    ; G0 p( q4 N9 T        {- r$ |5 I4 _) \
                    semGive(partId->semPartId);
    7 u. N% O' f+ y& I                return (ERROR);/ L5 m/ z# t* c$ E1 ~
            }
    ) [' p* K2 O  m5 L/ p* n  {2 v1 I( e" I" g% k+ Y; p8 ]: m  t
            nWords = pHdr->nWords;
    " T8 S7 R/ s, G9 \        if(PREV_HDR(pHdr)->free)
    + B: V5 i. D  |: \# F        {/* the prev hdr is free and than coalesce with it */2 O2 K5 i9 T6 X  l% f
                    pHdr->free = FALSE;
    % e6 i9 x  T- b4 f  K9 }) P$ x                pHdr = PREV_HDR(pHdr);
    # K- [( _/ ]; X% [  u' _4 Z                pHdr->nWords += nWords;
    1 X( M. \, l/ u1 P: |$ ~% H        }1 b% @; v5 c- O
            else
    ' ~% T, j; g) i) T1 ~, c        {
    - R; _8 ~; N# u; ~* H+ o7 d                pHdr->free = TRUE;
    * m; \7 R* Y9 S* f3 {7 C: T' z- H) z                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));$ q- _$ v/ l4 [, \5 e9 ^5 P
            }
    $ Q  I9 R* ~4 b% A
    ) ~. |0 |: k3 V: G% F        /* check to coalesce with the next */
    - j. [, p% U1 {0 Z        pNextHdr = NEXT_HDR(pHdr);7 O1 L7 ^$ j$ X! o! O8 n
            if(pNextHdr->free)0 J) a: M& R! @6 T) I0 Z4 [( @8 I
            {
    , v& E. C( e+ P9 {                pHdr->nWords += pNextHdr->nWords;9 |8 b  o8 l6 E& _8 O' ^
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));1 m/ K1 S1 J) k
            }
    ; I# W9 ?0 K( U( M0 S* O1 H! W* }
    / Z  e8 S. M- r' |        /* cannot use pNextHdr->prevHdr=pHdr hear */
    / P3 p" g8 ~3 S  n6 m' I' a0 \5 s        NEXT_HDR(pHdr)->prevHdr = pHdr;( F6 H$ Y. l6 l# P: o
    4 u- l1 N* }6 H1 A( O. }: u
            partId->curBlocksAlloc--;. _4 z- l9 _; s8 r+ a6 t; ]* w2 d* u* b  K: Q
            partId->curWordsAlloc -= nWords;, R( \, h: W' g6 m$ \6 ?$ P( v" W
    / r; a5 k. v8 h& n/ W2 Z
            /* TODO give sem hear */
      q6 ~" t5 g: b% J# [! d        semGive(partId->semPartId);$ e$ e0 w& o5 g, {+ g
            ; {$ o; g; K2 c* J3 {0 F
            return (OK);, E3 W6 C, t& s
    }
    3 @9 g. ]) c' l
    , E! m# Z7 T, [+ |0 u% S) j2 Wstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    : \" G2 I$ F0 v{! W' Y: |0 f6 f$ k  s0 d5 ^8 y
            BOOL valid;  }. S1 @! E) V, k& h
    ! g& y  K9 b6 {9 y4 F1 `2 a3 Y
            TASK_LOCK();
      p# _! v8 H3 Q7 D6 V5 x        semGive(partId->semPartId);
    0 M" w( p% d& q* M% P$ w1 s0 {7 D        ) _# Z0 A" t# P
            valid = MEM_ALIGNED(pHdr)
    % s% W$ [4 K6 ?8 x- `; z        && MEM_ALIGNED(pHdr->nWords*2), d1 f# r9 K" P' T% [
            && (pHdr->nWords < partId->totalWords) % Y1 p& M% ^; H- A
            && (pHdr->free == isFree)
    . d! y! e* I. Q! V0 e' _1 V1 B        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))% B& r6 Z, o( |8 k( A; d; Z
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));! T! J5 h2 J6 W9 W7 K, O. B! j
           
    ; q( q3 k/ `+ Z' P2 B) a        semTake(partId->semPartId, WAIT_FOREVER);
    , e/ y0 ~3 n! T* |; M0 E7 `4 t" M. |        TASK_UNLOCK();
    % K+ Z+ x; i5 V+ t& t3 U3 q; n4 v7 ~: M) t$ s3 M9 ^( V
            return valid;) J  x- A- ~. ~. @* l
    }* d8 }# |: f& W9 e2 k

    / m3 l  U& [  c  P5 ?7 lstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: x" [! o5 v! G9 s$ u
            , FAST BLOCK_HDR* pHdr1 o: u- s) j& l
            , FAST unsigned nWords
    / m  @5 J- i3 V/ K$ Q5 k        , unsigned minWords! @5 S; Z: l% G: M! ?) X  `' o1 b
            , unsigned align)
    ( b! e( h  o- J( f{
    $ d1 W. G: B& v! z+ R        FAST BLOCK_HDR *pNewHdr;
    3 g0 o* ?% M( D+ p6 o    FAST BLOCK_HDR *pNextHdr;5 F9 b% f0 i2 ~/ ]4 y% M0 B& A
        FAST char *endOfBlock;
    0 e8 X8 _; \2 {2 A3 _0 S" {    FAST char *pNewBlock;* q) X/ i( O6 k  a
        int blockSize;
    1 Q2 E; N# b# R) K/ f! ]8 m/ f* ?; N5 a
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);% |, _8 R' }' K

    : `, _& Y: G$ w3 m+ j) c: a        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));* ]8 B/ G; q$ l$ F, i" S9 N0 e
      u  E2 [% g+ m6 `* U
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    7 ^! L: }* N6 N: G& g6 F; ~6 ]5 c/ p
            pNewHdr = BLOCK_TO_HDR(pNewBlock);
    , `" s/ y4 q# [, R7 X
    $ |  p8 Z' j9 j        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;  L' a" u. O$ J- Z1 h. @

    % P3 o5 m# K8 u: r8 k        if(blockSize < minWords)4 f+ X4 a$ m* S% p$ }7 H+ I5 r
            {
    4 I+ Y/ ~8 Q" s( X4 m                if(pNewHdr == pHdr), @3 I* p; D- [' g6 n/ Q- T
                    {
    0 D$ b  D4 ^2 a, T/ e: }$ O! }                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));' h5 p. m( }7 K! F8 L
                    }0 h9 s& y) [: a. W0 H; D, l
                    else( X" w' J/ H4 `/ W6 r! a- x6 N
                    {+ ~- R0 j; ~$ I
                            return NULL;
    " W: C- K: t$ a( }/ s! J                }
    # G5 Y2 B7 ?3 N9 a# C  d        }
    0 D3 o& G# U  p. o' y        else
    $ Y- W; `* T% x- Q6 ?& l+ E        {        /* recaculate pHdr */
    4 U0 J1 u9 |: W                pNewHdr->prevHdr = pHdr;2 b" V- W( C8 g$ ?4 ?5 b, X2 n
                    pHdr->nWords = blockSize;3 X, ~$ g1 h  N. j& R
            }! n2 j/ U- C" V- o! d8 ]7 c

    ( G& Y# Q+ q  @2 L& H        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ' x0 q0 \2 P! w6 p; {        {
    " \1 V; r; k7 x5 H. {& F: X9 ]                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    - L% a1 n9 n9 h7 ?7 i+ Q                pNewHdr->free = TRUE;
    9 K4 `( i2 W5 s# {$ U! g. U. A5 i- W& V2 v- \; k
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
      ^+ U* S6 X+ L5 L7 B        }: L. H8 s/ e9 j( m5 B/ p2 s. Y7 E
            else
    , B2 H! P8 f4 ~$ D, b        {/* space left is enough to be a fragment on the free list then */; d* |- m4 e% Z' |
                    pNewHdr->nWords = nWords;
      c. ~6 l- _: T                pNewHdr->free = TRUE;
    $ j0 c# N9 T' d* }8 G0 [$ @
    ! ^% [% v1 D- r2 f. S* W1 m                pNextHdr = NEXT_HDR(pNewHdr);0 V$ ~) a" i' ~  z  j; M: Z
                    /* words 包括BlockHdr */
    , \: y! w. L! H0 c* O0 v                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;' Y: t! c$ d& N  K$ N! D3 p
                    pNextHdr->prevHdr = pNewHdr;. G. l, |2 z5 |: i1 I" z* T
                    pNextHdr->free = TRUE;
      g2 N( M  k% e/ |* P
    * m. g: z% D/ Y) I                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    , J& x  p: \- D4 J8 g- U
    $ R. P; j" l$ D# _% j  n                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;0 f0 t% n: B0 b& E' _6 K) \, d
            }
    8 I& [& w* x  w, S9 ]" N( r" x/ E/ }# q7 u/ `% A' G
            return (pNewHdr);, }; z. ?2 G, T' R6 W0 Y" I1 h
    }$ N+ Y4 I8 T1 C

    / E" P$ t. o5 c# hstatic void memPartSemInit(PART_ID partId)
    : M/ P7 y( p9 @6 d: G{
    5 L! H+ f7 h6 ~; F. j        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);( M% F+ S! \& w
    & m1 q8 X: p" v2 i9 c
            partId->semPartId = &semMemSysPartition;
    " ?( Q6 g9 w# _* u, J5 y}
    0 c- y( C6 t- p- b' [* a/ Z. G! c$ `7 M8 ]
    void* malloc(unsigned bytes)) P1 X4 P" g* l7 l9 H# y3 W
    {
    ; V) T" Q5 t  T5 P  U; w7 [# _        return memPartAlloc(memSysPartId, bytes);
    7 u* b! L! j5 a0 c}; Z5 P' p9 r( M$ X- t: X  E( ]$ ]
    # `7 U5 I+ U' @. r; O7 N
    void free(void* p)
    1 Y. Y1 Z1 I# S5 v& j% c{2 L5 L4 I1 M6 H' h
            memPartFree(memSysPartId, (char*)p);% W6 @! a/ F3 |1 N( |6 q! S% {
    }% ?% ]* r! E( F, C5 f
    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-7-19 11:10 , Processed in 0.392093 second(s), 51 queries .

    回顶部