QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2878|回复: 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++下的版本,更方便调试。有需要请留言; @6 a7 y( E: F$ S( T. |' e" Z1 a
    " [2 [- Q* b3 B. y

    . l/ i5 i( G. z0 a) o7 p, x9 y8 E! F9 x. n0 I4 N5 k
    *\file9 \, P% o0 e. b/ s
    *\brief               
    / G1 f2 I+ ~/ `& i3 e: z4 t; S *\details        9 t8 p! K! Y& m, y7 F* R* g+ _; J
    *
    , Z% y  B" K9 v& V2 n *\author        Janson9 S9 v( Q+ ^) |3 X, D1 i7 u+ O
    *\version       
    " S9 L) ^4 e( s *\date                04Jan122 Z; _. M/ d( p* ]! \( I# \7 L# c! K% z: t
    *
    ( u* P$ i6 b/ C5 Z *\warning        ; U1 V& q8 q  G2 f. ~
    *
    ) D$ ?: c4 G6 Q7 p; H *\history \arg        30Jan12, Janson, Create the file" r# d) r2 C3 [5 r& @. r
    *        modify from VxWorks source
    + c" i6 U, C! H; E: j* l *  Legal Declaration: it is for studying VxWorks only.
    & b0 F' ?+ M3 p */
    & L% e. \( Z5 _0 n" Y* V#include "includes.h"
    / L$ W3 p! r$ k. p+ J* t" o
    , D# B+ B# ^) d* K) Z# V/* The memParLib.h file is hear:2 J7 k3 N4 f/ G6 H0 I9 f& e8 i9 r
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    - b5 \7 P8 [* p# v  u/ @*/
    2 D+ m" I6 S1 X0 X0 ]" M  G
    , j. G3 K! l! y- l/* optional check for bad blocks */
    " [$ m# u: g) A# M
    ; s2 e9 V$ N9 O" a7 Z#define MEM_BLOCK_CHECK                        0x10
    , W! q/ i; `/ f. v! x3 c6 \# s1 r# A+ b! I& v/ Q( x
    /* response to errors when allocating memory */
    2 W$ a% N3 q: ]  V% ~0 g: m! L4 X
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x204 W5 z" V8 a6 m  `+ r/ p& F- u+ V
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40. }3 p7 Z3 _. ?3 `* i+ _  _/ ^. M( I+ {
    ; ^* B$ U4 {' u3 D  W
    /* response to errors when freeing memory */
    . j. `7 t+ s6 S4 x6 E
    ; {3 G7 h6 b! m#define MEM_BLOCK_ERROR_LOG_FLAG        0x80. g0 J2 u1 W/ ~! N+ V
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    9 K0 G, {; E3 M; V' q' m  p
    5 c5 B/ I8 G7 y; n' K# A* o4 q#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    0 t3 Z5 L2 U  j( S6 t6 m) l#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    , e0 O5 }& u$ o( Y+ f7 N
    # d! r$ W3 a8 G+ }& Y8 M#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))# |$ D' `  N# [. B; k
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \4 e' L8 y& T2 G+ m
                                                    sizeof(BLOCK_HDR)))
    " K9 x& p. {+ I
    % p2 w" ?/ o% n6 R( a' E' P: X8 M#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)9 ~7 f) Z/ n( M! k- F( c4 [4 o* b( Y* K/ [
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \" `- m+ j* N" p. |
                                                    OFFSET (FREE_BLOCK, node))): t& {0 R5 `- o. o0 k1 y5 h+ k- s

    $ [; |) P) Z3 P" N* a/ J& J: Fstatic BOOL memPartLibInstalled = FALSE;
    $ \5 J8 j1 x( @( o
    + U2 @  h* T' f3 V5 rstatic OBJ_CLASS memPartClass;
    + F' M: V* {' Z2 UCLASS_ID memPartClassId = &memPartClass;
    + X/ X3 U7 m: v' L2 i. }7 k% E
    7 x8 x4 D5 `) Z" k5 _' @static PARTITION memSysPartition;3 X3 _3 J/ A. ?; x% g- Z
    PART_ID memSysPartId = &memSysPartition;
    / k$ `& m5 U2 ?2 }, ZU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    / _  M$ P" h7 M# b  C* O% O0 k2 o  K% k; i  T) |
    static SEMAPHORE semMemSysPartition;
    9 O5 _! M' J, O- J( M! e7 @: Y9 N
    4 l  t8 L: S# d9 ?: g! wstatic void memPartSemInit(PART_ID partId);
    & f# c% R' X0 ?- H' j' J) h; A) \- l/ [" G
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    / d- w2 d3 ~6 c: P" l
    5 c: u' Z8 U. r( O0 lunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;  w1 j3 e, s4 L+ `, N

    / A' t( [( A+ C9 cstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);$ r/ P' b% K& s8 b7 n: K3 B* [
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId, L' E7 C$ h4 H
            , FAST BLOCK_HDR* pHdr) K( Y- ~0 C$ q" a' w1 v
            , FAST unsigned nWords9 h) G- I, @) f/ T
            , unsigned minWords
    * r& {- C7 r1 m8 P  H6 g% E        , unsigned align);
    4 O- B3 a. _; L# w% f9 P; n
    ; x* w5 {8 ^& v5 o/ b8 D5 ]static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);& \: T2 }6 \7 w  E9 P
    ) z- S1 G6 N6 B1 J( o. D! P
    STATUS memPartLibInit(char* pPool, unsigned poolSize)
    1 c$ g0 q& f& g, e6 z{. Z) h4 I, B* l; b8 U
            if((!memPartLibInstalled) &&
    / y& j; b9 w% U: x: Y. E                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)# {. b( q% k/ }: L. g( r2 y
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
      H! A- f: s6 i& f        {
    - G9 k) N3 l3 D4 \                memPartInit(&memSysPartition, pPool, poolSize);) q% {% q- a, m" @3 y
                    memPartLibInstalled = TRUE;) @# d6 N* {  \: M' ?; c) X: U5 x
            }0 m+ b& g+ T9 F) c+ U/ v: z
    7 m0 V% h6 |6 U) I
            return ((memPartLibInstalled)? OK : ERROR);
    2 a' k! C* x! ]9 i# R, z9 o}; k6 H1 }. |' Q. ^& x3 ]
    5 L' }! T. z/ t( O5 G6 a9 V
    PART_ID memPartCreate(char* pPool, unsigned poolSize)3 W/ T  P  I; F1 M! }6 q- i# n
    {1 g/ ^# [# O& \2 c/ ], |- n3 J
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);6 W# Z3 V9 s, G
    5 L+ M$ [# ]. |1 `! i5 M
            if(NULL != pPart)7 r$ e% ~5 b* E) S# Q* h
            {+ M& V# I$ o, w1 _; d
                    memPartInit(pPart, pPool, poolSize);
    3 O) x0 j$ V: u, {+ {* b& b        }
    , o: x! o0 U" E4 y' L
    , X, E, K+ B0 }9 g0 B( x        return pPart;
    / _- @$ |# u* a/ c( Z( f8 ~( P! k( M}
    5 x9 ^' _, c; R  U2 L+ W: M) g$ o4 `% a, B( N% u$ G" c. S9 r& X
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    : f7 ^6 t0 S' ~& [9 w+ K  G{
    $ [6 V; V! a1 I+ b, v. X' w        memset((void*)partId, 0, sizeof(*partId));
    + d: U7 Q. `; J% f. g4 f, v' K+ h8 c
    5 G# f& B4 o, F5 c! L0 B; z        partId->options = memPartDefaultOption;) D* l# Q7 X4 l/ d9 X
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */1 I3 G9 y2 Y- ]! Y1 X- r7 X

    & y4 }' C/ ~% a8 z+ o        (* memPartSemInitRtn) (partId);
    4 d8 y! t6 _& v* P5 |        ; _! c0 Y) Z( a' L( u# F
            dllInit(&partId->freeList);
    * n- ?- N; B* N  Y8 Z' P5 j        7 e! H: h* k  O$ G1 a' v( Y( V
            objCoreInit(&partId->objCore, memPartClassId);
    : a8 A# N5 D  V. S4 c5 k/ ?        8 R$ K$ g) v$ {- y
            memPartAddToPool(partId, pPool, poolSize);
    6 v, d; r2 U1 k* a}' p' j! K5 p% L; i: m3 F
    : J; o1 p! r. ~# x, a4 K' t
    STATUS memPartDestroy(PART_ID partId)% m% {3 D5 Z+ P) `4 D5 F4 ~
    {
    , z+ r6 I$ F/ W9 m2 H0 g8 z        return (ERROR);% o/ u: E& S9 `: \! k
    }/ }/ C) y' j7 ]( \; n/ z/ j
    . ~- i- L, L9 V8 `$ k
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    + ^4 ?4 N; R2 R" L$ \{$ I1 C1 t; A; w/ X3 [( B1 R6 b
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    + h4 Y, X9 Z& o7 ~}
    / x. x/ {# [$ G& ?8 t" z+ b4 j8 m% _  ?+ T; Z3 b6 Z/ O( i
    ; k: Z3 k) N2 v. |1 I! v* T% Z" i
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    6 j! y( [) }0 R( S2 b5 _/ ^8 P6 C{
    8 |  b3 e* j* G        BLOCK_HDR* pHdrStart;' N, |; g6 e5 x$ w) W
            BLOCK_HDR* pHdrMid;
    7 E2 h2 W) y+ y2 }! n: ^1 |        BLOCK_HDR* pHdrEnd;: e% E4 Z# H; C, p+ C7 m; M
            char* tmp;, R* s, i0 T! N  a
            int reducePool;
    % n: {& I1 x$ J6 B' _4 J2 A- u  S; X. v6 s' g
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    1 G' z* {' ~" r2 W        {
    # e$ h5 e  g. d  Q: s                return (ERROR);
    # {1 e9 l2 e3 V        }, L. X9 Y9 K( G, a+ O
    : _. ^! g" \1 d6 e, ^0 Q% w
            tmp = (char*) MEM_ROUND_UP(pPool);. a$ E: S1 V# k5 a- }8 a5 u
            reducePool = tmp - pPool;8 Q( a/ Q  D) R4 M! l" Z
    % g3 t, e2 F  E; t' q, @* e+ Y4 m; e
            /* adjust the lenght */
    ; b( T9 a7 C- r; l, u7 y9 C1 P) X        if(poolSize >= reducePool)0 `8 [5 {7 r0 E4 a! Q0 d
            {$ ?7 W6 C' N9 W6 [
                    poolSize -= reducePool;  r- b6 x+ R4 C# L
            }
    ' j$ V. G& W/ B/ _* C+ [7 |        else
    * b% v0 e# d$ k        {0 ^' O5 {6 ?7 R1 g! Z
                    poolSize = 0;+ P- f7 B$ M0 S
            }
    - {% V% K% A9 e" c4 R1 {- }        pPool = tmp;$ t. h5 y3 c0 a8 |8 @
           
    ; s& n9 L, i/ |/ s8 l        poolSize = MEM_ROUND_DOWN(poolSize);
    8 y# D0 l+ ^) W( G) }: I       
    ! U4 N# |) Y0 G7 a7 R        /* at least one valid free block and three header blocks */! H* w, Y( @4 U9 ]) I0 W  m
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
      s  P* W% P2 I$ x4 V3 c        {
    2 H& r2 x7 Q! ?% o$ W6 L                return (ERROR);( f! I3 `" B+ Q, b- g  B
            }) F+ y+ B, h) X' W2 I" F

    ' z9 V6 r* ?( L7 _        /* initialize three blocks */) f! a5 d, w) X
            pHdrStart = (BLOCK_HDR*)pPool;
    : G- `7 z  e% E) [        pHdrStart->prevHdr = NULL;
    " [9 q; F- s8 P; G' [. \; V; q        pHdrStart->free = FALSE;                /* never in use */
    " T$ |$ }# B; T. H  L& _        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    7 I! h9 y! ?. Z  b6 v0 i; C
    , \- u7 y; V  c; _' D( x& |        pHdrMid = NEXT_HDR(pHdrStart);
    , V! |4 S! e; b0 s        pHdrMid->prevHdr = pHdrStart;- Y% d$ _2 ~" S% Q! `- D& O% [
            pHdrMid->free = TRUE;                        /* the main block */  H8 t9 q  D, {9 p3 n  {  m- w8 Z6 |
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    ; Z- M( F% R4 z6 D1 Y1 c# t  J3 K9 G
            pHdrEnd = NEXT_HDR(pHdrMid);
    / G4 g+ `: |: c8 y        pHdrEnd->prevHdr = pHdrMid;( }1 T% N1 C# h( E
            pHdrEnd->free = FALSE;/ r0 b! r. V4 h, x' U* @* M, h
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;: j, ^  |4 F/ E* I. G  k, Y

    3 d, O. `' T( v; N        /* TODO take sem hear */1 T; b7 {% B4 z( m, P
            semTake(partId->semPartId, WAIT_FOREVER);% v# w! y# \/ n
           
      W: d* a' w+ L* o3 W        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    & B% b$ t$ h! U1 X. V5 a        partId->totalWords += (poolSize >> 1);
    / Q+ D) U0 A! j/ ?" D- M" V
    2 C% b- J' \. X" i* y0 J+ i        /* TODO give sem hear */
    4 v3 o4 }+ b7 [: G        semGive(partId->semPartId);
    7 ]& g! N; v5 e8 Y  x
    ' }- I# O8 o+ k2 y; j( d+ Z; Y3 z8 w& i1 R
            return (OK);
    2 K- B7 W6 k6 f2 E- v$ v; c( l}
    , L2 S5 o5 X; n$ i
    % p+ w9 R! m0 ^1 v9 N% svoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    9 K0 H* ]; Q+ y) R& v{
    3 v! Q' N3 _0 I        FAST unsigned nWords;
    4 g( X5 {; ~( i  t, r4 t' W        FAST unsigned nWordsExtra;
    2 c' s1 `! M1 ?' e        FAST DL_NODE* pNode;) Q* R( E, z; d
            FAST BLOCK_HDR* pHdr;
    : E- ^! l8 G& {) G        BLOCK_HDR* pNewHdr;3 o/ y! h, _! U( \! l2 I' i
            BLOCK_HDR* origpHdr;" S" O) b: D8 i, A7 y* p
    " p, p1 b7 P! @) X* q
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    . t7 |) q; K$ U        {& d$ V2 J/ y/ u7 S. r
                    return (NULL);' e5 ~5 d  k, I
            }
    * S! p: L, `  W" R8 T
    2 R7 E1 e& v7 h  t' Y1 |        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    2 e* L& M( v. B. T2 l/ N9 S1 ?; Z9 s5 U0 M& v+ a
            if((nWords<<1) < nBytes)0 e2 A, ?0 ~& o. I; m
            {# g3 A/ t/ B6 m8 }: @
                    /* TODO suspend the task */8 s/ c: j4 \1 F4 T4 a. a' N
                    return (NULL);
    % O! Z: ]/ e; b2 c& [5 T        }4 y5 p- O. c, n0 n6 U4 P3 W0 G. M

    5 j' ~0 e" M$ |$ O9 ~/ A        if(nWords < partId->minBlockWords)
    8 Z$ U6 b  ~6 n5 W% W& e+ U1 e        {7 ~6 p5 o$ l1 O. `% l5 A0 k
                    nWords = partId->minBlockWords;
    2 O( [3 c2 [' M8 [- p* ~+ X        }) w* h. C- ]. ?5 G7 h# v
    , f2 x0 A- M4 `$ {: V; ^" F
            /* TODO task the semaphore hear */
    " |2 }2 T: L. f, |        semTake(partId->semPartId, WAIT_FOREVER);$ b/ n8 c) ?$ N
            pNode = DLL_FIRST(&partId->freeList);
    . P$ j. F( P. v2 }        nWordsExtra = nWords + align/2; /* why? *// k0 o  b! S" {% @4 o" D  q6 O3 E
    6 C7 ^0 o) U0 ~( y
            for(;;)
    ! R- @5 c3 j* E: [/ [; I4 k5 L        {
    ; c; M3 ]) I  p% [/ f5 f                while(NULL != pNode)
    4 M. K' s2 ]. N+ [9 Y8 K; v6 N                {
    6 G  L. A; I! H: S) y0 a+ d3 L/ |                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||/ A- R8 d. v* t  Z
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && ; i' Y$ \  H+ Y4 @8 G, u( O/ _/ Q
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    $ d0 B6 x7 i7 U+ K5 O/ |                        {
    3 q% `/ t+ t+ E' Y! o  e9 N                                break;1 F4 d) m; S& Q1 S5 }& C( W& n
                            }
    9 H- [* O: B2 a; `; j
    . S' g( N0 b' V3 V7 m  d4 P                        pNode = DLL_NEXT(pNode);9 f( h5 ?& m8 U, \1 T- T; B( o3 ]
                    }
    & {- z3 X) V( b" |! T0 J! e& x+ h$ k" i, }' G
                    if(NULL == pNode)
    % Y9 R# X  T8 j  u                {* F$ ^- h2 [# j! J' g$ K8 B
                            /*TODO give the semaphore */
    5 D/ w/ {- U" F* I7 |3 K+ R, Q                        semGive(partId->semPartId);1 U; @& l4 D4 }# c
                            return NULL;) r4 {& o7 f/ o7 o1 o2 v8 u
                    }
    5 J1 s! U( B$ a4 H
    4 W. P, W% R1 S4 Z                pHdr = NODE_TO_HDR(pNode);& q7 D; a" o$ u  A& T
                    origpHdr = pHdr;
    ) J8 ^* V' n  w1 _! C. K0 w
    , A: n0 s1 S! S- C6 i( N& g                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);5 [: J8 d* \9 q5 F. u
                    if(NULL != pNewHdr)
    : F2 j+ i" O6 t: V  R9 M                {
      _  g: L1 }. Y" P                        pHdr = pNewHdr;
    # w- [( |+ @5 P8 o0 A3 l' J* Y                        break;* x! A' {" @. [4 q1 |9 `. s7 U# N
                    }
    # p7 ?: e& X' @- g- x1 K5 l  K
    * O+ `3 U# x+ j, I& @                pNode = DLL_NEXT(pNode);* b) A! l% H: I
            }
    4 g5 Y! Y5 e5 r& l
    ! u" d3 t& l0 Z% x% N% G        pHdr->free = FALSE;
    - x) [& H/ ~7 f0 {9 J* p9 @        partId->allBlocksAlloc++;! E3 y) ?( m0 u1 G$ a
            partId->allWordsAlloc += pHdr->nWords;
    7 m$ q' w3 a! |+ N2 Z' P( R        partId->curBlocksAlloc++;( K( T/ {6 t% ~9 Y1 a
            partId->curWordsAlloc += pHdr->nWords;/ W1 Y2 Z2 i, H7 P. y

    # T5 r( ]: B/ ?6 |. V3 y  k4 Z+ i) x        /*TODO give the  semaphore hear */& C4 W" ^) s, c8 S7 N
            semGive(partId->semPartId);9 n: h+ G6 d) |6 W* r* @8 q& Y
            return (HDR_TO_BLOCK(pHdr));
    9 c* A. K3 Q, K) M" n$ i        9 q/ }( b2 a9 o. Q. y! Y% i
    }
    & b0 D7 g: W0 i0 T/ C
    1 \9 ^8 W2 F) [" }' bvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    5 l* p$ v) q4 W! n{  M0 J: X+ z8 ^: a
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    $ b" [' a$ V* F! t* `}
    . @& ~& C4 r0 J' w2 d& g& `. j9 e+ t* T( Q# L0 W
    STATUS memPartFree(PART_ID partId, char* pBlock)( C' V- y. F* M3 U! U* U* U
    {8 E- s' K! s: u- e: j
            FAST BLOCK_HDR *pHdr;
    1 L) z6 T& F5 e$ ~& t5 c    FAST unsigned   nWords;/ O8 J! b  Y9 |9 M  F
        FAST BLOCK_HDR *pNextHdr;# p7 _$ ^- z+ N
    4 Z+ ^. v& p9 L/ k7 U! x
            if(!IS_CLASS(partId, memPartClassId))+ l& Q! O  ~9 A! ^+ W% b% N
            {7 \% U/ j' L3 G1 n" H
                    return (ERROR);
    - D) C$ q% R7 d( ~+ r( q+ V5 {        }
    , J- \: I# s. _8 [1 e# v$ U& ^- A0 T* S( \/ o) a9 S, S1 }: Z* l7 e
            if(NULL == pBlock)
    8 F: [+ t7 j( l+ {5 m& x/ ^+ k( c        {  g3 w* s' @) c6 y0 z! o" A
                    return (OK);
    9 L9 ^9 e* s* A/ C        }/ {4 J7 u" D0 d9 B' H

    3 N6 r/ V! w, o8 m4 M& K- Q        pHdr =  BLOCK_TO_HDR(pBlock);, d; ?# I8 r( }

    9 f8 Z# c/ U* L4 b) S7 `$ k* n        semTake(partId->semPartId, WAIT_FOREVER);0 c& M: k- X/ N8 F* Z! K# \
    ( ]( A* u) P# B5 y9 Z% h# t
            if((partId->options & MEM_BLOCK_CHECK)
    2 Z+ ?, G- m5 R6 ]; o0 |                && !memPartBlockIsValid(partId, pHdr, FALSE))
    / b5 E! z, @$ u8 \4 |        {
      d8 L+ o) z1 U" E( Z% K                semGive(partId->semPartId);
    3 ^  F! N0 d) h/ w  g) Q$ J* E& l  i) K, ~                return (ERROR);2 t( |" J) j, n7 Y2 R9 g6 A
            }
      E5 R& d+ ]) g$ `2 D
    1 c0 M$ q# J; y6 o( P        nWords = pHdr->nWords;4 D% x* R) z4 J% o& C8 V
            if(PREV_HDR(pHdr)->free): J) k  ?( L+ X  C) [
            {/* the prev hdr is free and than coalesce with it */
    : P. K  I6 ~0 J0 Q1 X/ g                pHdr->free = FALSE;/ q4 p/ V- Y8 x; z& V
                    pHdr = PREV_HDR(pHdr);
    - B. \. T; q3 u; Q+ Q4 \2 k5 \                pHdr->nWords += nWords;
    ! |* n8 K2 ?5 V/ U, n. K1 ~  }        }
    : R3 J+ \3 ?& C0 O        else6 F; ?% ^+ [& l! S/ ~
            {$ Q; y0 Y4 H8 l- S; F
                    pHdr->free = TRUE;, O  m  C4 s4 a4 t# ^1 |
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));7 k) W8 v$ c; u; E  f
            }. M4 b! |4 |' u; v0 m3 Q" |1 p
    7 J( r+ F) G) q* k5 l
            /* check to coalesce with the next */
    $ c7 r+ G5 V$ y6 k9 Z7 G        pNextHdr = NEXT_HDR(pHdr);
    8 ]; @) w4 l+ c        if(pNextHdr->free)6 F$ ~$ ]- A' B; s& Z3 N# d2 _& n) B
            {
    * w: a9 M  @( D3 ]3 e2 V& k, X                pHdr->nWords += pNextHdr->nWords;) X- |! l. C$ Q' r
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    3 }; A5 B4 p, A8 v9 j% h  d" U4 v        }% D+ f6 q  \* \8 V4 o

    : d4 H  k6 h! ^0 X9 O3 v; F: ^        /* cannot use pNextHdr->prevHdr=pHdr hear */" G/ c2 Z; i" L3 ~; [( M
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    * D0 \* q# F( W, U1 [' J8 ^2 j
    . m" a0 E3 S4 o9 \* z) a        partId->curBlocksAlloc--;0 l1 ?( G; e1 Y3 f
            partId->curWordsAlloc -= nWords;0 U9 d: m1 V3 N0 Y* j' j
    ; R' A# T/ p4 W  _7 v) M  i8 e3 B+ z
            /* TODO give sem hear */
    6 V' v2 g0 z2 k& n; @; I  t# I/ {        semGive(partId->semPartId);
    3 M! @* y7 g, o: t9 I) Y0 e) Q3 s        + a( t4 S' ^( d) c/ ]
            return (OK);* V) [' `( X7 Z: U# ?$ m3 ^
    }+ u6 n3 ~# d7 h% J3 K& W

    1 ?* x. q- v- q* a5 S1 M2 Y$ Kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)7 K8 a7 W* I! {6 n, k- g9 ~- D$ N
    {3 P1 B; L- K3 c9 q
            BOOL valid;
    & p3 A1 o1 N  S0 {, h  T0 r2 W/ h" c
      N" N1 j% K1 t        TASK_LOCK();
    # {  V3 y" H! U# A" b3 \        semGive(partId->semPartId);
    4 d2 j  s; L$ F" J1 w! j, }. @9 H       
    5 ]/ ~2 c: M7 }5 w8 Y        valid = MEM_ALIGNED(pHdr)
    : d- {1 \6 c( v# B( G        && MEM_ALIGNED(pHdr->nWords*2)% m  J3 v+ ?& A' w0 |
            && (pHdr->nWords < partId->totalWords) . X9 X6 y6 y/ D" Z& b) j0 }: G* R
            && (pHdr->free == isFree)* o9 y5 \. m, v& Q, B* w' s2 F
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    5 H( w" s4 k2 @, R+ H( j        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    ) b4 T) P0 _5 M4 D) S. ?+ T       
    - i. f( N5 T- W; q$ w$ [        semTake(partId->semPartId, WAIT_FOREVER);
    0 H+ |/ Z4 d* G* v  _        TASK_UNLOCK();
    4 _; y- p" i4 H! g& J$ ~, x1 H8 @5 c+ w! ^( f" O
            return valid;  \1 H" Y& e4 P3 i
    }
    $ ?& k; X; e! O  g. P1 ]- k( {4 o: E. F
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: d5 Z1 |3 H7 N
            , FAST BLOCK_HDR* pHdr3 y- _( X5 _4 g6 v& K4 B: P  w
            , FAST unsigned nWords: j8 D! [) ~+ g# b" d
            , unsigned minWords
    , x  q9 L: |" [9 u0 U        , unsigned align). B/ E8 `5 n- w6 h7 A
    {
    ' _* X3 K- Z1 `* X; I- \        FAST BLOCK_HDR *pNewHdr;( ]1 N$ Q' X% C1 C5 X7 W/ l
        FAST BLOCK_HDR *pNextHdr;* x; [% C3 E5 N+ v- @
        FAST char *endOfBlock;
    1 a; d& R6 O' k* u+ r, r* ~0 I    FAST char *pNewBlock;
    $ Y" I) I+ b- B4 M( R    int blockSize;8 |7 _2 d  i3 R5 X8 Q0 S3 ]
    9 e3 W. v6 D% b3 m
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    5 X4 P1 ^, ^/ h  I# }* m! t! s7 S1 T) t/ d( F, \
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));: L; E: L- d# V; `
    & `! j' K+ J# C1 [7 i
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));" P  ?& ~) C! M! L
    8 w5 ~% [$ _8 |- \
            pNewHdr = BLOCK_TO_HDR(pNewBlock);
    ; I3 I; _9 p0 a; H& ?4 v$ a5 L$ d% e5 Y# Y0 X
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;6 H3 C/ v8 I4 ?
    : h1 ~' {- F( k8 X$ P; d
            if(blockSize < minWords)# S- ]3 n7 x" [; x9 {
            {
    8 O2 @% y2 O( a( x+ q/ p3 T/ O                if(pNewHdr == pHdr)* ^6 P( a  E: o4 s
                    {8 K! Q  u* M' q  [* {9 H
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    , x) z2 e) s: n' @, r5 K; [+ l                }
      b/ Q4 Z* o3 T1 E9 t  m4 C                else9 O  a- P; p8 \' i: o( y" t- A
                    {. e  h, A0 u2 J+ {
                            return NULL;
    ! _- U. U5 @. _, h                }' q+ @2 l: O9 q
            }' O2 |2 W! L0 q% w9 M
            else
    1 b6 x" v$ s" g        {        /* recaculate pHdr */+ ?" [0 K3 {3 r" ?3 e
                    pNewHdr->prevHdr = pHdr;
    0 q: l: e" _$ H" c6 ~                pHdr->nWords = blockSize;( W! Y3 E6 o% K9 A% Q5 ^0 F2 `
            }
    - R, w8 Z8 n1 l% `# N* x4 J4 b- m7 {
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ' g" L2 \/ n. X/ ^# \0 v+ G6 d        {4 y8 L' s! C& U3 g* G! N; W* U
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
      H) r% t! G% u4 K( @                pNewHdr->free = TRUE;, r5 w2 D! F" n

    : a2 j: N- d/ T) ?                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;( D$ V; g  \6 N* n3 w% Z  h
            }
    5 K- M! A. x% L" @9 \6 {        else
    ( o. M1 L" v& D        {/* space left is enough to be a fragment on the free list then */
    7 Y7 E/ j7 T: G+ H6 a                pNewHdr->nWords = nWords;) Z  G7 t( k5 q( w, p" p! X# F4 N
                    pNewHdr->free = TRUE;* c* b$ f1 T% f" ?% V2 t
    ; }$ ]" Y* q7 i. |- B0 {6 S' T. h& I
                    pNextHdr = NEXT_HDR(pNewHdr);3 q8 ]+ o& b5 o% ~# H( L! m
                    /* words 包括BlockHdr */
    0 H' j& v3 e0 `- J" Q) ~; |- g                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    - Y+ u3 W- l' j+ ~9 a' }' ^                pNextHdr->prevHdr = pNewHdr;
    1 `, ?( P. G! g- k                pNextHdr->free = TRUE;7 U( ^/ e2 |5 j9 e' e

    6 e1 ]8 T9 k& e- H4 J# Z                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    4 o6 w4 H9 a5 j8 ^: x% ?: E
    . d, x1 z: e( K4 Y                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    9 l1 Y- ^; p7 e  \        }9 _; ]: F9 J. B2 B. n

    , Y4 g4 \# b$ \1 {  V) r9 D7 z        return (pNewHdr);
    ; o3 Q* q, y9 z$ M) v}3 ^0 j0 m& h, G$ J+ M/ A/ K

    # ^, h- N3 P$ z6 Jstatic void memPartSemInit(PART_ID partId); I% k5 f3 L! ^+ W0 O
    {/ d8 o- }4 W' z6 f0 D8 _
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);0 I/ [  p1 ?$ }8 j8 b! v. |
    ( c5 I0 V, }9 h9 ~6 W3 @- S
            partId->semPartId = &semMemSysPartition;) u7 J6 G; K( O, k1 n6 T; a
    }& Y* p! C" b. E6 e9 w5 T: e- n; u
    & ?3 H9 O8 v  l! h
    void* malloc(unsigned bytes)* l7 H2 v8 B1 G$ v) \/ C5 b5 c: \
    {% G3 e! c2 _! x+ ]- Y/ H& [
            return memPartAlloc(memSysPartId, bytes);7 {- ^6 H. z6 w2 p& Z5 j
    }! W& Q' X! j% S

    / N. {. D) i2 W) k& c0 Cvoid free(void* p)2 V0 [# S! y* Z; V  W
    {
    - q" |; [/ |4 U, J6 q7 U% R        memPartFree(memSysPartId, (char*)p);
    4 h6 W# o4 N4 ^( O}1 G+ r% E! {: D& t. }- G: l' B
    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-18 22:20 , Processed in 0.426050 second(s), 50 queries .

    回顶部