QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2861|回复: 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++下的版本,更方便调试。有需要请留言4 t$ @4 {1 h1 M* N

    9 M5 B6 Z4 H- I! M% p! Q7 x& z. d; d3 d- }, N+ l" x" F0 E

    ) d" b* N2 g) W; ]; j; _ *\file
    1 E0 c! {  k/ V$ O! t4 m) [ *\brief               
    $ a* E& R! M! G7 M6 v *\details       
    ; k% h( X  x) X6 s+ J6 r9 B *% v$ Y* p; `4 T' }1 `4 u! R- {2 U. e
    *\author        Janson' z) S2 `6 A. I% L0 i
    *\version       
    2 b& t7 k: n% g *\date                04Jan12: |7 ~, Z% r4 A7 M
    *! T. A1 N6 N7 Q+ v  ^1 G
    *\warning        / o+ G/ e3 x: f5 _
    *' i* C/ L  ]0 c+ a' b: q/ k
    *\history \arg        30Jan12, Janson, Create the file0 l  O' l! Z# ]; D0 e/ ^$ |% c
    *        modify from VxWorks source8 S, q. q6 T- `9 r4 Z0 A1 h9 r- Y& v
    *  Legal Declaration: it is for studying VxWorks only.
    ( Z$ E, E# I0 o5 x. q8 W* S */
    4 G- P: ?8 |/ ~#include "includes.h") e  z/ Z$ B, z  D
    - H' s& N# |( P- ]
    /* The memParLib.h file is hear:' v8 g: M! ^! t/ Y, ~5 ~
    https://code.google.com/p/vxwork ... rivate/memPartLib.h2 m, L$ q8 G7 `* n) W7 E' T
    */5 [* R- b) [* a/ t
    3 _* S, j9 X  k( h5 m% W
    /* optional check for bad blocks */
    " f( W. X9 O2 c) S2 m" h* N4 r* ]/ a- X
    #define MEM_BLOCK_CHECK                        0x10, G% ~. g+ X0 a5 `9 T) s# R
    ! ^( A; O, k9 t: M
    /* response to errors when allocating memory */. N" c( K/ c/ w. L$ ~, M
    # u& n# }- ]$ l$ F5 G: p' N
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20' k1 g# }2 Z( z' F& K$ S
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x407 f; p4 R( r" N+ ^/ G

      D. c$ K2 X3 U5 m& e" _/* response to errors when freeing memory */
    + d. G0 D' F% U% i* ~& v& p$ ]" \' d) v$ s. F5 x( O
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    - q! `5 O7 b) f% Q#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    % ]. S4 h9 Y& t3 c8 X, d1 r- K- Z, v0 a7 s, c. `8 z* y
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    , n: I7 r" f' n6 }#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    7 z9 r) T' g# K5 q6 q3 D  Y$ E- A! O& q3 A0 y- N
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    . M/ t: A- ]" a& {* A) N#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    8 {8 s7 u4 k6 h- c! O                                                sizeof(BLOCK_HDR)))  g( K& c2 s6 ?

    % S. A4 o: u+ h* k# [/ i5 _#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    ; m- T8 N% W' A1 b, h#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \* T' `* l; `8 H; y$ ^8 @( [: K
                                                    OFFSET (FREE_BLOCK, node)))
    % O$ q; ~4 k9 y# l9 `2 M( A3 H2 ?/ O" i0 }% t& r" l8 _/ v. K
    static BOOL memPartLibInstalled = FALSE;% p. R. {6 I  w" z1 i2 B/ u

    9 W5 j6 P' O) _, ]static OBJ_CLASS memPartClass;, t6 Q% T0 V7 q2 [6 H
    CLASS_ID memPartClassId = &memPartClass;
    7 J/ B% }% b1 Y, a
    3 F: H- `( h& W6 u8 H" p; T9 ]static PARTITION memSysPartition;
    , A. O5 _) ]" M1 NPART_ID memSysPartId = &memSysPartition;" ~$ v9 _0 C! e+ e# D+ e3 O
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;8 }0 z8 X" I. A* B2 J; ]) G; O5 @
    0 r! V3 h% D& L' u: S% W* l/ L: N
    static SEMAPHORE semMemSysPartition;4 o; [( Y$ J2 {" Q9 w0 h

    , R% n1 T0 I# l) u1 i" i/ }static void memPartSemInit(PART_ID partId);4 l0 _; Q9 S! E0 B2 y4 M
    & m" n7 j' p" x# z
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    3 P$ b& A, p* {
    0 u# a2 s) z* X. o0 @! Iunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    $ A' n( }! X( H$ ^( F+ s
    8 H9 R# X1 h4 m0 W9 k7 M7 s* Istatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    . b: M$ Z4 O( S  \, Y/ R3 Y9 D" \static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    + H' r' f1 Z: D; b        , FAST BLOCK_HDR* pHdr
    7 v( l1 o! r" |, F" R- I' O        , FAST unsigned nWords9 L% B6 w; O; b2 |4 I
            , unsigned minWords% x0 l0 N$ j9 T5 _+ a& j/ z  R' J' V
            , unsigned align);
    6 x" z# |! A& j, J7 W- X$ {
    ; ]- n7 ]9 N1 k- l8 l) n, H- vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);# Y; b: {$ F! ]4 i3 T
    5 H/ {! v6 A9 A! F
    STATUS memPartLibInit(char* pPool, unsigned poolSize)/ b' J3 n/ Y) N; Z+ t
    {0 H+ ?; q9 o- M( `7 s( {
            if((!memPartLibInstalled) && 6 T: R" h3 @2 A- q: O
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)* ?& c7 x; i8 d8 _5 w7 R6 @
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    : T7 U6 l5 P9 ?9 [# i/ S        {8 \" U( k% @$ H" h
                    memPartInit(&memSysPartition, pPool, poolSize);- j/ E! ^  E8 R. l% U( M
                    memPartLibInstalled = TRUE;0 S8 s0 F, `+ o& q3 ^7 ~1 M
            }
    3 Y; b/ L8 b; b7 Y% f: k+ Y" O9 Z0 U# F$ t+ b$ V
            return ((memPartLibInstalled)? OK : ERROR);0 J+ `0 }, j8 @
    }
    * |* C7 v2 \* ~* [8 V" ~
    - R; j  O: ^' `' \PART_ID memPartCreate(char* pPool, unsigned poolSize)
    - s$ H! E+ k. G  b! }, N{
    $ K/ O) J. Z, L1 f, C3 B7 D        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    5 }3 n; R9 V- Y8 ~+ w3 S* B) o9 H! Q8 X" h- d8 [
            if(NULL != pPart)
      u1 F0 t% R3 p! \* x" e7 u        {  q/ G/ |  H6 I4 J& K
                    memPartInit(pPart, pPool, poolSize);. f: t: k5 P! I' V' _4 G4 D" M
            }# B2 \$ X6 K6 M% c- c8 r
    ; ^, k& v/ {5 }6 c
            return pPart;
    5 X; \* N: n; u5 b* b/ N! G! k}
    # d2 ^$ f( t, c) _' Q7 I" o0 D8 T
    , e9 c! [& L  X2 E; o  pvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    $ y6 g: P( z! S- l{9 K7 O+ S2 w% _% Z2 Y  h) \
            memset((void*)partId, 0, sizeof(*partId));
    ; M0 W9 U3 |. R7 c8 D7 Q4 m1 i4 C
            partId->options = memPartDefaultOption;
    ) T2 q1 x. G( G  n        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    : ~3 w5 o* d( Y1 d8 h8 {+ ]% K$ |7 |, z8 x! O8 K  c3 {. u
            (* memPartSemInitRtn) (partId);$ @3 D( K6 ^  P/ ~8 m! F
           
    1 x& k* v( T" W, {$ R* U        dllInit(&partId->freeList);
    . m# z* `$ Z' g% x$ }        $ f% E! ]# @; ^6 |
            objCoreInit(&partId->objCore, memPartClassId);( b. ]/ G* P4 a8 W- ?
            + Y: S6 j3 C. d& c
            memPartAddToPool(partId, pPool, poolSize);
    5 i3 E, o4 z* K# ?, W}
    - r+ c& S% P+ C& Y4 H  q
    % |/ u0 o# ?3 K; t, \% _1 t* ZSTATUS memPartDestroy(PART_ID partId)! f& r8 e+ @, ?, ?8 [7 z
    {7 n  O% @3 r, O% A. H4 b& D! N: T
            return (ERROR);8 l( \: x) v) H
    }$ t6 T* w5 j7 }5 W8 g

    4 C/ Z$ u! R0 \void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    9 @8 P' |# Z5 Q% W4 o  q" {# W{
    % V- M) \6 T5 U    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    - u  E( W) j9 [4 h}
    0 S+ R/ F. X1 i3 j) K4 G7 L" `" J+ H) L( a' v3 D+ G- t( `

    3 y3 ^9 L7 \3 A' B( ^' x6 astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize): r" [8 m/ ~" k& O+ Q' E3 v
    {
    # L! J- C/ A% X0 [; s        BLOCK_HDR* pHdrStart;( L% z8 K# ?6 F
            BLOCK_HDR* pHdrMid;
      J5 G, ~' N" ^+ ]4 g        BLOCK_HDR* pHdrEnd;
    ; ^2 o: G: }6 {/ p        char* tmp;4 A7 g! i* V" E
            int reducePool;. a  G* N  S% A  y

    9 c3 I* b  u0 O$ b        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    6 C1 k/ S- R' p: Y' v1 f        {  q& |' V8 q- p& t" w" V, z4 H7 T
                    return (ERROR);
    9 j, G" a( F9 C, w* H! ^7 c        }" w: [' l) v9 u/ [, k

    1 ]8 K% O0 R1 v% b/ ]1 k! L7 g2 `        tmp = (char*) MEM_ROUND_UP(pPool);8 Y& i2 N7 x9 `1 q
            reducePool = tmp - pPool;
    " L: I: p* u$ I& E  d' D( Z$ \
    3 E5 G  Z, b% c3 L        /* adjust the lenght */
    : ?4 y5 w! a4 B% ]        if(poolSize >= reducePool): z7 g/ O/ Q, M. l" g6 P
            {3 o1 S: I% N% q* P( n. `$ r
                    poolSize -= reducePool;
    9 G0 R5 U1 W5 Z5 Z: r8 }6 u        }4 _5 `5 U4 `" s2 b: T: |
            else
    , N7 X/ Z/ Y6 D2 E+ L, E+ g        {% z' J$ q2 S5 O) Z; S( ?
                    poolSize = 0;
    , p2 C* `4 `7 z6 p        }" I# H. a' ?5 f+ `1 X% Y
            pPool = tmp;
    6 Z; K! q& l" x" X% s% X  b% B        % b7 m: T$ v2 P. [. P' p5 O/ T$ z
            poolSize = MEM_ROUND_DOWN(poolSize);. r' o- T1 {" a2 n1 q2 C
           
    : a; [1 B& M' h+ w2 P        /* at least one valid free block and three header blocks */
    * d; O8 v. X6 p" E$ ?  K# E        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    ; S; V& H! d% w5 o2 m, U        {  p- v* f; m3 H5 i
                    return (ERROR);& \% ?! I9 }' X: e/ x7 e+ A* }" j; c
            }
    0 s7 O/ Q3 v2 D6 E/ b" e9 S: `2 [
    # _1 z9 p, R: L& n/ B6 R7 ~. v        /* initialize three blocks */
    5 {" v* W5 e. `% M2 ?; v! U$ N' d        pHdrStart = (BLOCK_HDR*)pPool;
    2 C) [  K" t% O: c5 B  {        pHdrStart->prevHdr = NULL;# l8 z0 P7 W  H5 q0 ^
            pHdrStart->free = FALSE;                /* never in use */) h0 j4 t5 J0 _+ C3 d7 }6 x* I( i0 o
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;' A6 K9 H) @4 g  {$ }. O, _
    $ M% D! t' O  r' k! c6 A/ [; {
            pHdrMid = NEXT_HDR(pHdrStart);
    # v0 G6 E2 I, A4 Z4 ]. Z) z; h' B        pHdrMid->prevHdr = pHdrStart;0 C* e, T0 X- |) }' B1 j4 a# w$ `
            pHdrMid->free = TRUE;                        /* the main block */" ^3 _# D$ Y# F6 I% g+ \3 I
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    # H2 y; s( v$ b" L, I
    $ {# Z1 f: ]- a# p" z3 Q4 z7 O        pHdrEnd = NEXT_HDR(pHdrMid);
    8 C3 }( j8 ~8 M" ]$ q  ^        pHdrEnd->prevHdr = pHdrMid;
    ; v/ ]7 l4 r( F+ Q  P+ w5 O5 H        pHdrEnd->free = FALSE;7 C7 P) j$ \6 p* E+ V
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;2 m; i, _- q. |2 P9 }8 P$ T
    4 W) F0 b5 D- B4 k& Z. N
            /* TODO take sem hear */% j: a2 B4 @) [& S6 P  P! a
            semTake(partId->semPartId, WAIT_FOREVER);/ t* o9 A( I+ Q) ]# O+ V/ p  t; d
            / u( ?0 K! y  r6 K
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    7 e: h0 K3 U/ [        partId->totalWords += (poolSize >> 1);5 ?# ^) ^: t  V: H( Q+ ]. c

    " p/ z, A/ Y5 B; _% I3 C6 l        /* TODO give sem hear */
    - p. g' m% p( [8 e' C# Y        semGive(partId->semPartId);- F& l& K4 s6 p. |2 s
    : d5 t) S9 z4 F' z

    2 s& B7 t, a0 I  T1 U  f' L, `. s' Z        return (OK);
    * k  R" G. ?. @# M% C}+ J5 f4 K& S8 L% l; m
    ! X. \1 }; d$ L. v1 c. G& A
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    ! a. t1 C$ k7 K+ h' G- u! z{
    / {$ r6 x. q2 V" o+ s        FAST unsigned nWords;7 I0 H, o) E4 @6 E
            FAST unsigned nWordsExtra;
    ' h6 G$ b* i+ h$ y; y% S5 k3 i- g        FAST DL_NODE* pNode;
    / D& u% p8 l# E% R8 B& J9 n9 [        FAST BLOCK_HDR* pHdr;
    1 \7 s3 m- ?9 A2 q4 ]8 i  c        BLOCK_HDR* pNewHdr;9 c9 X( U- w" N* o# H6 x! X
            BLOCK_HDR* origpHdr;  v) u5 `* r( h7 w

    ( ~3 T" ^# |" r6 m        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */: A, f5 x2 ?  T( r' o2 F
            {- `: @4 B4 Z4 z
                    return (NULL);* x- C6 w% I% ?0 T+ B
            }
    / u* e, c9 p" U8 p7 V, P7 x% v* V( [3 ~. L0 W" ]
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    7 A3 M9 p; @% }" c1 U6 v7 v0 g3 f
    % J# c  a7 \9 s: ^" e* C5 G        if((nWords<<1) < nBytes)
    4 y  I  M1 X) ~" ^' H        {
    , T% n3 z9 u% z9 a+ B                /* TODO suspend the task */
    $ ?2 E4 t9 `" w% F                return (NULL);/ P9 y7 x- t; K+ Y
            }, `, P( K( |( A0 ~% i

    0 z% G+ A8 f4 F  W. y        if(nWords < partId->minBlockWords)
    / \# t( f0 D  ~. D/ s        {+ L) r' q/ y" `6 W+ @& {1 b5 F8 d
                    nWords = partId->minBlockWords;
    , o9 l! ~) B( N' }  b        }
    5 B; U; e% w1 b5 B* n$ D. I& n, v$ n# T9 f* p5 h% W
            /* TODO task the semaphore hear */; ]% `9 w$ I8 j/ x, _: l
            semTake(partId->semPartId, WAIT_FOREVER);
    # S3 e0 x1 Y% \# k8 P7 }        pNode = DLL_FIRST(&partId->freeList);
    ) f' Y) o8 E3 w  o        nWordsExtra = nWords + align/2; /* why? */8 a$ k) K" N) J: r' A7 X
    / g8 q; D6 p  u9 e5 ^% K
            for(;;)1 Q1 \7 W9 G# B
            {
    : S1 m; w! @8 l                while(NULL != pNode)/ ~9 v/ I9 r" F, j; q0 t7 P
                    {
      ?+ o" b$ @  d                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    6 x, n) u/ Y1 m: y* o; U                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 9 ]  _& V% x. P: Q2 v
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    ) K; p. k! y9 C$ G  q                        {4 ?7 c5 `: \7 S1 m: @- L* p
                                    break;2 }" ^) P# M. f# z/ y$ @
                            }3 A/ D! [' g" j& V, R6 @
    2 E% L; `/ P$ a
                            pNode = DLL_NEXT(pNode);+ Q2 r' O5 x1 w1 W0 g
                    }$ v+ ^% r2 _7 ]( u1 b
    ; o7 E* Z$ i3 g. h& o7 m
                    if(NULL == pNode)
    " R! J( l) N# b! }: A0 l" {                {6 a2 G1 Q6 M4 V% ~- ~% q
                            /*TODO give the semaphore */
    + P& _( f7 `7 J( l# |5 ^  Q                        semGive(partId->semPartId);
    ) X; ]& L6 O$ h9 Y, g# p" I                        return NULL;' ]# r  f: G! x# {
                    }' m. O2 N% O+ y4 x) F

    / u( l0 [& Q. `                pHdr = NODE_TO_HDR(pNode);1 R" c2 g5 E5 J: }' ^
                    origpHdr = pHdr;
    ! u4 ]" |* {$ S$ y
      o4 s2 U+ E: ^$ v: q  j                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    + f/ K& q! N/ \; e; m                if(NULL != pNewHdr)
    9 M& a+ q2 |3 ~- e0 [/ w3 }# y                {
      _- R# M$ v' n; W/ t                        pHdr = pNewHdr;
      A: f; d+ {$ @  X& i* C6 y' f2 l2 c                        break;; ^! Y) q& i: L" K* I8 H
                    }
    " P' Z# i# ?7 [' T; Y0 _* _3 r" s5 `- M; Z  }/ E
                    pNode = DLL_NEXT(pNode);
    # [' x! x8 `# m0 a' L0 N- `        }
    # n, m9 d- `3 q6 O- q
    3 F, A+ g1 ?8 Y7 d9 G' a        pHdr->free = FALSE;
    ! h3 u1 }$ X& R! z        partId->allBlocksAlloc++;% B4 C1 q" t9 h
            partId->allWordsAlloc += pHdr->nWords;
    ! h9 s: z* z# v/ h! c        partId->curBlocksAlloc++;2 o* `2 O% _) P1 a! R
            partId->curWordsAlloc += pHdr->nWords;
    ( a1 u- g1 ~+ U( }' h/ H1 {1 V
    ' \& j& j! ~) w* ?5 ~        /*TODO give the  semaphore hear */
    ( q9 D6 m# |/ m. M: H3 T        semGive(partId->semPartId);
    # |0 v$ j9 E" p9 Q' Z+ b        return (HDR_TO_BLOCK(pHdr));
    , \1 E2 I7 g% ~        + {) }( {& A' r
    }- H+ \3 ~, @5 V

    9 r! `8 j6 s( |+ h3 m- Cvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)" ^( u6 _9 Z* |8 f6 t- o1 K. Z
    {3 q# `. K% R0 n# A  f7 P
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    ! f  S) y+ Q$ e% s( p7 C: Z}' ?, o' q, L  Z4 {7 w% |
    5 k3 |+ g1 H  y% M8 A+ D
    STATUS memPartFree(PART_ID partId, char* pBlock)" F1 z/ b9 M) O5 E7 y" |' C
    {
    ' f. U4 W$ C- @" M3 m! m5 ?+ \$ z        FAST BLOCK_HDR *pHdr;
    8 ]* R" ]1 b4 e+ D    FAST unsigned   nWords;
    & R* S4 h/ H/ x    FAST BLOCK_HDR *pNextHdr;
    + J; R* V0 V/ a# E1 ?3 m) H% d1 P, Y+ J9 ?9 a7 r0 ?1 B
            if(!IS_CLASS(partId, memPartClassId))
    - _! Y7 l, N/ o        {+ H0 l( O" L; \. C6 Y) w
                    return (ERROR);
    # S' B, K& K6 R& R: v& M( j) j8 f        }
    ( t; m, \7 i$ @0 K) B- d  z7 [3 K& F
            if(NULL == pBlock)
    ) p. v7 _2 ]% N8 M# y! u7 N        {1 y  w7 w, e4 e7 w
                    return (OK);
    , P* c6 p# r7 j, @1 Q3 t$ J        }4 a  {- r- p5 M
    8 \" x" y6 Q6 d: t
            pHdr =  BLOCK_TO_HDR(pBlock);
    ; X5 O6 d0 Q! w' F4 R4 r" Y" A" `) n1 w* V
            semTake(partId->semPartId, WAIT_FOREVER);
    2 O$ H# W, f5 D# t2 m. F: W! r! v: |2 W7 w
            if((partId->options & MEM_BLOCK_CHECK)& ]/ G" V8 r4 j7 Q6 T0 F
                    && !memPartBlockIsValid(partId, pHdr, FALSE))' Y; B5 D0 r" T# j* v& t! e
            {
    " h# P$ d1 H4 m* @$ o+ t                semGive(partId->semPartId);1 j$ L8 k7 N5 g8 x& C
                    return (ERROR);
    7 b( b7 k& t# K9 l        }, R- L, s$ z0 h

    5 i, x+ {! Q: |* A  {8 y3 N: j        nWords = pHdr->nWords;
    - D9 c) D3 p/ P3 s& H# d( `; I, W        if(PREV_HDR(pHdr)->free)2 I& D- f2 h5 F" i
            {/* the prev hdr is free and than coalesce with it */
    + \; B9 H( z. T! k7 y% T$ h                pHdr->free = FALSE;
    9 @# [7 r5 y+ L) G  W                pHdr = PREV_HDR(pHdr);4 w3 }0 U) i# G
                    pHdr->nWords += nWords;
    . }) t0 J6 {, I( U/ X( q- Y3 z        }6 s- S& B, _$ M8 T, Z, J+ ^
            else( `- ~5 [% l# P7 @9 B
            {& S4 C- `6 c% T% C+ O9 S
                    pHdr->free = TRUE;
    ' g# v; M7 J; N) a: y5 X                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));3 F8 d. w$ Z- L' Z
            }
    6 q5 {0 A, ~4 o" C5 q  @" h* L! o$ o% V
            /* check to coalesce with the next */
    2 j; [- b5 z# G; l: ]        pNextHdr = NEXT_HDR(pHdr);8 O# C' L  u! Q# ]$ \* A* L7 ]
            if(pNextHdr->free)
    0 \( V# z) s6 T9 f- e# b& n( {        {
    ; [& l4 K4 D/ A8 l7 Q! R                pHdr->nWords += pNextHdr->nWords;
    # X+ j8 U. ~2 b* D: Q+ T3 O& J' e                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ' Z4 F: P8 |) d' c+ \& g0 m        }
    & t! O; _$ N% r6 T; _
    , X, O) p  P8 Q* z  t" K. K4 Q0 f        /* cannot use pNextHdr->prevHdr=pHdr hear */0 ?( S! o. O* E. W$ V8 a4 _
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    ( q& ~8 A/ T' K
    / i2 T& z1 `+ L- b* M        partId->curBlocksAlloc--;. s, v  i  {9 Z, v. a
            partId->curWordsAlloc -= nWords;) z( B* I, G4 A- L- _  x

    " x" E! }' ~6 e6 i        /* TODO give sem hear */( g2 E4 t  c2 u+ ~+ D  T' X5 u
            semGive(partId->semPartId);
    . n# O  y, `& M6 V' @9 D, |        5 T) O2 s; `2 q  }9 v+ C; Q# }
            return (OK);
    7 o" t; \0 Z9 f2 {) f  b- G- E4 ^}6 S+ P: Y1 h" |, E" K4 o8 @
    $ v7 s. m% w6 s$ T# v( q& b% i% i
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    8 G( S# x: U! Z, L: {{, h' h6 X* I. F& M
            BOOL valid;
    ( m1 X9 u3 N7 m+ B$ V  T: s4 @
            TASK_LOCK();& j6 c5 A: ?7 ^# n7 m
            semGive(partId->semPartId);
    - ^) h4 L8 p: Z/ A1 c       
    0 t% n# |3 k  h0 `* b+ L. s) z        valid = MEM_ALIGNED(pHdr)7 O: `+ ]7 ^6 _0 z  j
            && MEM_ALIGNED(pHdr->nWords*2)$ X, ]1 n: A" U5 g
            && (pHdr->nWords < partId->totalWords) 5 V9 v) X5 b, I
            && (pHdr->free == isFree)
    7 u% a% u  W3 n4 t# E        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))4 Y5 \# r! w6 [, o' ~# l
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    / ]- F% l5 e* y* W: V8 E) u       
    2 R0 |0 M9 X. m/ W" W        semTake(partId->semPartId, WAIT_FOREVER);
    8 L8 _( l9 R' a) o" q! ^: H        TASK_UNLOCK();
    2 o! J3 Q$ B1 H, V  }. f5 c' y, _" b) l
            return valid;/ {- m- G+ ?6 O- M
    }/ p/ _' j/ M6 r- H
    % x2 @- f1 b0 S& {( f
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    % s1 Y" t# G7 \" _3 ?/ u! e        , FAST BLOCK_HDR* pHdr, p. e5 J; n7 T! o6 t) f2 j
            , FAST unsigned nWords
    , H! `' s8 }# K$ ]# `+ t( i7 g' b        , unsigned minWords: r+ K: ]* G. a
            , unsigned align)
    $ \8 z+ k4 y& ~& B' B{: V: J8 Y# Z* U! s  j" V! Z
            FAST BLOCK_HDR *pNewHdr;+ q* r( }7 P7 r6 C$ }' I! K  o. w
        FAST BLOCK_HDR *pNextHdr;
    ! D' P2 w; \, i+ U% M    FAST char *endOfBlock;* j# c2 y2 k- M
        FAST char *pNewBlock;9 k; Q( @9 b: r0 N: }
        int blockSize;
    7 M/ C( \: o5 S4 Y. X( Y& |2 Q4 T9 I
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    9 {$ I, U% b0 K; G# v' f# a6 m- j4 m2 F2 w" H# r! s! q
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));) O5 Z+ E3 U" b# ^$ Q" N
    3 Q  w8 X5 O# |' W- L
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));6 C' t" j% |- ?. T- \4 K; N

    ) t) k: Y3 q* a' ?" J/ I        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    1 E" @, Y* L  u* \# @
    7 B" f8 W; G( J        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    9 \6 k3 j8 S" p' m/ E+ F+ `% M8 B# K. N
            if(blockSize < minWords)) R7 Q2 W3 \' U* G' k/ G  E6 A( R  Z2 x
            {/ @. \- t( k* _" W# [/ }
                    if(pNewHdr == pHdr)
    ! K7 i+ j. K! B9 J* I! [% O0 N+ T' ^                {8 ]& e% s; {$ I; a7 g0 n& a3 G
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ; M( l- b1 \9 c3 M: P! B                }! I" F0 W& U- u* ~6 O5 t
                    else
    ' s  l. l$ }: e1 k1 M                {
    4 K2 e& a0 q3 d$ N% Z                        return NULL;
    0 w1 n+ \& f. x6 i9 W                }
    2 k. i) u! w* R  F: a* X) E( `        }% |: \+ n4 V2 z. H0 g+ G4 u
            else
    6 k3 |+ ?! t7 \- R) H2 J        {        /* recaculate pHdr */
    3 p' Z5 f7 n, m4 |                pNewHdr->prevHdr = pHdr;
    + {8 u$ G' Q  G/ e                pHdr->nWords = blockSize;  F  z$ T7 X3 {
            }
    , m  y+ \5 C: ?. A
    " }4 A8 R9 h# n" T        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))5 v! d0 N/ U7 e0 S$ I9 o8 I
            {4 i7 [4 O! [1 q  Q  a1 ^- t: i
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    . U- O1 @: F% t3 S# b9 H                pNewHdr->free = TRUE;
    - F3 C  a6 `) j) w- H
    . D7 q! z% Y5 b* o& o                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;! O+ y* K9 R5 |4 g# R
            }
    ) n$ H; ]" v3 u; a( w        else9 C/ J# Q7 m$ b3 R9 A4 ^! Q
            {/* space left is enough to be a fragment on the free list then */
    : k$ m& G3 {8 w  T: _8 a                pNewHdr->nWords = nWords;  m: c( [; B; n5 A4 S
                    pNewHdr->free = TRUE;
    3 o; V+ b! Q% h$ h
    9 m3 ]6 q2 A+ w5 ]& P                pNextHdr = NEXT_HDR(pNewHdr);; W6 j5 d0 K$ z4 L3 g- }
                    /* words 包括BlockHdr */  E$ @% ]) d8 _# ]% V) |  M7 y  S
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    * U' W' X! i/ h: p- q' M                pNextHdr->prevHdr = pNewHdr;
    , ?- i1 @# w* v/ c. Z5 H                pNextHdr->free = TRUE;% O3 ~5 r% `, T' D

    - x/ z' ]1 W5 O9 _7 L2 J6 A                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    3 R" P' q! x7 G4 c, q
    4 H# D/ n* A; \( S; G" {! h5 t( r& o                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    1 J0 A/ W: }1 s* J! X( S        }
    ) M' F& R& b( g
    ' J1 b, M+ c6 E$ u4 W2 W0 G% X        return (pNewHdr);
    ' X8 C0 ?0 K1 H1 }}; @1 x+ M% g9 t* A! }& Z0 e' k- U

    # u1 M# W/ d$ {1 A8 [1 R5 fstatic void memPartSemInit(PART_ID partId)
    - O0 i% K. Q% ?! i- X  n4 ^- z& l{
    ! L9 g* Q3 I7 T* ~' F        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    * C: O( Y  |+ M: }, x, ?- W! u
    : Z6 G0 H: n8 `$ G! i2 l) T& S* j        partId->semPartId = &semMemSysPartition;
    + ?  V; J3 [( s0 T}
    - n9 _' W; c& k% {( ]0 t, A1 U0 P* z/ F' u9 ^2 q+ ]6 N0 {+ q
    void* malloc(unsigned bytes)
    ( ~; V9 w0 E4 `- r{
      D/ Q4 Y4 V. t3 m& ^$ L- G        return memPartAlloc(memSysPartId, bytes);
    * ]9 |% A5 B: O/ D* s% R}( T5 [3 C4 \4 {' b

    3 S, }2 b$ G' B' c7 T8 Tvoid free(void* p)& U$ Z. b  b1 ~: ?9 b- c
    {
    " g0 ?  H) ~/ @' w0 N( |6 m# R3 R        memPartFree(memSysPartId, (char*)p);
    # W4 _3 p( p9 ?5 t; ]}' z0 d2 d& y# e/ J" a- p7 w7 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-6-3 15:38 , Processed in 0.459966 second(s), 50 queries .

    回顶部