QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2839|回复: 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++下的版本,更方便调试。有需要请留言' D& s& J2 B3 ?  s

    0 f3 k# P$ V  i$ a9 h) H& R! r5 C) r, t
    , Q# R/ v' ?6 x) A( Z
    *\file* j% m3 I/ E  \2 b
    *\brief               
    # T  _& I' m3 r6 z9 o% C: \  c" q( x *\details       
    - T6 L3 ]2 t0 Y# s9 ]" W *+ {; U' {* b. e& H: L7 N- ]6 M. R1 ?
    *\author        Janson9 X% j3 z' j3 V5 r, c& ]
    *\version        ! h6 t8 g' Y/ Y! F
    *\date                04Jan12
    : p3 X6 e1 l3 a3 {4 F *$ u5 p& s# O( T! N+ ~/ E
    *\warning       
    : U: Q4 R) o8 [% v- {+ D; M *
    . t& c# a* x4 I6 m3 F *\history \arg        30Jan12, Janson, Create the file$ E+ N7 S8 z4 n3 q* Q
    *        modify from VxWorks source
      v( Q' K; d/ k7 l( M% o2 O+ b* ?  m *  Legal Declaration: it is for studying VxWorks only./ \; r4 u/ J. _8 d3 ]
    */1 k8 [: T' W% Z- w
    #include "includes.h"# J5 G( ?, M. j

    ; ]6 r# k. ?  y2 s$ ]+ u8 k/* The memParLib.h file is hear:
    4 [& C( W/ z) `- R( {https://code.google.com/p/vxwork ... rivate/memPartLib.h  s( Z$ f# r7 B! K. s$ d& _
    */' Z4 {# G# Z1 c1 P

    2 G" h" U7 R( Q/* optional check for bad blocks */% N- ]* L( g0 i- }4 n
    ; W) f( I. s- H$ l3 z' O: M
    #define MEM_BLOCK_CHECK                        0x10
    2 T, a2 ^* s/ ^, ^+ [1 X
    , A- O1 r: |* c& t0 D0 [/* response to errors when allocating memory */( m7 `. Y& Y, ]) x# I: r' u" [" H8 F  M9 ?
    6 C4 F# T% s' `6 y
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x207 V1 f/ g/ d7 e% Q" q
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    6 ^( z, u: a$ D9 U" y
    0 [7 ^1 ?+ V  Q8 `/* response to errors when freeing memory */
    : K+ i/ U, y% c- |6 L) z* f+ t1 m9 {+ g. D4 k" P: b
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x802 C& ]0 @8 j. f+ B4 L
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1008 L) r4 a! d% G" N' T
    / F% N0 y$ d# M6 h0 y( O. o
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))), n* @1 P( q4 m1 A( K( L/ u
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr): b( \+ h# x) s' B- U
    6 n! m2 X+ w# ?: O9 F* N4 Y
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    8 b0 y# B8 W2 S9 j7 S#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \$ V: |, A# M% s: _; m' o2 ]
                                                    sizeof(BLOCK_HDR)))
    ( d0 }+ }; c. {9 }& j! ^  J* |% c
    ( |; L, ~/ g; Q8 v1 ~#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)( D0 {9 \( F. w+ x( M9 U( x# Y
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \' H8 n% r4 v3 A5 f
                                                    OFFSET (FREE_BLOCK, node))): z, D3 ~$ x8 }7 K/ k
    : [8 R: q; _0 f! r! \. z7 F% N
    static BOOL memPartLibInstalled = FALSE;; a: M1 ^8 h! V* H7 ~$ w4 ]  H8 X& o
    8 g# C8 [& d' c6 h9 s
    static OBJ_CLASS memPartClass;
    4 z$ I8 _8 @# X$ H- T2 |CLASS_ID memPartClassId = &memPartClass;3 V, ~4 l) Y: o. Q% k$ ^1 L
    2 u* v5 h" a1 Z
    static PARTITION memSysPartition;
    + _" P/ T' Q3 `  Y3 \8 X# KPART_ID memSysPartId = &memSysPartition;
    . H; e7 M8 S" Z$ |4 ^! UU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;' k6 k2 H4 b* T7 C  h; V
    2 v/ ]6 u: \0 V2 A
    static SEMAPHORE semMemSysPartition;
    " U5 y7 ]) a( I. p! X; s9 J0 t3 Q, r  m% h0 ?6 H0 h, M7 c8 I9 c* f0 F2 P
    static void memPartSemInit(PART_ID partId);7 _, @% [# h. Q8 _# I5 J( T

    ( N+ e2 R6 X# v- k6 R+ b4 LFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    $ m& K) a% R* ?
    ; Z, \+ b: h4 f5 J; funsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    - t7 l3 S/ H8 K! A2 B, U
    / E9 O$ W4 L: A+ P: vstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);# z! W, D2 N, a& _# I: _( V! d9 A
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    1 Q4 l2 y8 [8 R/ U1 K/ U' D        , FAST BLOCK_HDR* pHdr* D, J; `7 D4 Z: N" k5 f
            , FAST unsigned nWords
    % M; p- r6 C4 Q, [, `' p! }; [1 g        , unsigned minWords1 U5 A7 c; s  l0 l
            , unsigned align);% d5 J/ A1 A+ ~( M& {: X- d! R

    2 o+ N: p  S/ Y6 xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);0 T  o# Z; ^3 C* {
    3 q) r8 i9 J0 s7 s4 V9 U
    STATUS memPartLibInit(char* pPool, unsigned poolSize)# k! C/ J: g! _% k
    {1 w: K. Q% `& r; w
            if((!memPartLibInstalled) &&
    6 |) e' X1 C( ~                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)* D3 ]9 d% F1 H( G
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    0 z9 e3 i# V/ ^* I        {
    * H1 r. G( {& R5 {4 [7 T                memPartInit(&memSysPartition, pPool, poolSize);
    ! b- Y- N" R) b  l# T. v* l                memPartLibInstalled = TRUE;1 w1 G0 T  B5 W
            }$ H* U/ k0 s: j  Z# }" h0 I# z
    ) G' s3 X8 _# R  Q" S
            return ((memPartLibInstalled)? OK : ERROR);
    / ?6 _  {' @, q! i$ h) g9 y$ o}
    ; F( A* D  {; E! I3 N4 t) v& I
    ' Z/ x; b" H9 i' i" bPART_ID memPartCreate(char* pPool, unsigned poolSize)6 ^8 ]) R. r# C% W- i) t
    {
    " S3 [' `& L' Q. i        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);* _5 [- X. G) t" O  ]# {! @7 T
    1 z, |, w6 _7 {* D
            if(NULL != pPart)( b9 x' }( n6 \# t* }
            {, x1 ^# `5 w% x  y0 o& ^1 _3 C
                    memPartInit(pPart, pPool, poolSize);3 I, j3 p- Y! l" e. }$ V
            }
    . G) M' a$ [6 D  r: Q, ]
    ; t7 W  \+ h  n3 ?& s        return pPart;# W" g5 D: i* u- ?. E
    }1 e8 B& P  T+ O9 F$ H

    & `9 R' d, i; Tvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    8 C8 r4 f2 }; L4 M{! u: }( W, H, I$ C2 O
            memset((void*)partId, 0, sizeof(*partId));8 @/ m; F% T6 L5 a- ^* p" T! h6 F
    + A3 R! L7 x- ]! d8 x/ S
            partId->options = memPartDefaultOption;  I* V$ w" v; a% N) L
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */# p) D' |/ W( u5 D7 c

    / H. h) t' G# X3 _' d        (* memPartSemInitRtn) (partId);4 J6 F0 V) {; _2 _$ ]8 ~$ `) V
           
    2 E' m5 {' V, k4 T% z8 @- G  z        dllInit(&partId->freeList);8 b- e+ f; t% `2 C2 W
            3 \5 M- E5 {$ n4 T9 K
            objCoreInit(&partId->objCore, memPartClassId);! Y/ O0 \  _# j1 N6 p  g, Z
            1 f: z) l, p- D0 M1 D
            memPartAddToPool(partId, pPool, poolSize);' Z0 ?9 A3 s( ~
    }
    7 ^# ~& ^& f9 H) f" D
    1 O  r4 h2 I; i$ ]+ USTATUS memPartDestroy(PART_ID partId)
    0 L- N" x. \3 x3 p5 \' a# |* k. g{
    " m3 R' h; n9 v        return (ERROR);# e3 d6 t2 m: ]
    }4 d9 y0 Q0 @& F8 a

    % C6 U: ]1 E: h7 A$ J# Wvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    * W2 M6 [$ a) U{
    + Y: {. R+ b7 \5 j2 u    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);/ J- v- C! Y5 t; r7 B1 A: `, v
    }
    3 d: m" `$ @2 x5 A6 N8 |+ V, e' ?4 e5 h" Y
    " w4 Q5 {! [% n2 M) n4 y; t
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    * Y) ?4 }* @* e# H{
    ( E2 x( ~  U# A        BLOCK_HDR* pHdrStart;* P6 W" C$ B2 _
            BLOCK_HDR* pHdrMid;0 a7 c1 Z% ^7 S2 q5 b
            BLOCK_HDR* pHdrEnd;$ U4 Q* g' E% O* K& o
            char* tmp;1 j, a5 P, g' J* C
            int reducePool;, a# ?: ]9 K' j4 g5 k' q
    ; R* |6 s; w. @' v; \$ a
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    : a$ L. L" j+ H: s4 E% a4 G        {
    ; ]; ?5 h9 u) v  W3 m                return (ERROR);7 R* E7 s! U' E6 a1 W9 y6 X
            }9 `$ r% S7 a  |* z1 g
    % S0 c, ~0 H8 c6 S
            tmp = (char*) MEM_ROUND_UP(pPool);# B+ X7 o5 Q  h  c+ ?$ ~3 r8 L
            reducePool = tmp - pPool;  u  m- j8 @7 i
    / g9 O1 z. H9 ?6 X
            /* adjust the lenght */
    3 `6 g$ W) f, h3 Y! d4 @$ T        if(poolSize >= reducePool)
    / ~9 Q% k+ B9 c- s: Z! C        {
    $ c4 ~5 p: M& z+ z                poolSize -= reducePool;/ I- N/ [6 `% u4 D9 c
            }: V/ k+ L2 g9 \$ x' _
            else$ `1 O; y' h; S4 D; j: f' x9 T( k
            {
    5 J% H% D/ n0 M% j                poolSize = 0;
    ; _; U9 f" u  n* G' o; g        }8 A/ w  E1 x. v
            pPool = tmp;* \1 z3 e$ Z, `  U; X; M4 ^: p
           
    0 G2 X! N  n9 z' _! z/ N" w! i        poolSize = MEM_ROUND_DOWN(poolSize);
    4 N" m# B( n" ?9 e* V  o       
    ' y5 {' h! Y3 l% |8 w9 o        /* at least one valid free block and three header blocks */
    5 d$ d& ?. D3 `2 G        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)8 {' l8 r6 ]( R) i4 e/ @* w
            {& g& S+ S/ }* v, X
                    return (ERROR);) h/ x9 B) q- @  o1 J) f
            }9 o, g7 k$ H& s3 H

    ! z7 ]2 B# G2 P% D1 v8 J        /* initialize three blocks */) g2 u% X% n8 N6 ~
            pHdrStart = (BLOCK_HDR*)pPool;8 c6 ?$ k/ ?% ~7 ?/ G
            pHdrStart->prevHdr = NULL;
    ; r$ P1 X0 }) g9 y2 ]4 F; R        pHdrStart->free = FALSE;                /* never in use */, O3 W5 k- N7 T$ u
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;; T0 u9 J/ [/ v; a$ `1 P. |
    / C& ^4 D+ T6 h1 Q. p$ H/ R
            pHdrMid = NEXT_HDR(pHdrStart);
    7 g+ q; d- {5 c        pHdrMid->prevHdr = pHdrStart;
    ( p; O- X' G9 F& E% @" r" m        pHdrMid->free = TRUE;                        /* the main block */8 L9 s8 Z+ u6 d/ s! W
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;( f2 ~$ @: F, ^% {# \+ U8 f9 V

    ! |) S8 I6 B% k( m# k8 \3 f1 o! ^- v        pHdrEnd = NEXT_HDR(pHdrMid);6 w6 R# F- w; Z
            pHdrEnd->prevHdr = pHdrMid;2 U. p3 a7 A% Q" q: k
            pHdrEnd->free = FALSE;
    / y2 m, |: e4 b, M3 l0 b* F" q        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;8 M; U4 w# g" M: t: r

    5 {7 M4 I  C! \/ v$ S        /* TODO take sem hear */
    8 j: ]- {+ Q# z        semTake(partId->semPartId, WAIT_FOREVER);
    ' N1 E9 k: \2 G) G! W        ! S# M* N' l. _! l% |+ @+ X
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    9 v- U3 B! e6 S2 q$ I        partId->totalWords += (poolSize >> 1);
    9 B: E; }% L. g8 N; I! }. d# ?0 D
    3 }9 R) Z) }5 \  s+ g  p0 g        /* TODO give sem hear */, p9 H( q6 w1 y# W, }9 d
            semGive(partId->semPartId);$ ~) f" z6 v. `. [# h( ]" z- f
    ) J( X8 l: z3 t" _

    - s  i( a) ^- F& {6 Y9 P, S        return (OK);
    / Z2 Z! {8 `2 @6 g4 z  Z}/ h7 }3 F2 r1 _" {) ]7 i
    * M6 i: U0 l- ^5 d
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    # s- g& v6 l! f9 j4 z+ t{; ~+ Y* u! [' U5 H& |
            FAST unsigned nWords;
    8 m( A7 Q% X: R2 S        FAST unsigned nWordsExtra;) }5 E1 N# {. R; J$ J4 ?
            FAST DL_NODE* pNode;8 T: ^# ~9 p9 f9 c$ O$ x6 Z
            FAST BLOCK_HDR* pHdr;
    2 R( Y. j6 }5 ?        BLOCK_HDR* pNewHdr;
    / D6 U  k3 P% O. |9 H( D4 z        BLOCK_HDR* origpHdr;2 c; r" P* V9 L. Q3 l- I9 F9 D
    7 k' T- d$ z# [  A
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    8 x, M8 ^, }# _+ Y5 X        {
    - J9 s: b% w: ]1 ^3 O                return (NULL);  a- v% j3 u, o% W" M5 v! ?
            }
    $ I  K6 n5 c/ n: N7 y9 `, l( P1 c  T. h
    " X& R& j; h- Z+ ~0 [        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    9 G/ R' O6 z7 _# u3 f9 J; M, t" @9 ^. ~0 n
            if((nWords<<1) < nBytes)
    - X5 a" n/ w9 |( O. s  C        {
    . K! j; L6 O  ^5 H3 x                /* TODO suspend the task */0 M& D3 l) y. U: t2 ?6 O
                    return (NULL);1 I8 x: ?3 I2 a
            }
    + G! S1 ^: {% H! B/ ^' y0 p
    1 a  s9 T0 Q* N3 M        if(nWords < partId->minBlockWords). |" N; N% L( l* [( Z0 _
            {
    ( h1 x# N" q3 A$ U$ D                nWords = partId->minBlockWords;; b9 X' x5 @' R. D, ?, N7 N
            }
    % s2 t4 Y) @8 h" i4 P- \. w, n2 b
            /* TODO task the semaphore hear */
    5 I2 c, [; m' m        semTake(partId->semPartId, WAIT_FOREVER);4 Z: O+ x7 W! @6 t  O9 t: \3 q9 g
            pNode = DLL_FIRST(&partId->freeList);, p, u3 K! G5 r- g
            nWordsExtra = nWords + align/2; /* why? */
    & h; E, D1 S! u9 I
    % @0 m! o2 j$ Q- A/ X        for(;;)9 a0 X4 s) ^8 s; F6 `) h
            {; J0 \. I4 ?6 l
                    while(NULL != pNode)' v  }3 R/ b2 p2 o/ y9 h2 `
                    {% u" E5 I& K9 w3 b
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||1 O# l7 |. S" {
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && : y% w+ S  Z1 B+ g  `" y  a
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    # R/ h! k3 f8 ^8 Y! k" |9 Z. `: V  ]                        {
    ' d2 r6 {  z- i- V                                break;
    , E: x2 }/ f/ d) k5 z  ]                        }
    ( p1 X& `7 B6 X2 k) f3 ]9 h2 `: N$ [# ]" X  l2 y, k7 I% S
                            pNode = DLL_NEXT(pNode);
      R2 t0 @3 U' p) s) i0 }5 a, T                }. U0 \/ I  u& r$ p4 w
    - m. |6 L- H' c6 w0 U+ n& _  c( V
                    if(NULL == pNode)' v2 V8 l* q7 o1 {; O
                    {
    * C1 h0 n7 I9 ~( W) J- M                        /*TODO give the semaphore */
    + C; {$ E0 d2 _* F0 y                        semGive(partId->semPartId);
    9 o$ G; ?% K: F5 l                        return NULL;
    , _; L6 o1 {( z7 y                }
    3 j) L+ i% e+ F
    7 S. t3 e" ?9 X5 |/ j/ S                pHdr = NODE_TO_HDR(pNode);
    0 Z/ j" C+ C1 a                origpHdr = pHdr;
    9 ]! g; N+ n* J4 z
    + F; \& x& x7 m# C: t                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    ! ?! ?# Y6 S2 g% Z                if(NULL != pNewHdr)
    ; D5 _- P+ v9 b# K                {
    , l  h+ ~: D; l4 v& z* l                        pHdr = pNewHdr;, w; e$ W& [# |4 Y8 A
                            break;9 b: C) _) p# V4 X. H, x6 ]
                    }
    " {# g- v: P0 a% Z; ?7 t# e, N: v4 q% ?: b2 Q7 }
                    pNode = DLL_NEXT(pNode);
    6 A0 q6 ^. X+ k  {- \        }
    ; ^5 F8 r5 O& a1 @" L# ~7 t. ]6 T1 s0 V1 W! r
            pHdr->free = FALSE;
      K5 V+ B! o) g8 t; P; c  k        partId->allBlocksAlloc++;
      S& |" Y& Y* _; E8 A        partId->allWordsAlloc += pHdr->nWords;
    3 s" ~- t; z- ?$ @. E5 }5 P5 j3 Y        partId->curBlocksAlloc++;
    - o: K; C0 M5 t6 c! `4 k! Z        partId->curWordsAlloc += pHdr->nWords;
    ! [. M! Y9 S0 g- o/ |2 J
    ) Q/ E& N5 l+ h5 e9 P        /*TODO give the  semaphore hear */: g- N( f9 `3 w2 F3 P0 A) s- M
            semGive(partId->semPartId);
    " X6 c6 {7 z$ R$ S3 A( C* g        return (HDR_TO_BLOCK(pHdr));
    . M. M+ O4 g% n# Y6 [       
    0 K/ y$ [0 q, S2 J7 l+ S+ A* K. b}
    3 |1 i, [+ V# e7 J- I
    * F' ~1 a4 N$ }+ ~& V* }void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    7 m; h& a" _3 ?{5 T( `  ?) ]) J9 W& t2 k9 l! y  \
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);9 G* y9 }( K% c/ Y! {. A, I! S
    }. {& u- a5 S2 m* v

    . h# [/ B; E9 `3 ]STATUS memPartFree(PART_ID partId, char* pBlock)' p( F9 u% |! u7 ~. y
    {; J, s, h& i0 B  x9 a& {
            FAST BLOCK_HDR *pHdr;
    # c# ^; w* S! Z1 c, n8 l    FAST unsigned   nWords;5 n/ o4 M  t6 n% z
        FAST BLOCK_HDR *pNextHdr;, U) |" Y! K. A; ^7 ?( S
    & T* f$ L: C7 x7 r( V
            if(!IS_CLASS(partId, memPartClassId)): X: z9 H% ?, o- s# Y' ?* ~- g
            {
    & e, o' A0 t1 C) q1 i                return (ERROR);: W0 t' o! F5 ^
            }
    7 a$ Q: y* b' G0 o& }; E: N: W, z' j0 f, _" N, o- B# T
            if(NULL == pBlock)  l# V, k: Q$ z4 w/ S. z
            {* z, L3 B3 a! Q/ e& ~# z5 ?' D
                    return (OK);
    / Y1 O4 w/ D0 N) }        }
    . ?, z/ V. n6 |! W
    % a: g& h# @& p# v        pHdr =  BLOCK_TO_HDR(pBlock);
    , _5 q+ G1 d7 c6 b5 t6 U# s( D5 o
    0 `" r3 Z5 B+ s, M5 {4 ]5 g" e! e2 t        semTake(partId->semPartId, WAIT_FOREVER);
    0 y8 F9 {5 K+ g" x; H: a: w
    " i  ^3 T8 C) f- ~4 s) o1 Z        if((partId->options & MEM_BLOCK_CHECK)
    6 }9 A$ d  c8 R7 m8 g5 U                && !memPartBlockIsValid(partId, pHdr, FALSE))) ~! `+ o) Y& ]4 \
            {5 c) _" Y) B: q
                    semGive(partId->semPartId);
    " l, @7 z4 z- }  c2 `                return (ERROR);. O* d+ a+ z2 |: M$ O  `  B
            }
    ' L2 }5 S1 w+ Z& |. u. S: ]' N' E; t: ]2 I7 _! V0 d  W; k
            nWords = pHdr->nWords;' L  I  G6 K" F# c& p( Q
            if(PREV_HDR(pHdr)->free)$ B# d1 O( V4 m4 n" y' ^
            {/* the prev hdr is free and than coalesce with it */2 Z, b1 h' J5 t5 o' }. Q
                    pHdr->free = FALSE;* P$ S9 B9 ^5 x5 B2 [0 c
                    pHdr = PREV_HDR(pHdr);2 m: U7 G' H1 ]
                    pHdr->nWords += nWords;% \+ Q  g' g+ X5 Z8 F9 j
            }
    , S: r3 p# U. a4 f0 E. v( z  q, a        else, `  c1 n2 w; H; D8 B
            {8 W- z* E! \9 N2 i; L; K
                    pHdr->free = TRUE;; {) d) u" l5 V) s
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));; Z3 N2 D7 `4 g4 m9 t5 }9 d
            }
    : y1 |! j8 O: `7 b2 h" o& q* |
    8 s" ]" T$ G' Z9 c        /* check to coalesce with the next */
    9 g: u; t; Q$ N  R2 }5 V0 v        pNextHdr = NEXT_HDR(pHdr);; H3 l+ a( r, R1 M) q. l8 M& i
            if(pNextHdr->free)
    0 z: o& J+ o/ ^# Q        {6 a% d7 V4 M. J- T
                    pHdr->nWords += pNextHdr->nWords;# o) x* }/ U4 E# E; w
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ) p+ ?2 C% {) y9 e/ a0 Z, j# M        }& ~- Q& z6 d0 f( ^
    ; \3 |9 p  u& z) E6 Q; x$ F
            /* cannot use pNextHdr->prevHdr=pHdr hear */5 {2 h, i* h. d1 z2 `
            NEXT_HDR(pHdr)->prevHdr = pHdr;: y7 O2 d7 O$ b, B. M

    ; l5 H4 @' u! ~7 Y+ }        partId->curBlocksAlloc--;! Q1 ]4 \, G9 q
            partId->curWordsAlloc -= nWords;
    6 r8 X! Z% k0 j4 R: Y/ E9 @4 d' P" d7 b8 d9 L* Z
            /* TODO give sem hear */3 B2 K8 y7 P# t+ P, p
            semGive(partId->semPartId);" y- P# A# K* `: R
           
    ! O- A* b) a' S) G: T4 R7 F5 M  M        return (OK);
    4 m0 z- V& w+ x, V, f' _. I}6 y. S0 ^- V% v( s# b

    + Q) W* b( W: }3 R8 [- Y1 V/ ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree). G! j0 Y; ~+ E- K  {
    {
    $ M" |; W% n( S        BOOL valid;
    ! v1 }' m, B) i2 |" `$ X& Z3 V- V
      f8 |# Z. T- r9 o        TASK_LOCK();
    2 O, V. Y  Q0 A        semGive(partId->semPartId);2 W0 C0 c# v. K8 C0 S' t9 c
           
    + p- J, \8 Y3 I. K' W        valid = MEM_ALIGNED(pHdr)
    * P) I! G6 Z8 T1 \0 H        && MEM_ALIGNED(pHdr->nWords*2)
    + R0 j4 d& r+ x        && (pHdr->nWords < partId->totalWords)
    " c# r  I; D% n- a8 W3 m) ?        && (pHdr->free == isFree)/ }  E5 z# o" A- w
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    0 o/ ]! u2 H1 c, C* ?        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));' F4 P, M9 Q- w; U$ k
            0 d, S: Z7 P4 R% A9 [
            semTake(partId->semPartId, WAIT_FOREVER);
    : X# |/ U# |' D( R  _8 D        TASK_UNLOCK();
    5 ^8 ]& Q5 `0 ?$ u  |/ ]  \, |2 K0 t
            return valid;
      b; e" H4 N. ~  p}+ M8 Z+ n4 ]7 V" d/ o

    9 Z+ `) t9 H0 g+ r( |; ]static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId# O3 d4 t8 A3 e
            , FAST BLOCK_HDR* pHdr
    3 G6 C" u/ d7 V4 ~/ G        , FAST unsigned nWords
    ! j" P; J) ^& B- J6 v$ F        , unsigned minWords/ c' Z7 {" L$ J6 ~& R, y
            , unsigned align)
    & r. u: |5 o- x{
    5 `. p7 L) w5 w9 Z        FAST BLOCK_HDR *pNewHdr;
    5 N0 e" N: l4 {4 D/ C    FAST BLOCK_HDR *pNextHdr;1 j( V& a& Y% A/ L- C! ]" u
        FAST char *endOfBlock;
    6 j0 H7 `8 [0 x& t; X& T    FAST char *pNewBlock;7 b% s/ ~6 X8 U) P6 G
        int blockSize;
    & z7 V5 _& ~- v" o8 I: H
    5 l0 V8 l7 B; J( j# e* P; A9 [5 Q        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    : x3 a8 k3 k* {) l: h, t
    + u% H1 i2 r% S: H+ u/ n        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));; f! h1 ]  @5 ]5 d7 K: A
    ; X7 ~; X$ I  y8 Q* c
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));4 \4 o+ D+ N  P- \9 x, M' g

    3 h/ ^% `, r, {  h, O* C        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    * `$ b- U9 x) ?! V0 {0 f8 c5 k) K  E# d8 M; h
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;. J: J0 x1 d8 a1 M4 V

    3 J4 Z" j* m0 F' ]) x        if(blockSize < minWords)
    0 [4 b6 `" y6 P, ]! Q) [        {: M  l) {5 w1 c' G! S
                    if(pNewHdr == pHdr)$ s! w3 C$ ^7 t% A2 [. r& L% d
                    {. s6 M; u& a2 \
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    , R" f8 l4 m- @! I2 H! y+ R7 a                }
      w% L* G5 E4 x                else9 M3 ^5 ^% \4 e  S
                    {  k8 d2 m: S# M
                            return NULL;
    / C: d; L0 C  M' N                }1 T+ U4 j2 t- i0 R
            }
    4 v; {2 ~* i6 R7 ^        else8 t+ F8 m) u5 q- x) T. O
            {        /* recaculate pHdr */
    , n3 @0 |; J8 o/ C                pNewHdr->prevHdr = pHdr;/ i% {5 I* F$ s# p% k2 m7 a  b
                    pHdr->nWords = blockSize;
    & M% ~% X! x' A* I: ?        }
    4 j3 Z1 a1 k' ?# q7 q! s( J7 \. Z, [( {0 o* T
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))6 O6 p2 r2 i" U5 V
            {
    ; `# v2 |0 u& v. l8 V                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    6 P6 ^. l( N: s" G0 x3 J( q2 B5 W                pNewHdr->free = TRUE;
    8 y% p$ N: N1 x# ]. L4 f2 c0 n, y/ I3 Z  h6 W  {1 @, W  j. Y
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    9 k$ F" f* r; M2 V: M        }& d( m. y2 N* N- G
            else. E4 z3 P- \  ~1 b# C  F& d! g8 h
            {/* space left is enough to be a fragment on the free list then */; T% e: X$ R& u& N8 i/ D
                    pNewHdr->nWords = nWords;
    - B5 z) v4 Y' x/ u* F                pNewHdr->free = TRUE;& Y# P$ A* Q1 @8 W: O5 W

    / F" q6 q% e7 s+ @                pNextHdr = NEXT_HDR(pNewHdr);
    6 B7 v2 q+ p& w" |+ y                /* words 包括BlockHdr */
    7 M( g3 x4 t( e; o' r9 W$ Z5 S                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    : q" l: Z4 q& Z7 t; y  G4 b- H/ [                pNextHdr->prevHdr = pNewHdr;
    9 D5 S5 G+ z1 ~2 O! `3 t2 j% a                pNextHdr->free = TRUE;+ L7 K% s6 \  b$ l3 C3 a2 S
    % X0 V+ N1 F; {; J7 B
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    3 l; K  A3 ~" _, R" z
    8 R8 ^; V( b+ Q* T3 ^& K: B                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;" E1 ]' h, M4 I# ^; G8 r
            }
    , N) R1 ?' H' d6 \6 Q
    " {1 N  O+ ?' b! E, S" l- {' F        return (pNewHdr);4 r; k; U, Y9 e' J+ X7 `+ }
    }7 J/ R/ C2 ^' i4 I) b& F9 S
    9 N) H7 J8 d. n
    static void memPartSemInit(PART_ID partId)6 i7 n  k. |3 W0 l. L
    {. y2 @0 M1 U8 n5 `0 m) X
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);4 z3 q) P6 [4 _5 D6 E0 R+ f- ?4 g

    9 B6 _  {9 ?& C        partId->semPartId = &semMemSysPartition;- ~# L; `6 D) L7 R' c7 R
    }, B/ w8 y% M$ D

    . Q+ a% O! t, _6 t! e: R7 K- jvoid* malloc(unsigned bytes)
    ' n; v7 s7 T/ r6 E  X. X1 K: A. k{( B3 F- U8 y/ n; [9 }3 L' }
            return memPartAlloc(memSysPartId, bytes);- S$ J' {# o2 m4 e! I$ Z6 @% C
    }
    - s( E; ~. I' ^; ~# z2 O$ F. v* C& K2 T+ }. ~/ M0 i
    void free(void* p)
    / T5 h3 l, O- I, ?& j/ D{4 H- I8 @) ?* j3 j* n
            memPartFree(memSysPartId, (char*)p);0 Z# y) C# L/ K
    }
    4 i% x, S& c/ c* {5 |5 [
    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-4-18 20:00 , Processed in 0.433077 second(s), 51 queries .

    回顶部