QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2642|回复: 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++下的版本,更方便调试。有需要请留言
    7 l; X8 p' {8 M
    $ B9 s# Q! i* T, |( o* Z! W* Z6 R8 x

    1 G% o+ l- @( i+ d* ~5 F *\file
    8 d3 e% q! N0 O  d' K/ n) y *\brief                % ]; i, b) b0 h% m; z; k- r
    *\details       
    " V$ N& b7 ?! P' D; t' i& a *
    2 Y+ ~1 P7 H- _% V *\author        Janson
    , n! t4 J- X  `$ E0 k+ f2 M3 ? *\version       
    " o* T: S4 Y4 x/ k6 N% O *\date                04Jan12, E  ~$ y' }# G$ j$ e3 \# R
    */ H$ S( Z9 z4 o% m
    *\warning       
    ' z$ C9 x* H* c0 g- ~" B *7 ^& b, G4 D, g& q+ }/ _
    *\history \arg        30Jan12, Janson, Create the file  [9 Y* Z5 Y: Q& W# d* l& s" f
    *        modify from VxWorks source9 o  K6 s) ^0 F/ L3 t
    *  Legal Declaration: it is for studying VxWorks only.9 |! R1 N! F, p7 B8 V
    */* |: L& Q" D- Z, W9 @
    #include "includes.h"
    8 R# f0 ?4 ?- d& B% U' @! N8 x: f7 I
    /* The memParLib.h file is hear:
    - S% T0 X& t  z+ o9 }/ e. ?https://code.google.com/p/vxwork ... rivate/memPartLib.h- F- Y% G; j. v6 ^6 u) l9 F' v
    */
    2 K' ?: _. ?: ~
    ) }+ ?2 @. z; ^/ |5 e/* optional check for bad blocks */5 x, j* |0 g" ]/ C

    9 C, B7 U" @0 A+ Q2 b: o$ |+ z0 w#define MEM_BLOCK_CHECK                        0x10
    # x8 t8 X! D# S6 G
    % l- E* H  M& b# B& H1 R; T/* response to errors when allocating memory */
    9 |- M4 j  q  D( c+ v8 i! K& O3 F1 G( z% t4 }" V9 s& q* c. f: l
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x208 a  Z0 G1 w/ c2 ~
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    , u& T# `! x8 {8 x& i/ J# B6 D! `, n5 M+ @
    /* response to errors when freeing memory */
    ' p# M, c' _2 u
    # {0 S; ?3 U, s6 `4 `#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    & o+ z0 Y0 ]. ?#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
      h/ `% v9 d0 D
    ) d1 C/ [5 N" c0 ^4 r4 P#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    ' l3 @, s+ n1 E( y8 f#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)3 V  r7 W& @% Q3 }/ j. f
    # K0 g7 R" U3 `) Q
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    ) {. q1 o* {# ~( P  K6 \" \1 S#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    - d1 b5 E  s- m0 M; N                                                sizeof(BLOCK_HDR)))/ N+ N0 s# S; @' W  J0 ^; x- N; u
    6 c( b, i; j1 D8 U' I
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    , H. J$ F1 ?) f& o#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \8 y+ K! U8 x" x6 i3 I6 N# e' E9 T
                                                    OFFSET (FREE_BLOCK, node)))
    8 X+ c$ F3 u6 L) I  ?! k3 ]
    , e2 V8 p9 B1 m" ]% ostatic BOOL memPartLibInstalled = FALSE;
    . V3 b1 {! O1 O) E3 e0 J+ L" ]% U" d  z
    static OBJ_CLASS memPartClass;
    8 s) `. Q1 H' ICLASS_ID memPartClassId = &memPartClass;
      o. `  P2 f9 u( K( `( a
    & L: u6 f3 r- {7 B* z- i; gstatic PARTITION memSysPartition;7 O  H# b( J: {. a$ t; ?. A- R; y
    PART_ID memSysPartId = &memSysPartition;
    / n, m* f+ I! Q1 B1 j( b* tU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    * A5 Z3 I/ n! I! H7 t
    2 C' D0 F4 n5 cstatic SEMAPHORE semMemSysPartition;
    ; j5 t/ A. t$ Q* u2 E8 M! j9 y6 ^$ g- s1 ~: w  K& l+ g
    static void memPartSemInit(PART_ID partId);; E& D" O% G. Y6 e! o

    / D. o/ A, L) k$ OFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    / f# n- g2 P" Y' c; ~
    6 ~% A" s. E3 A! b" ?! Xunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    % c+ u6 l$ [5 @& i
    " I+ Y6 ?/ ^0 D6 ~6 x* A: Dstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    6 {! U% \5 z& f  D& N7 a4 K% Istatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId; L" j6 V- q) |% U- e  V
            , FAST BLOCK_HDR* pHdr
    & s- [# v$ [7 O# G8 t- f4 s# s        , FAST unsigned nWords& d3 C* ]+ V. K% P- v  X
            , unsigned minWords
    7 a  \/ y; y) C5 j$ _8 s) F        , unsigned align);
    9 u1 P9 Q# L# a$ ]  M9 ]% {3 z$ _& ^' z9 J' F# }
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    * w' c: x0 O, j0 X- C3 w/ J
    " M/ F3 \0 b( i6 iSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    2 {5 _3 |, m) x{! m! j0 D8 F; n6 C
            if((!memPartLibInstalled) && ; t$ ~  G2 @$ c' [2 M* w1 S* V
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)8 [( I4 O9 K* p0 P1 ^. P, g
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    " i! U/ ^' g6 w  b        {9 s8 Y" L3 J( H* [* I1 j
                    memPartInit(&memSysPartition, pPool, poolSize);
    , ?' m$ z9 G, g& g6 ?                memPartLibInstalled = TRUE;
    ' ]# [8 w% ?- w1 o1 @- N        }& {( u5 A; R: j! G0 h

    ) C. B2 w3 r. F! Z# O        return ((memPartLibInstalled)? OK : ERROR);
    - n4 U3 j4 F! M# {}1 ]1 k: X1 X. r: l" Y! ]

    9 H6 B( b- A5 {1 MPART_ID memPartCreate(char* pPool, unsigned poolSize)
    ! i- h+ a8 Z' O* y6 y{+ K9 e0 v! K  p; t' _0 y+ B7 u
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    ; {+ \- C1 j! x: x) V
    # G7 B" S9 N% N: b2 G' R        if(NULL != pPart)' s+ y( ~& b' ]5 |- x7 O
            {! S; e, `* a8 k$ e& a7 }8 p
                    memPartInit(pPart, pPool, poolSize);# T. d9 Q, j8 N+ o
            }
    5 s; p* a* q. ^* J0 ]5 _. Z" K) p: l2 g7 z9 S  j3 n# x: F
            return pPart;+ ^$ T2 s) o# ^. O- P
    }
    ! I6 \0 j# w5 g% g- E
    , `/ E# P4 b6 W2 w3 nvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)% _* \# _+ R. N- I% r4 n+ X# l7 J
    {" P& a: O2 T7 k! P+ W0 l! Q+ \
            memset((void*)partId, 0, sizeof(*partId));/ P% s/ s) u& T5 Z

    + p- ], Y' w7 y& \0 ~' \5 G, G        partId->options = memPartDefaultOption;
    5 G! B, t; o  W/ q5 ~1 R4 L& ]5 P        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    : U+ G3 q8 ^  s! x5 G
    . \9 r% F* j+ k; H# [' O5 A3 d( i        (* memPartSemInitRtn) (partId);
    ; `+ r1 ~# V6 u. d! D0 ^: t3 }$ p) t        " \6 s- g3 ~6 G
            dllInit(&partId->freeList);. v8 o5 ]; s" M: N" ^6 \/ h. I
            " f" H5 H: W+ P; m$ @, A
            objCoreInit(&partId->objCore, memPartClassId);0 v; u) k2 K. Q% q8 A
              E! b. J' [8 s
            memPartAddToPool(partId, pPool, poolSize);/ t, ~, b1 j  J# W3 N0 v
    }
    2 o' @& y. _0 Z/ d) Q$ E
    " e: S: E9 b5 r7 F! d9 p) \/ ^3 VSTATUS memPartDestroy(PART_ID partId)7 o9 \7 k4 W3 A. O3 q, U0 Z
    {
    ) W, P4 w( i( O        return (ERROR);
    5 }- g' e6 R8 d. ~}8 E! U( j# r$ B5 }" U5 T
    # w" ^* ]3 W5 v) E
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    ( g: ^2 T$ e) Z- c0 V{4 Y9 p) Q6 k: f. r! \3 X/ w
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);% u0 G, N! a  ~- q- g
    }, G7 N5 R% Q3 z6 `, s
    4 \4 v! L' C: U7 }
    & Y5 d: w" ^! s$ C6 @3 v
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    % Y  }: c! r2 C9 S{
    . x# }: I" i( W# Y: X2 k        BLOCK_HDR* pHdrStart;$ X2 o( i1 r; I& \
            BLOCK_HDR* pHdrMid;
    ; h8 R6 L& [! Y) k/ ]% ~3 n        BLOCK_HDR* pHdrEnd;- {" l! _3 r( L& l9 \- f
            char* tmp;. t5 r4 O+ ]% Y: O
            int reducePool;. E$ y  }" b: @
    ! P: y5 z# C4 h8 O9 d+ D
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */+ l3 w) {5 u  L! P' R2 ^' q
            {2 R7 h9 l, Y( C# {1 j
                    return (ERROR);
      |2 w* X; Z! |7 [. y9 s& M0 H        }
    7 i1 M- Y" ]8 p# `+ @! I+ e' @$ O; U0 Y3 m3 m" @# [3 Z8 [
            tmp = (char*) MEM_ROUND_UP(pPool);, t/ f# r/ _/ l0 e9 a3 T7 }2 @
            reducePool = tmp - pPool;# x) A$ y/ u2 ~2 A5 g8 n

      T" b: I, u! W/ y- h& R        /* adjust the lenght */
    $ ^4 W, G2 E/ V: j2 B' A        if(poolSize >= reducePool)
      t; R7 ?& w; s; p        {
    5 B( n% d. q( I* m: t- c                poolSize -= reducePool;6 a$ g$ E; S4 U$ G
            }
    0 C; q/ W9 I: }8 R& p" w        else
    6 C6 ^% v, }; y7 \$ Y* r7 S. j        {
    * ~" Q: e# q" J* Z& \9 z                poolSize = 0;
    0 W% P2 q. B+ H; s( P& A0 R1 X! s        }0 l* J5 G; Z$ w/ E* g1 B6 ^- m' u
            pPool = tmp;$ k, J" Q. C/ m  u% A2 k
            ' m* E* a! B3 ]  W  k
            poolSize = MEM_ROUND_DOWN(poolSize);: {. w% y& }2 @* ^) ?/ p  P
           
    # h$ |( u7 d2 J  C( F" t/ e6 N3 g        /* at least one valid free block and three header blocks */( y* W% a3 X( H9 j$ g; l6 Z
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)5 x  I, O/ x: t) X' ]. s6 @
            {
    / w2 R6 z+ i9 R                return (ERROR);
    ' i: V2 b: @+ \5 t7 e9 r        }7 {. q  x) M" c
    : ?8 m, ]9 C, o5 e; a
            /* initialize three blocks */
    / x( F3 }% O& f7 F        pHdrStart = (BLOCK_HDR*)pPool;
    3 ^2 P/ @; Q6 q: ?; H* ?- S/ f5 b        pHdrStart->prevHdr = NULL;
    ' A: f! n' N4 L% O        pHdrStart->free = FALSE;                /* never in use */8 ?0 z/ x9 r% j, w7 ^5 o( j6 T$ `
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    ) j- a4 I( T' }. k$ E* e' @6 c/ O! K) Z$ e1 r" d; k
            pHdrMid = NEXT_HDR(pHdrStart);8 y9 }$ Z, V/ k9 S) ?8 M) _) h
            pHdrMid->prevHdr = pHdrStart;
    4 _3 M! q( e) \; R        pHdrMid->free = TRUE;                        /* the main block */( P& ^# d* K  a$ m! l* I- x
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;9 `: d. y) |; G$ Z# v
    & u9 `7 M( s" i) b3 J' p
            pHdrEnd = NEXT_HDR(pHdrMid);! j9 ^; L' \# B+ ~
            pHdrEnd->prevHdr = pHdrMid;
    ) s. `$ L; _2 [; T+ L( g; v, c# I        pHdrEnd->free = FALSE;
    % G- _+ y9 U/ O# Q# E4 T6 f6 A% A        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;! M$ v2 S% k* }1 t- a
    7 A4 N+ }: C0 g& S4 B9 W* k
            /* TODO take sem hear */
    , a* h! s7 W( `3 S, E        semTake(partId->semPartId, WAIT_FOREVER);
    8 n4 ~) W: J( b# y       
    7 w* B% @* e& `& f6 A        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));' v0 Y4 S8 B' f$ O( r) N
            partId->totalWords += (poolSize >> 1);
    3 S6 ~7 ?3 L( S  b6 l4 f0 b9 q) w& h- D  {/ L- l
            /* TODO give sem hear */
    & T4 j, H$ u  r+ T, a7 L2 g3 X% X% a        semGive(partId->semPartId);
    $ @9 h' r( a- U" P, B
    * e5 K3 g3 f* N9 ]( I" M; D* E0 Y& q. q: f- R9 `
            return (OK);1 f; r; Z4 e  u
    }
    8 Y/ Q8 v: w4 G# |
    3 A" I  j* Y3 A9 D! f- Tvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    2 X0 u9 \+ k: N$ o{+ L) ~) B  ]' T4 C. m% t, T
            FAST unsigned nWords;6 l, f3 ^; H% E4 D6 x
            FAST unsigned nWordsExtra;
    * M( |, F/ X8 X8 C) p$ B7 `. Q5 u        FAST DL_NODE* pNode;
    # R/ |$ P9 i6 z        FAST BLOCK_HDR* pHdr;/ r) R' j! ?) I# o1 A  R
            BLOCK_HDR* pNewHdr;! d/ I! o% a; ]5 y) \
            BLOCK_HDR* origpHdr;4 N( E6 k) p) H, Y9 O

    6 E2 L" v# g( R4 o        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */# z9 L0 p5 v2 W$ M* D7 n
            {7 a2 F! |4 ^( `% A0 z0 A# \
                    return (NULL);
    % c5 [1 i. E. l$ X, N6 g        }5 r7 Y" _3 X0 W! ?: A: O5 P+ V

    + r& R9 Q. m) h        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    + M+ k0 W8 K% i5 r. d: m; A$ E0 ~( `
            if((nWords<<1) < nBytes)
    . l3 _% x8 F7 F: H2 e# L; v        {
    * \* D6 Y. `4 D' p& \0 _9 {! B                /* TODO suspend the task */
    . }1 y2 ~+ D; O# ]+ d3 Q                return (NULL);+ u3 r/ a" c  F" p. U( w! G
            }
    9 n- J# W: c+ p: t0 K# r; t: ]: H( G& B9 S8 I
            if(nWords < partId->minBlockWords)( j* V! V9 Y4 M" Y7 ?& [
            {
    ( x' O. U( Y  b5 w" W/ N                nWords = partId->minBlockWords;
    . W8 S- Q8 ], b- `1 [# [        }3 b% |1 @. A% b: t+ }" p! L
    8 @! x1 t, O) i4 b% q
            /* TODO task the semaphore hear */5 [, h& J7 M0 ]1 n
            semTake(partId->semPartId, WAIT_FOREVER);/ a3 d4 r- F9 ?8 u, s: ]6 p; L
            pNode = DLL_FIRST(&partId->freeList);
    ! r% c6 `, g0 k) ^/ M        nWordsExtra = nWords + align/2; /* why? */# d6 c! n/ K4 _/ v  x  \

    ) v' R3 H! K, S        for(;;)
    " e" e( O5 H# {9 d/ y: t        {
    ; T& S5 O$ z" v. _+ s                while(NULL != pNode)6 B- U( A, `! u4 {) M3 m
                    {% @  S0 r8 \' w* s
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    # N8 Q2 o8 A1 r$ K  Q( N' I! d                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    # {, Q2 b0 m6 J/ u; ]- V                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))% o3 ^% l. c9 T
                            {
    1 m* _1 X5 K1 S- S                                break;  K" F4 s  {! X
                            }
      J2 T7 I( M2 u' h4 k4 h! [" H0 c6 ~( T, a
                            pNode = DLL_NEXT(pNode);
      o5 \2 P( H7 e4 o7 P                }
    ' R5 H; l# ^5 c6 Z/ r3 X) z# t. Z% {; M" ?+ V
                    if(NULL == pNode)
    " w6 _- |$ p% M9 j2 r, ]0 A8 h                {0 C$ [6 `$ @. E* J) n
                            /*TODO give the semaphore */
    % c1 A$ m7 C8 E% R2 l                        semGive(partId->semPartId);
    . r; i5 K" K1 ~/ k                        return NULL;
    7 O0 A  c; J- g' b  T                }
    " X, y+ X( Y# A& ?( x, ^
    0 y" v) _2 y  [  ?3 f$ e                pHdr = NODE_TO_HDR(pNode);; C- q8 ?# \9 ?* x& {
                    origpHdr = pHdr;7 ]+ T; Q% _9 Q) d+ h. _* j

    . G; ^( O& ^5 C9 j" X                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    9 l& C( l& J9 D                if(NULL != pNewHdr)
    4 q) N" Z' C; r# |# [' T                {
    " ?, V: Q* J" U( Z                        pHdr = pNewHdr;& P; I! p/ W9 g! _$ ?4 u* J
                            break;- p& u* f7 W, N! {/ F* o+ ]; H' y
                    }; R2 _8 t# ~! e9 L
    ! m$ B/ N% f, b1 e1 q! |" `
                    pNode = DLL_NEXT(pNode);% `) V$ e- n& _" e5 \% r
            }0 O" h1 u) f* y" |5 M& o

    ' J% y$ |! |' \/ \        pHdr->free = FALSE;; Q- j8 Z& l5 y% X9 f2 A
            partId->allBlocksAlloc++;3 T# Y$ }) |4 q2 s( q/ k1 E
            partId->allWordsAlloc += pHdr->nWords;5 o: z+ {# X$ h( c
            partId->curBlocksAlloc++;
    3 H3 w0 d. g6 V( z  m) X        partId->curWordsAlloc += pHdr->nWords;7 K4 V, R2 c1 j- C
    : d$ S; J; c2 d+ p& [
            /*TODO give the  semaphore hear */
    5 f4 I8 }7 k) m) Z3 K        semGive(partId->semPartId);7 C5 ]1 q# o2 M$ R( X/ X  e0 ?4 S
            return (HDR_TO_BLOCK(pHdr));$ |( u2 h2 j" f# L( ?/ ~
           
    $ E! s1 ^% F  V1 V; i' ]7 m}
    - P. \7 o3 |% _7 l% d7 s8 q8 R8 c+ Z' d& ]
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)2 F3 k  w& D# _2 x
    {2 ~% E) r# q! Y: U" d
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    5 _& w' @" P( k9 O; `9 @}* m" L# Z) |& f4 e( e
    , D$ g9 ]( y: `1 D9 B5 `
    STATUS memPartFree(PART_ID partId, char* pBlock)
    ) n6 v, O) R- y, X# }  e{
    / q/ [; g7 R6 V% I: l" @* q" m2 [% L        FAST BLOCK_HDR *pHdr;
    ( j  U7 u/ |1 v& M2 G+ x% ]$ y    FAST unsigned   nWords;
      `3 P( |/ S6 L5 i2 }    FAST BLOCK_HDR *pNextHdr;
    3 `, i2 x6 ]- M( P& P* T0 Z& [' A2 y% `" e6 Z* J/ ~
            if(!IS_CLASS(partId, memPartClassId)): `5 @9 l' _- Q, `. O7 E! `
            {* H5 d+ o! [  A: D  S, b( W
                    return (ERROR);
    . Z" }& V6 K/ R        }
    8 M. M' T5 ~& |& t7 Q
    ! {5 z) Z& M+ z% s/ d        if(NULL == pBlock)0 |5 J" k, R; E& {- }
            {
    , d# X: F0 m3 e! \" C                return (OK);
    " |; ]4 N$ i& n$ _        }
    2 q3 {) I- F. z" F6 `; t
    ; G  i5 h( \  l- O( H        pHdr =  BLOCK_TO_HDR(pBlock);
    : t. b& w- d( F$ k7 j. t; E3 x0 d2 b  n, S
            semTake(partId->semPartId, WAIT_FOREVER);  m$ h1 s1 c/ g6 B' ?" a

    3 y; `" f; q* Z6 N, l, w" X7 o% y        if((partId->options & MEM_BLOCK_CHECK)
      _, n& B- C4 A& z' @% v& x$ Y                && !memPartBlockIsValid(partId, pHdr, FALSE))& S' l' a) Q  _. w0 g# a% z0 z$ c# V
            {8 C4 L! _/ x9 E3 K
                    semGive(partId->semPartId);
    & L9 `' ]) k3 U- B' ~. {* m9 k2 v0 _                return (ERROR);! u& K' `/ e9 V0 o8 ~
            }* d5 r- L8 S2 v  Y9 l- p
    , |3 i% ~- A1 j4 e9 a; o0 J: L
            nWords = pHdr->nWords;8 K, X! U9 J- v% b& Z% }
            if(PREV_HDR(pHdr)->free)/ C% |  }7 F; p, _$ w+ M; F% {$ M) ~' h
            {/* the prev hdr is free and than coalesce with it */
    & i; S0 y/ V- V- Y7 f. E; @1 c                pHdr->free = FALSE;
    % K4 V% ~% m1 o2 q4 p                pHdr = PREV_HDR(pHdr);, F* [' c1 y1 N9 u  `  S5 }6 @
                    pHdr->nWords += nWords;
    % |; [2 t6 r. \$ `( b* q5 t        }, d4 {; \5 f' a
            else* c; n! h* u' S4 j4 w4 `* r
            {
    ' i7 ~3 r9 E# a# \0 _                pHdr->free = TRUE;
    : M5 b6 P2 |- J                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));. N/ t) W3 g/ I; \6 D  e$ E. d# O* P
            }4 e. I& M/ a% {

    8 J, v1 ^; v0 _# Q2 O# D0 j        /* check to coalesce with the next */' R) D- s8 x# n- K& v" N1 N
            pNextHdr = NEXT_HDR(pHdr);- R% o0 D7 J* {6 N& l1 g3 b
            if(pNextHdr->free)
    $ r1 G* E6 O; x( x: b4 G: ]* @        {3 D' ?' p4 f1 o" g. o. N/ o) U  d( |
                    pHdr->nWords += pNextHdr->nWords;* _$ m: U8 z/ ^  d1 K* I
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    : d  q% \! G" t  n+ a" W        }
    4 {8 p3 i; G6 ^& W5 i# Z, \8 G: V1 ?, F- L; {; I( b
            /* cannot use pNextHdr->prevHdr=pHdr hear */! }% `  _6 q8 @
            NEXT_HDR(pHdr)->prevHdr = pHdr;
    4 k, |4 O% L/ D4 b. w: d* A5 K: `' z/ L4 O( F3 `
            partId->curBlocksAlloc--;
    5 z* m2 @: a" Z  {: a3 Y6 w  Z        partId->curWordsAlloc -= nWords;
    6 ^. w' D+ M) e: R
    4 S( i4 }8 F0 q+ y        /* TODO give sem hear */& k, P* Z+ n3 [+ f. O1 `
            semGive(partId->semPartId);
    9 i" A, K6 u+ ^. q% n- O9 Z# b+ K       
    % {1 ~3 D. W* G2 E# e3 u. v        return (OK);
    ( B- W# p. p. q1 G  a* h  e}- t9 ^8 o3 g( f

    ! a8 i2 a' j; z3 ^7 a" e8 Pstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    5 {+ u' \+ Z: q0 Q{
    : Y' |3 b0 l8 |6 ]3 v) _& i1 b3 k        BOOL valid;0 ?" U; |" r5 L" Z6 v2 H

    ! P! D, W! c3 E) P8 b        TASK_LOCK();
    0 L# N+ x3 f8 j) u* b4 c2 O) f4 F6 F        semGive(partId->semPartId);: V' U6 l' v- m6 D/ W4 W% y
           
    ! c' T5 Q& x+ a$ A* `        valid = MEM_ALIGNED(pHdr)
    , U0 [8 S6 n) [+ S5 P2 e        && MEM_ALIGNED(pHdr->nWords*2)2 Q$ [( U& }0 F6 {2 N
            && (pHdr->nWords < partId->totalWords) ( z. g0 ?! h: H5 \5 [' c6 h
            && (pHdr->free == isFree)+ d6 O5 v. k/ h. e  J
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))1 a; a1 N' x. U$ k! {8 p1 ^
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    . k* I* b3 v. {, l$ u9 F: F       
      p$ w# ^6 ~# F# B# {        semTake(partId->semPartId, WAIT_FOREVER);
    # X8 G3 C1 T3 R5 r; q7 @2 O9 u        TASK_UNLOCK();5 \, U' W. i. m

    ) W* e! l; [- _        return valid;% a, U/ r4 V  {' @( `; r) L9 B
    }+ H6 V/ A& a8 t- \

    ' ~' t5 k: _# kstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    * l' z- j+ a! U% {$ A# y' D        , FAST BLOCK_HDR* pHdr
    ( n: J0 b6 M9 ~( p! Z4 ~3 E3 O        , FAST unsigned nWords
    ' ]' d. ~- `: I% P2 f: R$ H        , unsigned minWords
    " L" P* z, o: A) e& ?% j$ c        , unsigned align)
    8 r8 t7 L; |( r* ]' b& R{
      ]9 ^6 Z+ D' O; @        FAST BLOCK_HDR *pNewHdr;
    / Y9 {7 c0 _8 {- a) Z    FAST BLOCK_HDR *pNextHdr;% j3 ^5 [  e% n) g( U: i
        FAST char *endOfBlock;
    7 v- c8 g1 e) {5 u    FAST char *pNewBlock;
    : F# i# ~' p, `, E. L2 Q& I2 k  T+ [    int blockSize;& f, @, W5 f% O% f( P1 U/ A0 M2 J4 c

    / a( |+ [- J4 l4 c( J# b! ?; _        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    6 [% |3 z% j' y, U( b/ z& |, C5 C* ^3 R" W
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    2 G0 O8 k5 c, ^6 p: f: H1 t1 r8 Q  q* l  ?% i- ?% ]% e
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));) m7 A! e1 v+ u, N' h8 H9 E

      J' @! {8 L5 R* ?2 T0 o        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    3 B/ ?: U2 h7 H! m& C& G! ^" N* E$ M- [. o2 @7 S0 F: E
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;$ F, L) i/ }2 C& X
    9 g& D0 E& p' p! N
            if(blockSize < minWords), H1 t: k5 i5 w4 r3 x+ ~+ B% W
            {4 O1 f7 x. {. \
                    if(pNewHdr == pHdr)
    0 i  j: T! ?- V. B2 J6 V+ ?* ?3 i                {- d0 q  ?& W; L
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    / e/ ^% e! Y4 d6 o, L                }. j+ A; E  x* b4 s7 z
                    else
    # s% b* c3 q. K" \/ {' x( H3 u" ]; Q                {
    ) z' T) `. Q- q5 p0 b( O, B9 c( o                        return NULL;: t4 K* `8 x' f5 G5 V9 j9 Y' s
                    }4 }2 X% A: Q# K+ M0 p% K
            }$ Z7 x7 m5 I+ @. q  f
            else; m, l% B* K- o
            {        /* recaculate pHdr */# W+ X, r  v8 p2 W
                    pNewHdr->prevHdr = pHdr;/ H; s" `( ~  D3 Y5 N1 D0 L* W+ i
                    pHdr->nWords = blockSize;
    % q# m9 H6 j8 W  f; i2 i0 ?        }% J! O9 U! E/ e) H# |

    3 x: Q7 g: O  P* o( J" O5 o        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ' j8 R: s, e8 U, `. N& j* o        {
    6 L( I6 T/ x+ Q$ u4 r3 ^" d                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;) U2 @, L( B; c
                    pNewHdr->free = TRUE;
    4 P. m3 \; I5 a# [8 D- Y$ V0 g0 l1 ~5 y. s  V3 r9 ]6 x
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;+ s# k# A5 W: x+ x% g/ w! E3 O2 u" ^1 g
            }
    9 N4 f- F) L. }  j* r        else
    0 c3 S5 H5 G2 q* |3 H8 C" z. F; j        {/* space left is enough to be a fragment on the free list then */! E  {. P/ v4 W; C
                    pNewHdr->nWords = nWords;
    3 y! m3 [1 e9 ~$ k& ?4 W  M                pNewHdr->free = TRUE;
    3 i: v1 a" {1 |, B% C) W: x! N6 M5 c$ r& M" w4 D# h
                    pNextHdr = NEXT_HDR(pNewHdr);
    ! f( X7 E. J/ l. r                /* words 包括BlockHdr */
    1 J* ~3 p2 A1 ~, l/ v                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 a6 ^* n0 V+ }: W: R3 V0 `* r
                    pNextHdr->prevHdr = pNewHdr;$ O! h/ s0 y" M6 N% d+ W
                    pNextHdr->free = TRUE;
    + b/ E4 H1 ], s8 ^* X% |% Z/ t
    , _% Q, c" H1 Y5 Q. i+ g3 n1 Q                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));) \# H: S: P0 e2 E$ p/ Q& b( s
    6 W* r1 r! O5 \2 z1 u3 U5 z
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;0 w7 {# }; m) j0 e1 @# l- `% _
            }
    ! o# a: O3 g$ U9 V9 P$ ?' G" E( j5 H/ ?" \0 K
            return (pNewHdr);
    2 G7 C: [2 ~# h}
    $ U# m7 h# w* ^0 {& e: Q4 `
    ) l6 E' n6 x6 q" {/ q% Ostatic void memPartSemInit(PART_ID partId), _! I8 g9 e' \: T0 C
    {
    2 p* @1 D4 E5 R4 A- W        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    ( c* x- ~" J5 R0 \4 o" q, a
    2 q) C: \% a8 I        partId->semPartId = &semMemSysPartition;: |3 E6 v: a  P1 L( J' V7 C' m
    }
    . l0 V' {; e7 u  h0 R0 E+ j* F8 T5 p' @, S1 k
    void* malloc(unsigned bytes)
    3 M$ M  {5 P: _{
    ; z7 X3 a, F" c0 W0 t5 d        return memPartAlloc(memSysPartId, bytes);0 R- e# U) u9 v4 `" M3 l3 Z- A) l
    }
    ( M5 m. y9 S% Q2 P) N
    0 z/ h7 K. J) Avoid free(void* p)
    + ^3 f+ l0 h5 ^" ^* Z{
    $ ]+ U4 c0 Y( \, N        memPartFree(memSysPartId, (char*)p);% p3 a- N: _# ?# u2 ^9 n& m3 I
    }
    ' J! {5 ^  U  c3 S# f6 }
    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, 2025-7-14 14:37 , Processed in 0.323340 second(s), 50 queries .

    回顶部