QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2880|回复: 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++下的版本,更方便调试。有需要请留言9 ^* [& ~0 T( C/ X% \; z2 b

    * n4 ~3 Z5 X0 o( A$ i- g) ?
    6 {4 f% q+ ?) N
      \+ F2 B- R0 R1 \7 a  Y *\file
    % }2 l9 x$ B# i- g: q6 ]2 x *\brief                / f4 b; h! m2 T! p
    *\details       
    - g4 \5 D. K( f$ W *# w- }" ~1 P4 |  b5 b
    *\author        Janson9 b# u9 ?# @* n( ~- n4 z: l) ]6 `/ D
    *\version        4 k2 O  f& e2 q+ B% ?: E
    *\date                04Jan127 n6 |" A% T" v& G
    *- C$ ~: D8 T8 \* ^$ R4 z
    *\warning        7 u! E1 X6 J+ h
    *
    : K3 J' w+ T5 m8 t0 C& {$ | *\history \arg        30Jan12, Janson, Create the file# R- P0 ]7 q9 L6 z, b9 z
    *        modify from VxWorks source5 y8 P7 A/ l) M. y5 d+ W
    *  Legal Declaration: it is for studying VxWorks only.
    # H2 `; x8 y8 i, R */
    " b1 Y; `) a3 b+ W#include "includes.h"
    $ `  Y$ a1 b9 T
    : @$ o# y& @* N" U$ `' W) r9 d, B/* The memParLib.h file is hear:0 `, K- e& ~  S9 d
    https://code.google.com/p/vxwork ... rivate/memPartLib.h+ o: C8 N  N0 _6 U
    */
    3 I: f3 W- w( L1 F* q
    8 l. {0 F4 F/ Z7 F/* optional check for bad blocks */
    ) y9 s4 m9 T4 r/ E1 v7 O' r& h$ [; k9 F/ S- {
    #define MEM_BLOCK_CHECK                        0x10
    8 [$ h4 y( W4 c% b6 q' D" Z* C7 |( n
    /* response to errors when allocating memory */* L7 V' Q' J$ ?/ ]

      v0 \, Q5 t/ d- C" p% n) A5 j#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    / S0 j+ B; N1 c2 b# x#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    ) x* E( i! q4 A# j( V7 @6 q4 s9 b* @# g+ W2 \8 m0 v8 n2 P
    /* response to errors when freeing memory */. q* _- ]$ M  A, G

    ) k% S+ c/ F3 F#define MEM_BLOCK_ERROR_LOG_FLAG        0x80+ _! I. n4 J7 C# w- |& R
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1005 b, o4 W5 f' o3 x

    ' P$ p$ }$ [: @0 f6 l$ ?/ h4 i4 C#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    & g" R0 Q2 t9 V6 `6 X+ U/ ?#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    ' f- h4 X% i8 H& c1 Q8 g* C2 C! ^/ a0 t5 j2 q# Q
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    8 j9 y( g. a1 {1 W% L#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    # \/ b, m5 r# D) o4 D                                                sizeof(BLOCK_HDR)))
    # c. z8 p2 ^* H% ]$ N# u% i+ h! q7 I/ m: u
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    % h% |' T( \" ^: `#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \  S8 q# f) z- d! p0 N
                                                    OFFSET (FREE_BLOCK, node)))7 v6 g: Y: e/ T
    ' B9 N3 G1 `1 y' j
    static BOOL memPartLibInstalled = FALSE;. j: k! K8 l4 ~/ l
    ! {  r5 d" ?5 o# j% X1 w7 `/ A
    static OBJ_CLASS memPartClass;
    0 |1 _" L; b) ?; RCLASS_ID memPartClassId = &memPartClass;
    4 c( f7 C4 h$ J: `- ?& p) h3 N9 o- z/ X* K1 N* D
    static PARTITION memSysPartition;3 Z; o8 F" Q1 g, L* U* `/ z
    PART_ID memSysPartId = &memSysPartition;% H& v. @" q; w5 w3 |1 G7 r& w7 m" p0 s
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    4 W% M' \9 s* O9 G1 X
    7 q% U5 T! }* }static SEMAPHORE semMemSysPartition;
    , w) v0 `* n2 ]. _& ]  v, w; R2 a! }9 H
    static void memPartSemInit(PART_ID partId);
    ; L& o% g: ?+ w$ u; j8 L$ |" l4 `& j" s$ r
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;8 ?0 z+ h  b: _4 a

    ( B- @. u& N; x3 d3 \unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;% R$ F3 m- ], u; N" E% x
    0 T# q, ~* s- e2 p0 e* d
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);  L, z: `' t0 n! @1 r6 |
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: X1 {* O" F, q$ o/ J
            , FAST BLOCK_HDR* pHdr# s) C8 t+ t8 T9 \# i7 k+ T
            , FAST unsigned nWords
    , h* Z( ?& }0 h( }+ I( t        , unsigned minWords
    # E: G* b2 N$ u5 p  ~+ R        , unsigned align);) d* {4 Y0 A, d2 O% p  B& M
    , ^! w" \2 W  @. S. d' u9 b
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    . R, o. z3 D8 l. U: c: P' t3 k
    : W% ^3 q" w7 I& x& i0 m+ zSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    ' W0 x+ U( m5 E{
    6 J" a8 w  Y% J& k9 W        if((!memPartLibInstalled) && - |2 L7 m8 a: D" S# D7 I
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)8 J% W3 z  l% h0 ~; J2 ?3 C/ R
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))1 J0 H7 x9 K: n/ e2 C' A/ H) {
            {+ r3 P+ R& [& x' p
                    memPartInit(&memSysPartition, pPool, poolSize);) S3 F1 w( T& f' d7 ~5 q
                    memPartLibInstalled = TRUE;
    & f0 V- h' I2 N5 b& N2 ]/ t$ X        }3 O$ ]  h# W# t$ f  r
    ) L  F9 c+ m! O: |2 \
            return ((memPartLibInstalled)? OK : ERROR);9 Q3 E" y) n( H" S- N8 f* `" G
    }
    $ ~7 m! t- ^. p  g
    7 ?& r+ t) Y, A- d7 UPART_ID memPartCreate(char* pPool, unsigned poolSize)  y2 e+ L4 M! _1 {8 E* p3 J
    {
    1 q; k7 L  n" O  s        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    $ D! d3 Z7 g% L2 u/ J! f, K8 k. H2 q- z1 a2 H3 [
            if(NULL != pPart)$ L! v9 U0 A$ L/ K" g( H) a
            {1 }7 ^' R- {! C. O
                    memPartInit(pPart, pPool, poolSize);
      ?" J, S/ b, ^/ H+ I( @6 M        }5 X$ P4 X2 X4 @1 N' g

    : r3 P! Z' y" o2 N2 L. k; K  V        return pPart;
    / D& m; v2 z- h2 h- M( n}
    & f9 Z8 x4 i, v. J8 N* z- e5 y, y' z* T/ Y" g- z
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    / Z& Q7 r( p" P0 W; v& {{
    1 H. m; m4 r: m        memset((void*)partId, 0, sizeof(*partId));1 }$ I$ v0 j. X

    2 j/ E# j2 Y5 K7 A1 A$ U        partId->options = memPartDefaultOption;
    . D% a5 ?( `5 ^: H3 p/ C        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    1 U, a4 x, [3 s% k0 Y+ ]
    : h& d6 u$ t" `4 j2 m8 b! R        (* memPartSemInitRtn) (partId);
    % O. R- E" }; J% p) @& R. |+ C7 f        5 z9 `4 @8 h7 Q' t6 |" l) B
            dllInit(&partId->freeList);
    , f2 v- n5 K& r( A$ J3 C       
    + P5 i5 ^  g. Q- @3 H& L; N        objCoreInit(&partId->objCore, memPartClassId);' [$ I9 E4 o! T1 T$ A0 m$ |. o6 S3 r
            ' O/ r* f9 {1 k' B0 s
            memPartAddToPool(partId, pPool, poolSize);: ^& |; r7 a3 _  e
    }! S- X: F' q3 g

    + U/ t5 Y) W' BSTATUS memPartDestroy(PART_ID partId)+ M2 p: [, M! s0 r/ M( s9 J* s6 g; _# ^
    {' a/ g; P7 @/ i7 C- z. l2 `) a8 n
            return (ERROR);
    3 |$ L# e( q2 \1 l9 F}
    / e) d) _& l6 q$ \' K8 E5 R. S' Y% _2 \4 C; y
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)/ C1 x4 h0 t5 v3 J
    {9 }3 {+ @% B+ V1 s
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    4 s; A5 Q( |( E& K  \0 {! @/ j}6 f9 q, |  F: n9 F- r

    & y6 Y0 {9 }5 u
    2 }( b& k. i! [* b! |8 B- }static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)3 F/ t; u  u: |7 B& {' g; {
    {
    0 g# s: w) K( m( j2 B) O# L3 B  l        BLOCK_HDR* pHdrStart;/ q) y& X# ^$ H6 {% d0 q. E
            BLOCK_HDR* pHdrMid;; N" a3 @& ]$ \
            BLOCK_HDR* pHdrEnd;
    & H, J: j" f' |6 r7 S, Z        char* tmp;1 [* G' _  k6 K. ~8 O
            int reducePool;& F+ _' h& g! b. x& S& z$ @6 T

    ; O* t0 z2 C0 A4 D8 B2 F        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */& x$ e8 ]" G. W: R0 V$ X" i
            {
    # _' A+ v. v" j/ V# d                return (ERROR);
    2 k. S; y# V. n0 z# Y        }9 p0 d) G, [) }% Y, }

    ' k! j) c7 R4 E7 B: |+ ?        tmp = (char*) MEM_ROUND_UP(pPool);8 K2 }0 j9 _3 H( n
            reducePool = tmp - pPool;7 C! |* l& s1 L3 M3 @9 }$ `

    . H* [+ Y" E; }0 I        /* adjust the lenght */1 Q, q6 f/ J6 a  K4 i
            if(poolSize >= reducePool)2 U7 ]0 c/ |- |# y- ]1 p8 a
            {
    0 C* s4 N( f. i4 G: J. A                poolSize -= reducePool;& ~  B. Y) u9 ~+ w! D
            }  ^' F: f, m9 q% h3 h6 \7 v7 [
            else
    $ p0 ~" ]; E1 b- Q# R        {
    $ h4 H' Z  |( M: [. p7 V" u  N                poolSize = 0;
    ; u0 K3 M- L* K; ]  U1 p        }, c& f' S7 @5 f' j
            pPool = tmp;4 N& L2 Y9 n3 k) q& B& ?3 [) T! K
            " k" O% b8 s5 |/ M+ i
            poolSize = MEM_ROUND_DOWN(poolSize);+ E; N' X6 ^$ g- j
            : s$ r; [8 I$ r+ H. |' h5 f
            /* at least one valid free block and three header blocks */" Q1 I+ M9 q' }$ U
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    ( b% }1 {" ]  l5 D* b/ M        {2 z/ E1 f" }$ u1 F1 C! g7 G
                    return (ERROR);
    0 f1 z$ X0 A: [4 E, [4 [6 G        }
    $ }* m! Y* z- x' [4 T. O
    4 a# |& m6 o! P3 @# o5 X6 h        /* initialize three blocks */
    $ H5 R7 S  C. M, l8 ?6 q. l$ a        pHdrStart = (BLOCK_HDR*)pPool;
    8 T/ {& C) S% y. T        pHdrStart->prevHdr = NULL;
    , q* B8 p/ i, W  b# V# W        pHdrStart->free = FALSE;                /* never in use */
    : x3 l+ X0 a3 H  I8 B5 h        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;
    1 C& w( s) x& f% H/ h
    3 F) d9 j' i+ e* a) ]        pHdrMid = NEXT_HDR(pHdrStart);
    1 ~4 @& ]% z! J: g, H- g        pHdrMid->prevHdr = pHdrStart;1 L. n& }/ I: H# `
            pHdrMid->free = TRUE;                        /* the main block */
    ' M* ~$ {5 D9 d: x        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    7 h6 i! o# I! w& z$ }$ k; K, G  m
    ) B: l- J  g' A$ v        pHdrEnd = NEXT_HDR(pHdrMid);
    8 D8 ?& R# h6 n# G9 `  |. S* R+ s% ^        pHdrEnd->prevHdr = pHdrMid;1 E; ^) U& T$ K- R# ?
            pHdrEnd->free = FALSE;9 O1 u; p7 e1 Y
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    ( `  B7 g% C* `8 C7 q# M, `5 [( V' j# ^% {
            /* TODO take sem hear */
      D: u5 ]6 n3 {* A        semTake(partId->semPartId, WAIT_FOREVER);8 @8 h1 K) O8 }' A, u, M
            / {; k2 ~- Q1 v: N6 T
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));/ R; s" r: U4 ?! i
            partId->totalWords += (poolSize >> 1);
    & m+ ?  O1 P2 z1 k: f; S9 Y0 }* o/ y  K7 }9 O- {6 @
            /* TODO give sem hear */
    * v+ f5 T+ N2 h        semGive(partId->semPartId);( O6 j+ a6 A( m" G$ c% I% A9 N

    9 D8 O+ J& I# J: \  c# G' o
    ( K: Z* ~, A% S) H6 K5 X        return (OK);
    . S1 t# e5 R, ?}
    7 _0 s0 o; v  A% R1 z
    3 y! K1 y, w, f" ]' a9 g, Avoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    + f' I! A9 d/ L9 v# T{
    ' L+ e" n8 l7 P2 B2 [+ B  v& y        FAST unsigned nWords;- r5 C0 V2 a5 Y7 a6 l  z
            FAST unsigned nWordsExtra;
    6 [6 C2 `) z7 e7 O+ r1 Z        FAST DL_NODE* pNode;
    4 _' C; T' v' k1 I- f        FAST BLOCK_HDR* pHdr;
    $ S& S+ ^) X  d2 x        BLOCK_HDR* pNewHdr;
      \( x/ g. I  h: L8 F. H, w- H        BLOCK_HDR* origpHdr;; N, Z  v9 t5 Y

    7 H: h7 Q4 }" ?& |* j        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ) L) a$ ]8 K- b! K" ~7 ]! {        {
    ' |7 R+ q6 }9 U# ?. Y% Y& \2 c/ R                return (NULL);
    - C1 q  P% b( B9 c/ b        }# b8 _% E8 g" B+ d& t/ m) _

    8 h! C0 M* r) b5 l6 b# {! k        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    9 d0 w- O1 e# _( _) j: T9 H' f: k' \1 w% L1 W
            if((nWords<<1) < nBytes)
    . P( v; M  }+ O3 d, |( w( I7 {        {
    1 B) R! r; Z8 z& G! H, ]# k. K                /* TODO suspend the task */+ j$ g  w0 L. I
                    return (NULL);
    8 Y0 p) D6 x1 k        }2 H6 H( f3 c0 T
    + F2 u1 j( ?5 {1 g. ^0 m; _  `1 F2 _
            if(nWords < partId->minBlockWords). S6 a' I4 x8 [) [
            {& z9 Q% {$ ?  X2 l; {3 H
                    nWords = partId->minBlockWords;! s6 B$ U3 }. G/ G
            }
    6 }& D2 {1 w0 L' y+ o9 |- p* S: ~6 A$ M
            /* TODO task the semaphore hear */
    ; M3 d% j1 H% j  g  o        semTake(partId->semPartId, WAIT_FOREVER);
    2 u4 }0 H( ?9 j+ r3 c: l        pNode = DLL_FIRST(&partId->freeList);! _- T% }# v7 C" Q
            nWordsExtra = nWords + align/2; /* why? */8 x$ E$ Z0 N. j
    ' B  B5 M% k9 k4 \. N
            for(;;)% L$ _, S- k" {: f
            {
    ; {3 N- Z# r1 ?: N0 Y+ S                while(NULL != pNode)3 P+ c, d# b2 _3 \
                    {
    2 @1 T( z; X% B% N) d% h9 I                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||: g! _! s) Z+ t( F5 o
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    * w8 T5 A9 A+ f  |$ J  `                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))  ^+ }7 W9 F8 q7 Z0 Z8 I4 b
                            {7 G; k1 D" d4 l6 p; z. m* q: J
                                    break;
    5 @- A: ]# X$ B5 f' |' Y  o                        }
    2 V3 f  B! X  |# g' G) E+ O, Y5 e3 w; M/ @) F$ t; ^7 S
                            pNode = DLL_NEXT(pNode);
    0 o. D5 c; I* M, ^4 ?                }( q  {: x8 |5 o1 |) O; d, G

    - k' N0 G7 _* k: `+ E                if(NULL == pNode)8 S! b. P: k! t$ [, ^
                    {
    - z9 L1 f3 A; F                        /*TODO give the semaphore */
    2 ?0 \' |8 v. B2 a" ^2 ?6 A% f' e4 M                        semGive(partId->semPartId);
    3 @6 O$ K  G% Z3 p1 d- v" k6 R5 U8 H                        return NULL;
    5 @' D! X) C9 u7 W; c* a" t4 {                }( x+ S9 d3 f$ T9 ], ?! z; r" _
    ! x, C5 l* A' M
                    pHdr = NODE_TO_HDR(pNode);2 y; _: Y: B0 Q
                    origpHdr = pHdr;- |! v, l* R6 z; h5 G/ d$ Y& u
    0 ]- W6 e) v8 H1 }+ O
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);" k# _/ \1 `+ b" x) Z! N
                    if(NULL != pNewHdr)& e7 A! ]! C4 ?' ~
                    {( l& p+ F/ W8 ~
                            pHdr = pNewHdr;& ?' v8 c6 P2 O9 S$ Y  m# ^) R/ t
                            break;
    % g* {+ z- [% ^3 X                }
    0 c4 o( H" c6 s- ?0 J. U' u) l5 T1 a5 [& t2 `' z, ^. t% E
                    pNode = DLL_NEXT(pNode);  g! ^% t3 f! W+ X
            }
    7 M: X+ x( P# `  D0 K! C# M
    & V% w$ d3 d3 Q* q$ J# U! H5 |        pHdr->free = FALSE;: R$ H% I8 t8 _4 l; g3 A5 b# ]
            partId->allBlocksAlloc++;5 G% i+ s9 U; N% f
            partId->allWordsAlloc += pHdr->nWords;
    6 R* a. k7 \4 D' Q        partId->curBlocksAlloc++;
    0 F% h4 U& Q6 p  w        partId->curWordsAlloc += pHdr->nWords;9 r# M) f4 e- ?; Q( M

    " [( Y; W. a4 |1 c- A: ?' b        /*TODO give the  semaphore hear */7 K$ F; }" Y9 T  M/ u
            semGive(partId->semPartId);; f/ \% p) x% s- |& g5 ^
            return (HDR_TO_BLOCK(pHdr));  X) S) X1 J; G! m: ~; x  z! _
           
    1 ~0 c& ^+ D& E5 M$ e5 B}! R2 p4 L7 _* H* f5 `7 p

    , e; U; P! Y4 lvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    : T. Y) }1 L& k& K{
    8 q5 @0 [3 k9 z( j- Z! P        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);4 f/ |* C* s. n. f( J' j; _3 M9 R
    }
    , T1 v, r. w8 M. d2 g7 o  T# {
    STATUS memPartFree(PART_ID partId, char* pBlock)
    + b( A7 _# S  B/ M; K  k{
    - i) w7 u; B" [        FAST BLOCK_HDR *pHdr;; {  k" n# q6 K& v& t4 ^
        FAST unsigned   nWords;1 R% F2 }& A0 _8 H/ _( E" q
        FAST BLOCK_HDR *pNextHdr;
    + i+ g3 q' \( [3 o! X+ c/ _1 C
    3 e' e1 r2 d5 [  i, o; I* e7 Y        if(!IS_CLASS(partId, memPartClassId))
    # Q7 {; F6 q8 [4 J  w  q4 i6 m# m2 P        {' W# o, @: h+ q) J0 W) Y1 M
                    return (ERROR);2 }% i: Y3 a2 M  `) \5 {5 n
            }+ N1 a4 y- k5 r+ o8 n- d

    2 v6 L% ^( H0 d( q# C/ N# X9 Q  b        if(NULL == pBlock)
    + `0 j) @( ^5 p( J0 s6 Z# p$ h0 P0 q1 w        {; A4 [/ N  F/ Q4 e$ ~6 q( H
                    return (OK);! A# k% H; o5 R8 B5 R; ^
            }* L( \& H% c) h- Q

    ( J4 q( z1 ]9 r2 V$ \: l( v. x$ ]- r        pHdr =  BLOCK_TO_HDR(pBlock);( v+ X7 Q. M8 I) j! A4 ~. u
    " s7 I) N3 r* Z( I. H  J2 {
            semTake(partId->semPartId, WAIT_FOREVER);2 e  P: k; X0 f! @, ^: l1 L
    3 n! b# A8 Q. w- Q6 ]
            if((partId->options & MEM_BLOCK_CHECK)
    * k5 s4 X/ F4 b8 ]$ S+ [                && !memPartBlockIsValid(partId, pHdr, FALSE))1 G- {% M$ F3 f% s! t# {
            {
    ; @  I  v& l8 X                semGive(partId->semPartId);
    : X  D3 M9 \, c3 J7 H2 B# n                return (ERROR);
    4 Z6 S2 q7 j# J3 b        }' `# {3 ^3 f6 m, q* U

    ) C7 D6 A; C6 @8 L0 G        nWords = pHdr->nWords;
    ' N# E+ s3 d' Z# `3 }# f# u! b- M        if(PREV_HDR(pHdr)->free)9 m* [$ G5 w3 C( U
            {/* the prev hdr is free and than coalesce with it */. ]. a( ?# p% s3 V' z1 z6 s' R* N. I
                    pHdr->free = FALSE;
    . u: x9 H/ n; r8 f5 i! K/ q                pHdr = PREV_HDR(pHdr);
    - ?3 N  q  k! n* f  f3 t6 e                pHdr->nWords += nWords;+ K& i9 D/ k4 R: r5 u
            }$ }6 S/ @  A7 m% ~- l, u
            else
    ' o/ [/ U$ ]2 {; [/ {. i' ]* O        {- W7 x) B8 r" I* B
                    pHdr->free = TRUE;
    7 A$ u) o, H" u$ [4 `                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));- S3 k! T5 Z; Z
            }' T4 K+ u, i, \  w! g

    : T8 h0 C" K; j* r9 I* k        /* check to coalesce with the next */) s. l: u$ I" ^- @
            pNextHdr = NEXT_HDR(pHdr);+ C9 ]/ B% ~6 ~$ b, p+ [7 t  T  `
            if(pNextHdr->free)
    8 ~; |; l8 j/ }2 i        {) q5 {: c2 W2 i
                    pHdr->nWords += pNextHdr->nWords;  r2 d9 K4 e6 |
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    " S: @* H3 k2 g        }5 l( h0 p! J3 M' z+ w
    " F& M  z1 C- K2 l9 E
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    " w5 S- j( k- ^# c        NEXT_HDR(pHdr)->prevHdr = pHdr;. g/ N5 c+ Z! ?- H

    . l. T& v- E- m# f) n- j        partId->curBlocksAlloc--;6 @8 b! n  D8 P# E) u" o
            partId->curWordsAlloc -= nWords;( T1 m/ k: ^; @$ }7 H1 q
    7 L3 ]0 ]8 e5 u
            /* TODO give sem hear */
    6 ]5 B2 t- `% h6 z7 n        semGive(partId->semPartId);
    + |* |- V1 t4 Q" e       
    " e" x, ?, N) ~$ Z+ [        return (OK);7 x1 ]8 ~/ D9 S
    }
    $ M& y/ `4 Z' ^8 O! ]: [, \
    ) e: V9 E( [/ R( ?9 |/ y, f  ]. V7 b3 }. Lstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    ) W' ^4 j/ ^, D9 l# [7 R; J1 J# V1 A{
    1 C) H9 l$ w& t/ R        BOOL valid;
    # ~  j2 O5 U, W6 }: K) w. S7 \9 f5 G6 `# e
            TASK_LOCK();6 L# k# Q/ e- Y
            semGive(partId->semPartId);
    5 q# ]6 a) V' k+ m6 m  ^       
    - \* L7 Y3 H* Q4 C5 ~. g2 F1 j        valid = MEM_ALIGNED(pHdr)
    - m* G  g5 s; i# R( ~& f        && MEM_ALIGNED(pHdr->nWords*2)& g5 R3 M1 n$ `% s
            && (pHdr->nWords < partId->totalWords) 1 a9 e9 Y4 Q& Z" \
            && (pHdr->free == isFree)3 G$ I# ~/ l: s2 E' h5 N3 \( K$ r
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    1 ~8 v9 f0 Z8 S: Z7 u* t# s        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));0 H8 Z0 V: g' ~1 U! {- z) }
            ; R0 @- i: o. X( D% W
            semTake(partId->semPartId, WAIT_FOREVER);* J  h3 `4 w: `9 y. b
            TASK_UNLOCK();* \, ?! X, P7 u% j# K

    1 G( G2 |- E: v/ K5 _* Z* ^        return valid;9 p& _0 w* U$ G0 H+ ]6 W
    }+ {8 E' w  l# M5 F% W

    " \: N$ {9 x2 Q. @! H8 jstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    0 m$ X0 J4 _5 K$ T1 \        , FAST BLOCK_HDR* pHdr
    3 ^, @, \. C" K        , FAST unsigned nWords
    2 Y2 r  r5 l. n4 z( {" f( i        , unsigned minWords6 F! C" E+ X7 l( W- G; j
            , unsigned align)7 o: o. J% q' y( _. i. d
    {
    3 j% @, e4 F# k+ V( y  h        FAST BLOCK_HDR *pNewHdr;
    + x% e( ?$ f% J. D$ A    FAST BLOCK_HDR *pNextHdr;
      L0 F* [% Z3 J( [    FAST char *endOfBlock;
    - v1 }- k5 H( r- o2 n* a    FAST char *pNewBlock;
    $ s3 N5 R5 A3 I' N; o0 J& ]    int blockSize;
    - p/ ^" J3 Y( q- V5 U
    5 H6 n8 ]: g! j/ I) s* h* l* Q% ~2 A        endOfBlock = (char*)pHdr + (pHdr->nWords*2);3 Y4 J7 Q2 ~/ S
    1 W6 R0 A  A+ I6 c8 \1 r6 e/ l6 Z
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));. q9 j- E( q5 w$ l
    % M% I; g/ F2 C" u' H' ~
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));) F' H( S8 K& k( ^* S
    7 j1 h0 E2 X$ W, k9 k
            pNewHdr = BLOCK_TO_HDR(pNewBlock);
    5 Q$ ^6 R: ?; H/ J8 d3 }" q2 Q4 L: q) }  b
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;, @- Y" l* J* n! d  g

    7 Z: |5 M" m- K5 y        if(blockSize < minWords)+ L; Z& @/ m7 v
            {" g+ L! R4 M2 W
                    if(pNewHdr == pHdr)0 s2 [/ C0 \3 I
                    {
    - d; }( D" a' D9 F/ i                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));8 O7 W& ~3 z7 M5 S
                    }
      n" J, L- N: w, w7 w                else0 ^' S5 s# v# ?# h
                    {
    : Q9 y8 J8 \7 S                        return NULL;
    ( l" F4 |8 [' t% @7 N  L# L                }
    3 ?( u0 ]# p5 B; V* r8 h        }
    % r2 `. I: E9 y& Z2 D+ e# t8 J        else9 ]* [+ P3 k3 C' L" Q
            {        /* recaculate pHdr */: Y0 u+ n3 W6 ^1 T
                    pNewHdr->prevHdr = pHdr;* C6 V/ e% @) m
                    pHdr->nWords = blockSize;
    : D/ P* h# g2 p* _        }
    - E4 ]. m/ J$ b( I; t2 K- T
      R  l" j* ~1 P4 ]        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    5 s& Y( S' D2 @9 F/ z        {
      L' h. E. c5 S, \8 Y                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    0 g% b& U% G+ s                pNewHdr->free = TRUE;
    ) K3 S( v6 a1 f# q2 J+ b- @( ~. K
    & d) a8 o8 h3 H0 \$ B                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;. u; }1 p* e1 d* n/ Q& G# O
            }
    # ~" E% B, T6 ]1 i: m        else
    4 @6 O" C0 K0 c7 Z3 G& s6 ?! O        {/* space left is enough to be a fragment on the free list then */
    0 H. S8 f& S! ^* ?  A                pNewHdr->nWords = nWords;; L5 J0 g& v7 |, u
                    pNewHdr->free = TRUE;
    3 R& N4 z" ]8 A0 h4 P; @7 l! T& c
                    pNextHdr = NEXT_HDR(pNewHdr);1 a/ M- {8 \- J
                    /* words 包括BlockHdr */& @5 k2 s# X" I" g( X' c+ O0 A1 d3 t
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    ; X4 q( Q" H, d2 y1 _, Y                pNextHdr->prevHdr = pNewHdr;
    6 y: I" I2 W, t8 b                pNextHdr->free = TRUE;
    4 D. N) H' r) W% v, {6 ]9 ]
    " N5 b4 R% j/ ^$ b                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ' L4 V6 a9 u/ ~7 K5 s" ]2 w' t: ?8 O; y( s8 H5 h% n
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;. ]; O$ V- d4 Y9 L* C$ K
            }) |+ g4 j7 C$ Q* v8 l
    9 B, N, \0 s. |! m/ y" R( E) V, p
            return (pNewHdr);' T' u4 b0 U& e3 x: p
    }+ }% M6 u! H3 l( H' f  F* r
    5 U$ P7 q6 `/ `- T, O5 [9 D( B, Q
    static void memPartSemInit(PART_ID partId)
    , Y3 V: E9 f! V6 {3 U; @7 X) S{/ v. Y1 z: N# ^. |9 p4 {9 J6 V; t
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);1 E9 r- E& z9 L

    / d3 v- I, J7 Y0 W3 Q' \        partId->semPartId = &semMemSysPartition;
    5 A/ z6 _1 W' V2 {( e$ g- Y}
    " s; d  L: K' o" Y8 f$ q! }- d. o' {, [* {! J
    void* malloc(unsigned bytes)/ l3 {5 W% m! T/ a
    {
      i, _8 e& [/ b        return memPartAlloc(memSysPartId, bytes);5 v& E! D, ^- X/ v/ L. s/ U, R- {8 C
    }2 M* i+ f6 `7 e+ x) n" R5 Y

    4 n* }' @/ z8 r: R  X- S" qvoid free(void* p)
    . W- n0 b* v* d! t0 h{+ h1 X# e& K0 @' O6 S! N: B
            memPartFree(memSysPartId, (char*)p);
    + w/ L5 f# A0 B0 D0 v& s; V2 O% I" W}
    9 }3 \1 J  [, ]
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-19 08:47 , Processed in 1.691517 second(s), 50 queries .

    回顶部