QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2644|回复: 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++下的版本,更方便调试。有需要请留言8 B, X! {6 l% G4 Q! c- e' @
    " h0 |( s; k& U: L3 i

    4 a' k7 J& L5 S; ^9 n) w3 b! R" H; Q3 ~7 Q, n0 A3 k  x" J
    *\file  h! `4 Y8 S( e. l' p" Z2 U
    *\brief               
    ; m0 [, ]! p. u- t4 S *\details        1 R# f& d1 a* ?: m
    *2 n& a* {& n" H! X& a$ b3 O
    *\author        Janson
    # n0 P7 F  H- r7 ?8 h- H# u *\version        % t3 `& S5 N0 F% }8 {4 g0 A" O
    *\date                04Jan124 B+ q4 i/ P, t# o: U+ K+ }
    *5 P  J2 O: E! ]6 q' n
    *\warning        - O& b2 o! m2 R- K$ r
    *
    % l8 S5 o8 j! J *\history \arg        30Jan12, Janson, Create the file
    5 A0 l% _. u* a# V. S *        modify from VxWorks source
    8 F5 {" t4 b& N0 K; R, } *  Legal Declaration: it is for studying VxWorks only.
    / m& A, a3 o9 m6 X$ l */) L5 l7 y* H/ Q. Y% D, F9 q
    #include "includes.h"
    ' }: N" N9 }0 l3 T! m, P
    5 Z3 G" D" H/ ?4 w  R; F, a/* The memParLib.h file is hear:6 g0 L4 Z8 T, z1 h. C4 g3 I0 O
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    : ~- \4 }$ A6 t4 z*/7 s: u* N1 E: G: ]) }5 l

    $ s% s. O- N2 {! R2 W/ Y% [/* optional check for bad blocks */
    - D' Y4 y% K7 [9 N2 f* m- Z  Z) ]6 P+ p
    #define MEM_BLOCK_CHECK                        0x104 I7 X9 {. A' a! v. G4 W

    4 ~' v2 A3 x3 N0 N; v/* response to errors when allocating memory */9 ?  O9 g  l/ X5 n
    # f+ z8 w+ ?+ i. f$ D9 ?2 w
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20) K: d/ S  b( Z# o; Y  p; k
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x408 ^$ k' i' X9 i( n% {
    7 c. `0 B( O3 P9 R5 l% M/ t
    /* response to errors when freeing memory */1 E% N2 |% n; z3 J

    ( J% X% H( x+ h. P/ r7 }+ c7 {! C#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    9 X1 U# o( @$ l#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1006 N4 l# M2 T) R+ }3 H4 m! d

    8 d0 S3 @( \. I; s#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))$ b: l! \* ]- l! c0 g; W
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)( r0 i4 O  a% u- @5 Z5 T/ l

    , M2 P* m4 \$ ^! E#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR))): c8 m, a0 P2 l3 [6 V: y& |
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    " z1 y7 ]0 s& |5 S# G  z                                                sizeof(BLOCK_HDR)))+ G  d1 F+ w! @0 c/ I  u0 t' M
    & B$ j) ]! U. I; s( }
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)$ o- K4 x$ i1 z1 j% Z
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    9 U; _! Y3 B/ T' H) X  z. j6 ^, B4 \                                                OFFSET (FREE_BLOCK, node)))
    ) j, J7 F1 \* F3 y% e! U# Q# \
    * v) C# L8 _6 q- l3 I' Q; \static BOOL memPartLibInstalled = FALSE;
    ( R* w7 W' ~5 Q5 e
    3 u9 Z. Q8 r- L5 \/ ~" [! [+ xstatic OBJ_CLASS memPartClass;- Y; T0 z$ x2 i7 [7 ?* B
    CLASS_ID memPartClassId = &memPartClass;& ~2 D( J+ ?. ~; X
    6 w# T! G" J: ~6 F. R* P
    static PARTITION memSysPartition;
    ! ~$ T, d7 ~* i* V: q- N5 NPART_ID memSysPartId = &memSysPartition;/ |; {+ P2 b+ x) o& C
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;  v. p3 o: J( y$ e- m; \

    1 p6 I' V' v9 T! X: |+ Xstatic SEMAPHORE semMemSysPartition;$ \  t' Q- X0 }. Y! V. U+ t

    4 c) P# P/ G! g6 ]4 Dstatic void memPartSemInit(PART_ID partId);" h% z6 g2 W8 l
    4 B( T: b& u; y! Q# X4 q5 f- |
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    ( F2 k& B1 E& [2 I5 b  Y9 N3 O1 j# s
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    % h+ g0 d( R7 z9 A" J2 z' P; d4 L9 C* M0 D! v5 J
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);3 t% f: |. p2 X& p6 ^: |
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId1 \4 M) T* h# `# D4 g
            , FAST BLOCK_HDR* pHdr
    / S' o" Q) `4 N! D  _6 [7 y1 x$ g        , FAST unsigned nWords; a$ [- R5 E5 O* Y
            , unsigned minWords* O+ _5 P) Y9 @/ b$ N
            , unsigned align);9 T" h4 Y0 ]1 F3 ]* |' A; f! w

    : K  @6 H' z1 f* J7 Pstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);( b: e  a! x1 E9 C/ G- o" X) K( @( u

    / H% N% m# N0 K' YSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    7 V% U( V' P& M' s3 u; h{
      w: P) I; O/ R; q. |; ^" H        if((!memPartLibInstalled) && + q7 q/ ?  ]; j5 H9 U1 O6 f
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)& q6 ~6 b! O) V/ d8 d+ \
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))' T3 U9 }+ E9 ]+ i# M* c2 i6 J- j
            {
    " y& L! J+ w) w                memPartInit(&memSysPartition, pPool, poolSize);
    1 x; Z) J+ {, C0 L                memPartLibInstalled = TRUE;4 B; ?( E) e( a6 x; o# I- U* h
            }& y) G+ O* g/ D1 N! g  h% p
    - {- \( @* Y3 l! |8 z
            return ((memPartLibInstalled)? OK : ERROR);3 s) B; ]* i9 a
    }5 Y8 C  Z  m0 U, {4 U, ?

    ( H; l% b7 g) Q! a4 X" Z3 LPART_ID memPartCreate(char* pPool, unsigned poolSize)
    5 F4 z0 R+ f: \& o* q1 g6 \{
    " g6 J5 r% Q0 W- v* G7 m. `; g        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);* U2 r7 T2 H  c/ R7 m  j+ A

    & o2 w( m; K( m        if(NULL != pPart)/ k7 ~: ~6 q+ f5 [, j$ [! q' c
            {
      R- X6 b. v8 @                memPartInit(pPart, pPool, poolSize);
    4 u- k, B5 Q. n4 f9 {. {        }+ r0 e- H6 W! L  m1 H

    2 P1 `5 ~+ J7 N! g  y" y        return pPart;. W- A$ G( n( I, Q* ?
    }1 B+ D. N/ W7 O( J2 _! o- K

      O  `% x9 n* d: x5 _" evoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    ' j1 M! I. R: S9 R5 c: N( |{0 d$ {! w% b0 G1 o  O+ F
            memset((void*)partId, 0, sizeof(*partId));
    7 v! \* u* S9 ^" U1 T  M% ^
    / [& r5 |. C7 v) T7 |        partId->options = memPartDefaultOption;
    ; @( \" C1 _5 w0 \. S. O        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    : d4 l3 [+ r: }% w) D7 a) t4 I; v
    . N6 q3 ?6 P, l( ?. U& A        (* memPartSemInitRtn) (partId);
    5 U3 o% H+ ~( i% Y& T+ B       
    & c( G: N2 z0 G) p        dllInit(&partId->freeList);
    / m4 T- K3 \5 U. }# n/ A# Q0 `5 p. G        , e) T4 R; S, ~/ r) k4 V4 s
            objCoreInit(&partId->objCore, memPartClassId);( [( P7 y/ q; w/ ]) X
           
    $ n0 x: h$ h. [2 \+ U) B& T8 t        memPartAddToPool(partId, pPool, poolSize);
    6 T4 e! I; L) E: k) v}* N& |& }% z& L/ `0 e

    + q' p" y! O# G! l% r8 JSTATUS memPartDestroy(PART_ID partId)
    ; P# R3 x( c' E# C( A  c4 a; j{
    % g" J* e; D& `7 z        return (ERROR);
    3 y/ ]: @2 V6 ^4 W9 v3 H' m* V$ ^}& p8 \5 p$ A6 r6 ?+ z; v

    " m1 ?% @, R: F6 Y% W* pvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)- ]" S: t, a9 W/ \4 l+ U
    {
    - u/ d4 o. p$ d: _    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);- ^# e0 K* I: C5 D  E2 {6 m# v8 j; I
    }
    $ Z* s# g; A, K# h
    # X" f4 ?# u1 x$ R9 I5 U
    ( t# R: _. E5 H, s0 x3 estatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)! `* ^5 n$ a" M, M& t0 q% P
    {
    & \7 C( S2 s  G        BLOCK_HDR* pHdrStart;3 n+ S- V! |" {0 U, K6 l
            BLOCK_HDR* pHdrMid;
    & ?5 p6 v9 g$ V; ]+ n: V% E8 U6 ~        BLOCK_HDR* pHdrEnd;1 ]1 g$ C9 G9 [6 |3 `! O
            char* tmp;0 S8 R& f  }0 f% u  E- z2 A
            int reducePool;$ \+ d7 g8 A" {1 A
    $ W3 h+ @( v. ~/ W! i* m
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    5 n5 m2 Z# E; `! g, l' I) A        {# M4 i2 b3 q  l$ c9 B6 @; }
                    return (ERROR);
    " Y0 s- f/ V0 P5 s/ Q        }1 A7 [  v) ]8 M: g4 _) G

    % F( C! t) n& g8 g* K. h  h        tmp = (char*) MEM_ROUND_UP(pPool);
    - n. r& {% A5 f$ m0 l0 i        reducePool = tmp - pPool;
    % n5 E, I: g2 w$ `# V  d! B7 O; V# G- `4 n, l
            /* adjust the lenght */
    ) B2 }4 W4 i  O9 g( y. ~: g        if(poolSize >= reducePool)
    , p0 R5 R9 M; y( O7 ^/ P        {9 i  l# l! x( J# {# _& c
                    poolSize -= reducePool;# }" N4 J$ @7 {+ y
            }
    4 |& Z% P, f0 ]% g- }        else
    7 Y/ N1 C! |  x: H  g        {: c: {+ b2 M, o. j1 F% }5 q: ?7 Z
                    poolSize = 0;6 }8 ]) \: R7 ~2 c) y: J* c  a
            }. Z. ~7 l' G: s/ i# \
            pPool = tmp;
    7 K" @7 e# |# l       
    $ s+ U8 X, M' O' K. ?" v% o        poolSize = MEM_ROUND_DOWN(poolSize);0 T$ T2 o# x% X2 _8 f
           
    7 X" j( h4 t! ?' }' i$ Z2 b- B) T4 p  r        /* at least one valid free block and three header blocks */9 O1 y6 K# T+ {9 }3 G
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)" j# P9 u# c! }! e: [
            {
    5 i; T! S: J# Y; P; N                return (ERROR);
    5 G7 F& x& J- S        }
    5 S0 _9 z" ~8 U6 B+ n2 |+ [, X/ {
            /* initialize three blocks */
    & H* |7 N/ d# B- l        pHdrStart = (BLOCK_HDR*)pPool;
    $ B# e9 k1 G( S: C1 H9 `        pHdrStart->prevHdr = NULL;
    , v3 q- I2 Q0 K1 F/ G1 r        pHdrStart->free = FALSE;                /* never in use */) z7 w% F  h4 Y  Y. H+ i
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;2 [7 I4 U, @; P% a* a

    1 a, ~+ X; ~$ I/ j) y; Z( s) ]        pHdrMid = NEXT_HDR(pHdrStart);
    + X2 v2 a# V4 K- v" Z% [        pHdrMid->prevHdr = pHdrStart;
      G9 O' ^8 L( f7 d  y* ]        pHdrMid->free = TRUE;                        /* the main block */3 j! D+ w4 E& [% r2 ]" g( K" ?- V
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    8 n! ~9 |7 L& c8 K3 M/ k8 F  z8 A* I7 q
            pHdrEnd = NEXT_HDR(pHdrMid);
    7 r; ?' i0 O* N: Z        pHdrEnd->prevHdr = pHdrMid;+ y# _, B! I- C1 p7 v1 @: S
            pHdrEnd->free = FALSE;
    5 o1 m$ k5 t9 c' ]6 A        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;- w" b0 k$ j& d% C) V6 z
    - E: P/ M7 h" _6 g1 s
            /* TODO take sem hear */# c9 B9 n' v3 y. _
            semTake(partId->semPartId, WAIT_FOREVER);
    * N% w) j. k) o        & S9 z* Y- A1 F! h$ b+ ^& O
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    % |; c# C& a1 n7 B6 I& |; _. C' q1 m8 j        partId->totalWords += (poolSize >> 1);
    ( I* O+ P% q2 Z+ d" ]$ t1 N6 s+ R6 h3 l/ Y: s5 J
            /* TODO give sem hear */* g1 k- D1 n7 Y5 y, g
            semGive(partId->semPartId);$ F* A$ d. [8 A+ m% i
    4 q& d- d% l6 R; p- }7 S2 F; A: m; m
    - v3 M' ?0 N' N, y7 v" Y! v
            return (OK);
    ) ]4 l/ d# R5 G; R" b4 U! ?}& x) N: O( L' y3 J
    - E) b; V/ ^& k" S3 _
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    ; ]4 B# X5 {1 A  `8 B) m- i$ K{: s6 a+ K8 ^6 x# n& S8 h! {: k, S$ [( n
            FAST unsigned nWords;
    ) c1 i8 X" j( S# Y) h) k' S        FAST unsigned nWordsExtra;
    / y1 K$ K  Q$ |5 j        FAST DL_NODE* pNode;4 A" i  r5 D* }4 _
            FAST BLOCK_HDR* pHdr;+ s4 M1 w/ I. _- l0 ]7 w
            BLOCK_HDR* pNewHdr;) f2 T/ K* e5 J6 c. N
            BLOCK_HDR* origpHdr;
    2 `: ^$ H6 Y+ B9 d# T
      c% L- H3 h2 K  K. J& f# n# B! x        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */9 i0 C; V& T7 x: o( d
            {* Q: J1 t" l7 F1 e7 @$ W1 u/ n
                    return (NULL);
      Z% t8 @2 w. F, U' R        }5 ~( E+ T+ ^6 K
    9 b' Q/ o" c( q
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;7 @7 o. ^* p7 W# D6 _8 J2 Y
    + S; k& O! ]4 J0 o
            if((nWords<<1) < nBytes)% T3 s, Z( g. W4 o
            {
    % j; k: T$ P* `1 L5 Y$ v; J                /* TODO suspend the task */
    3 x2 Q& `& T1 N5 N0 F8 y* |                return (NULL);* T+ T( R/ k# O6 c( ^
            }
    ; \& _- M3 T2 E5 s4 j; U, @" E" c7 ~9 j1 Z! c2 p5 T' e
            if(nWords < partId->minBlockWords)* y3 H, r+ j$ s) L# }' }. I, J
            {
    $ t' [2 C0 W0 I7 L" K* w: S                nWords = partId->minBlockWords;
    + Q3 \0 Z7 y0 t, V* R5 m6 E        }* z( [: {- U- w# r' R
    / W5 }0 S4 p7 J
            /* TODO task the semaphore hear */
    " d4 t7 y$ \# J: M        semTake(partId->semPartId, WAIT_FOREVER);) U  p" U& _5 x4 d( V" O
            pNode = DLL_FIRST(&partId->freeList);/ K% a: b% x0 {" h/ n% o7 d
            nWordsExtra = nWords + align/2; /* why? */
    - p% o4 Y7 ~$ T, b: _% Q: ]  @  I- f2 X/ o( }3 a! s
            for(;;). v' f* D3 a, j' L3 v3 H5 i! m
            {4 _4 |7 \- q3 ~, _+ n3 X) ]! f
                    while(NULL != pNode)" m1 |0 e; _) B0 V/ u) z* M5 X
                    {
    0 _# r6 t# f1 S' c- q( M5 J- x& e                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||0 \' n+ n# D1 |; {% Z( e, u6 C
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && ; D! I- d# a2 C; n6 b) i$ l6 _
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    1 M, o0 ?" c8 _& Q% v; u                        {$ T: X& Z  Y, r" ^, O" t) k$ o( [
                                    break;2 A+ b9 \4 k$ b3 o1 k
                            }
    % e3 y. {" K  m4 C; l9 Q
    & f/ d) i% N8 Z6 h                        pNode = DLL_NEXT(pNode);
    4 I  z- {2 d; W$ Y                }
    & P7 d* K' c7 ^* a, [( P: \# Z6 M7 l
                    if(NULL == pNode)  c3 b7 W2 V- \8 Q/ ^
                    {9 S5 [9 y, H2 x
                            /*TODO give the semaphore */
    " C) T+ G4 ~6 G, b  Q5 ]& }- n' z+ @                        semGive(partId->semPartId);- V' S' {3 U; c3 N- Y4 C# G' @
                            return NULL;; F5 G' W4 V" j+ ^7 J
                    }1 ^" V, G, B: A% J8 f5 Y2 {
    ' y% A% p" Y6 `: w0 ~
                    pHdr = NODE_TO_HDR(pNode);# @9 E9 q4 _9 c6 o6 B
                    origpHdr = pHdr;% I! e5 ~, \) `
    9 e2 F  N* U* B9 X6 v' Q
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    8 K9 a: G, p: ?  @; a. y                if(NULL != pNewHdr)6 r' ]& O" K& ]; M2 O8 ]5 h
                    {
    : @% t0 U/ e' f. H                        pHdr = pNewHdr;% I* p/ u2 E( K
                            break;- y+ J9 q7 Z2 _8 X+ {9 a4 z
                    }
    1 U9 i) h) q4 ?# s( ~
    3 {& T  F& G, d5 F5 P% U                pNode = DLL_NEXT(pNode);8 K3 d# M5 }( ^: J& l
            }
    ; T0 z7 f( c5 x
    , `( U! T& s" [/ p        pHdr->free = FALSE;
    ; ]: b8 V/ A. _$ s- m        partId->allBlocksAlloc++;
    ) V; N8 m5 l  `; S+ s3 D- u9 b2 G        partId->allWordsAlloc += pHdr->nWords;
    * A8 _8 r7 l* D5 X* O& L- n+ o, C        partId->curBlocksAlloc++;* y/ r) Q! s' Y7 k  G  b
            partId->curWordsAlloc += pHdr->nWords;
    1 B( |0 P- z' w! S) Y
    & K- r' c' O9 L7 r' k9 V        /*TODO give the  semaphore hear */# ~, z  x* Y% v: Y# n1 M; C
            semGive(partId->semPartId);
    / \9 f& j/ \  ^0 H" J( d        return (HDR_TO_BLOCK(pHdr));
    2 K* h' B" U7 P: I3 {. F* ^       
    : d/ T! l8 i- ?' B}
    + Z5 j9 X* l# y. E2 h+ Z3 u- |7 {5 Q5 t
    - r. _& ]4 T( w6 E8 s* Z! n& Tvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)& G7 {% v! c. y1 P
    {
    3 U5 J3 |" `! ?$ F* H! f* I        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    " Z% [# S" {/ ]% C- I}1 l$ A, n% M$ U) o5 U& x# E

    % a% f$ c9 ]* G1 ^1 N3 @STATUS memPartFree(PART_ID partId, char* pBlock)5 A" ^* }" w6 n6 f+ ~- ~- R# |
    {
    * H" S( W: b! }  r3 z- B& `        FAST BLOCK_HDR *pHdr;
    3 H/ V1 C4 I2 i; p# n. G3 E    FAST unsigned   nWords;
    $ y: z' Q, B& c0 o# _- J* T# e    FAST BLOCK_HDR *pNextHdr;
    9 s' ?$ \5 m; c7 V6 ]
    + c* y+ R% J/ p* d  a. `% K; y9 \        if(!IS_CLASS(partId, memPartClassId)); L# f, ]! w# D* t( X' H/ S
            {
    9 G1 _( x0 f* f                return (ERROR);# l' Y% @0 I0 h% Q6 p+ x
            }* D; f6 o8 n0 h: G, S

    : C7 u1 j, }9 R2 X# r" t        if(NULL == pBlock)6 g( ~8 e3 ]( [/ Z  L
            {
    7 }4 w1 L: F$ C: \- C                return (OK);
    , `5 E0 `! i" d- }" K0 b# q        }
    , w! V9 W+ l: H4 P  G. m# a3 k6 Y  U* l- Y) T% R$ a# Q( q
            pHdr =  BLOCK_TO_HDR(pBlock);* j3 E& o- h' Z4 A" _

    * i, Y, u% E4 k2 `        semTake(partId->semPartId, WAIT_FOREVER);* z* N1 d% ^/ z' H) z( W/ m

    + c1 `! [( w5 {; U% q$ }; A        if((partId->options & MEM_BLOCK_CHECK)3 a# B8 V3 c- i( M4 K4 E8 \
                    && !memPartBlockIsValid(partId, pHdr, FALSE))
    + x; `6 f- R" Y        {
    " C' ~1 }- O+ g, b, p/ q& e                semGive(partId->semPartId);9 E3 R9 j/ u- I
                    return (ERROR);
    . H# S( j3 Z2 X        }
    - Y8 m+ G1 G+ O0 A+ n; P! ^% I: l5 V7 u& L) D" M% f6 Z
            nWords = pHdr->nWords;  P, X: i5 t) \4 }# L  y: v: J' U
            if(PREV_HDR(pHdr)->free)
    ; D  w  T1 V6 @9 Y6 S        {/* the prev hdr is free and than coalesce with it */
    3 k, p4 k: e7 W                pHdr->free = FALSE;
      b6 V4 R' O8 v+ V& `3 C6 G- Y- ^                pHdr = PREV_HDR(pHdr);
    " q/ }0 n4 r3 `8 ?1 n: E5 j                pHdr->nWords += nWords;
    ( j! U6 t1 G) n* s: S0 X        }& J4 a$ J4 C; J0 R3 E
            else
    + P1 u8 r9 `5 e' Y' [$ N        {
    6 f9 j8 q* V" Z( E                pHdr->free = TRUE;, s7 y) l1 Y* v& e8 b) F
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));+ h: z% G' S6 }! t7 W5 O
            }; h3 u9 q/ ^$ w0 \% [; J+ j
    2 M7 _& {5 d- c. E4 [
            /* check to coalesce with the next */2 |) F+ n+ z$ c) c* ?
            pNextHdr = NEXT_HDR(pHdr);
    5 \( u/ x4 h' R* u& z        if(pNextHdr->free)
    $ g7 I/ T6 v% G. d        {/ j' o7 ?: O& S6 u/ l1 W  V$ L+ w
                    pHdr->nWords += pNextHdr->nWords;
    1 ^2 H. x7 {3 z                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));/ k2 t* g4 \# i/ U& O/ j/ J4 J
            }
    * i( t/ l4 R. I+ h* b( t
    : s6 L, ?. t( w        /* cannot use pNextHdr->prevHdr=pHdr hear */
    + I+ i% P1 K2 r        NEXT_HDR(pHdr)->prevHdr = pHdr;
    : c' {" d; ]" B/ t9 O1 T" Z$ A  G* _# ]1 C5 T- ?- |* p+ F5 o
            partId->curBlocksAlloc--;0 `7 z+ j3 t8 y: e$ D8 O
            partId->curWordsAlloc -= nWords;% [" X1 A# B- I' }+ S
    ' d( M/ g' x6 _1 T& Q+ m- A6 O' g
            /* TODO give sem hear */
    1 ^( Q- c  ^- ^. T/ L4 S        semGive(partId->semPartId);" M9 E  v4 ^4 |* e1 l8 l
           
    2 U- l" _0 z' x% ]: H        return (OK);! f+ a4 Q% q5 }. ]* a/ Z4 \+ c( q
    }$ [9 g! g9 ?! y! p

    . E2 a" q; w2 R1 z' kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)7 f0 _2 W& K7 X4 Z5 F: O
    {
    9 C+ C4 y+ q* W5 M4 T2 p" k) J        BOOL valid;1 e' P: r# ^" P

      E2 {/ S$ e9 j. y; \* H        TASK_LOCK();
    7 }! K/ Z! T- K' c0 {6 z6 V+ K        semGive(partId->semPartId);* D$ L+ {: D% M- R8 h. J
           
      Q1 w  t3 w8 d! ~        valid = MEM_ALIGNED(pHdr)8 d' x! U0 `' Q$ @7 q
            && MEM_ALIGNED(pHdr->nWords*2)" V4 s* W  u1 a5 L1 D
            && (pHdr->nWords < partId->totalWords)
    ) k0 t( D2 V7 y- u+ I        && (pHdr->free == isFree)
    ! A! Y# f2 U: S- h- X* K        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    * K: N( b" d, M/ R3 R        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));6 E: `' v4 E7 B3 Y2 `6 o. T
           
    ) {5 i$ n' s& R; d        semTake(partId->semPartId, WAIT_FOREVER);6 p( g) k) Q% M0 ]$ H2 [7 P
            TASK_UNLOCK();
    . x6 |/ }3 P  A5 e" I+ B9 y
    - B& S/ H* J" }/ [: b! D        return valid;
    ' u. o! e" _$ x. @}$ }5 ~: Y2 w' }' K4 o: i4 L0 E0 @$ x( b

    , _$ g$ s, p! i. M! @static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    : w' F% K2 A$ ?- _" g* ^5 M' y        , FAST BLOCK_HDR* pHdr
    : @) v2 V6 x$ j+ f3 `. t) ^        , FAST unsigned nWords4 [1 g0 }( V: q
            , unsigned minWords
    ' \. a& t' ?' K6 r1 k        , unsigned align)5 I' W1 F& ?1 h& Q1 h1 W1 ]" D5 t
    {1 G, h# q" R2 C& l3 w
            FAST BLOCK_HDR *pNewHdr;
    1 {4 R2 j7 i  \! E' _7 y    FAST BLOCK_HDR *pNextHdr;
    : B6 U. D% X4 r7 K1 `/ v    FAST char *endOfBlock;
    6 X2 ^# H: f: |! y; f$ d    FAST char *pNewBlock;5 [& Z, S( e! ?; g2 {; O, W0 S
        int blockSize;
    - K/ f% J# {9 u( v5 Q5 _) g
    4 Q2 v* g5 K( i        endOfBlock = (char*)pHdr + (pHdr->nWords*2);+ K/ R& v9 v9 z6 H/ f& v! Q+ ?
    ' X% l# ^; _) t& e/ h- ~
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    ' F. e' @; V2 f  ?; P9 s$ ~
    9 `9 u" Q9 \( }  x% Z+ H: q        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    4 N5 h4 F8 U! T$ o! J
    5 y; N0 q; l8 C4 z        pNewHdr = BLOCK_TO_HDR(pNewBlock);  w7 R! N" z1 O4 m
    + o, [* P" }' x  x2 C; c+ u
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    # w. D+ ?; W5 _# m& p' q. B/ D, g" c. Q' d- D8 l1 c4 p; x
            if(blockSize < minWords)
    ; b! k# a& T# D& j        {
    8 O/ d7 d/ w! m& M                if(pNewHdr == pHdr)5 f+ S+ q1 ^! u
                    {" Z& u, B& S# o+ X9 U$ W: V
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));6 Z6 d6 r2 T! v/ S& m
                    }
    3 }) s  D6 y# ]+ l1 s  d. t                else( O( u7 D4 H' L3 A  ]9 Q1 j6 j* I
                    {
    / \4 g8 r: ]% f4 l                        return NULL;
    7 E2 O  G: L) {7 T; F                }, {, X8 M# K9 r" m* H+ v
            }
    5 ~0 e8 v+ s  e' I3 f        else" e: o. k0 H( y  p( m* a: y$ e
            {        /* recaculate pHdr */
    + D0 x2 S- D' ~# Q3 w+ m( |8 ~                pNewHdr->prevHdr = pHdr;
    4 `1 a6 C  T! G7 y( X# n' h( \9 E                pHdr->nWords = blockSize;
    & w2 V3 T0 v) {- }+ {0 n        }4 g' J& g( C% ^+ K

    * r6 v2 B+ g$ \" @( l) v+ @/ V; H        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))6 j( d7 f& _, V4 d4 K! ~8 _, p
            {
    % N! X5 K* V1 _, r: M                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;9 @4 G2 B4 t, |( x! Q3 _" n
                    pNewHdr->free = TRUE;$ A/ `# {5 D; g8 V" ~1 c* _1 y, O
    + _4 }5 x8 R5 L% o- I! G% O; f3 ~/ }
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;1 W+ R2 r8 l$ q" y  S" L
            }
      S* A! e% i7 I0 i        else
    8 X7 o. V' @9 ~. ~7 l6 u        {/* space left is enough to be a fragment on the free list then */
    % W, C/ d7 k( r$ R8 k                pNewHdr->nWords = nWords;. \* ~0 F( Y- w$ u1 L4 U0 D" G9 B
                    pNewHdr->free = TRUE;
    / b. ^/ ]3 ?0 K; i$ e$ O9 ?$ H1 d7 G0 e) K. u, ~! `
                    pNextHdr = NEXT_HDR(pNewHdr);
    0 q' Q6 m* o* a- _7 ]9 W$ X6 j                /* words 包括BlockHdr */
    ; _& U. g& _3 L5 }3 A& o8 I                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 H* o3 |9 e5 _/ c! G- i1 ]. ~& ]
                    pNextHdr->prevHdr = pNewHdr;  d  L! }, L  ]
                    pNextHdr->free = TRUE;
    ' f8 e( o9 T' N, D+ Z/ K2 s
    & j) l3 n2 U" P8 d. w. y" X                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));/ W! @5 X4 C4 C' G' D

    2 _. |8 o1 y# u+ v0 E: O+ c                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;6 N. b7 K5 n# U6 }9 j
            }
    1 ~6 X# {( w' O( u% M5 C
    " C/ ^5 B# |% Y8 G4 E2 c        return (pNewHdr);$ H: \1 s1 m  M" B
    }
    ! C+ \+ s' s" S9 d, _
    5 a6 g4 a: b! I" Fstatic void memPartSemInit(PART_ID partId). u( S/ k& B4 ]0 I! v
    {
    / K/ o* J! O3 G/ e4 p/ W        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    % g1 C& x: r* z" r5 q% }' w/ O" c/ a* j" b
            partId->semPartId = &semMemSysPartition;* H, U0 R' w8 U) |6 }9 z
    }
    6 f) k: B6 ?' f) Z( R
    , j/ v# k0 x! {void* malloc(unsigned bytes)$ W; C) W. P- P5 V4 }/ V! G
    {
    1 v! ]' ^% w7 c5 t0 R; i) w        return memPartAlloc(memSysPartId, bytes);
    " i5 e3 F% {/ f6 c9 I}
    ! J6 n: q2 C  r  \* k' y3 T: E' |& N2 e
    void free(void* p), W4 d0 W3 w* V( ]( s6 y
    {1 I8 l9 u; t& _0 s4 ^# t+ |' y
            memPartFree(memSysPartId, (char*)p);8 F: d# G: j' X' y
    }
    , [& @- u& \$ ~8 Q7 j( Y1 M8 _# N9 _
    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-15 06:18 , Processed in 0.644036 second(s), 51 queries .

    回顶部