QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2905|回复: 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++下的版本,更方便调试。有需要请留言
    2 ^1 s2 v: I* E: V& |0 o0 F- E$ b' [! J3 }
    + r# n! l& R: b

    * k: ~7 j' |, x *\file. b" s: O( f0 P0 N( ]' Q, L# e
    *\brief               
    7 F2 v  B4 _  Y& L) p. u) ? *\details       
    + \* p' q2 B& @ *
    ' g; i9 E, n% a- q *\author        Janson
    , e& z: B+ ]" G6 F/ m: p2 J *\version        * P( b- a  z# _- F+ `
    *\date                04Jan12
    6 ]0 \9 Y$ D. { *
    9 L9 n% l9 p. k( K *\warning        5 u  j' T$ b4 o; o9 F
    *" {, j6 Z3 Y$ f: z7 L& U
    *\history \arg        30Jan12, Janson, Create the file8 h4 s3 o6 v" t! d( S# _
    *        modify from VxWorks source; T( r$ E; Z- c; o. v
    *  Legal Declaration: it is for studying VxWorks only.
    ) v3 W3 H8 q' _ */
    % O0 T# f; D* _% q# U: ^- p1 k#include "includes.h"4 C- }) v$ \1 I5 R4 K
    2 ?8 p( |% a, v; Y# A
    /* The memParLib.h file is hear:5 F2 f; ]9 Y5 R7 c8 Q# g4 t
    https://code.google.com/p/vxwork ... rivate/memPartLib.h1 B" {. H0 M( l+ W* i" x
    */6 c* K6 k8 a% s9 L3 L' x

    3 J, q) N" m3 x- l8 Y3 M$ V0 h/ p/ v/* optional check for bad blocks */
    ( A3 Q6 l; Z8 |: ~4 m  @
    ) V. L( t! W) y#define MEM_BLOCK_CHECK                        0x10
    ) b3 N; \+ P+ F6 S
    0 U+ f& d4 F2 ?/* response to errors when allocating memory */
    0 C$ o2 U9 m. I1 J$ p" R
    4 e1 R2 D7 `% F( a8 x#define MEM_ALLOC_ERROR_LOG_FLAG        0x20! K: |( W$ s1 D1 [# u1 Y! u) E# i
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40. l% c0 F$ @- J2 U2 R) z

    ! b) X# s: _% x; L7 J/* response to errors when freeing memory */
    / d! ~! J# e! A. Z7 u- a
    " h4 s2 h, J& r" M* e  P#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    2 s; E0 C; I! ]! e- h$ k' v#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    6 v$ X8 R+ E# C7 ~+ g7 J) m0 p  \7 g) _9 n
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    ( h. V0 H" q7 V- q2 R#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    3 O$ `; J0 t6 Q3 U" D
    ) h) q" `' X  S4 P/ D#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))3 ]. ^" @2 u/ P6 x
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \7 I( Q" N8 R2 w  Z
                                                    sizeof(BLOCK_HDR)))
    # M4 T, f4 R! M/ v# P5 y# L1 t9 C7 \. y* O7 a8 f% V2 `) o& a
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    3 u1 B1 E9 y+ }6 h% V#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \4 T* L# V& w; T- F
                                                    OFFSET (FREE_BLOCK, node)))3 V' i9 B; ]7 a% c
    . X) W, h$ E: ^( f% a
    static BOOL memPartLibInstalled = FALSE;! O- f/ e) P" k$ l" s5 U" g
    0 i% C/ k  W8 {4 _
    static OBJ_CLASS memPartClass;7 H5 D- n5 k8 q8 W
    CLASS_ID memPartClassId = &memPartClass;
    ! y2 J3 Z1 U1 Y& E  o
    ! o+ o, f( _+ r5 d3 H( I, h& M0 @8 l, |static PARTITION memSysPartition;
    6 |6 }: E: m- g; _/ [PART_ID memSysPartId = &memSysPartition;
    ) j) V! U# V7 yU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;% r# Y1 O7 t5 g4 i3 r" l
    . @+ K0 G. k8 v
    static SEMAPHORE semMemSysPartition;
    ) u9 r9 Y% U9 p: L* D+ V( f; @2 g: s2 H) p) n
    static void memPartSemInit(PART_ID partId);- w- ?, r6 a. _* z5 f

    ) q1 C3 l0 s" }/ }/ B* ]* ]1 g7 i- x) }FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    * f9 }  m# y$ U6 C" i( M1 _" w* @7 {% v1 v5 R
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    ! W: M- S4 A/ e5 N# n" z! X/ n( r$ S3 w
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
    ! W% I8 Y. K# h  Bstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId9 A1 U9 ]2 E( D  u% L  j
            , FAST BLOCK_HDR* pHdr
    " K5 _' d* v  B' d/ ?        , FAST unsigned nWords
    " l. N( n* C9 o/ g" X( @( O: n& i& _2 T        , unsigned minWords
    , g+ x1 W1 k; H% E& K        , unsigned align);# o# \& K' W( D+ @

    4 I5 B! c8 ]$ k+ ^: U& W4 X0 astatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);& [. C. [5 U8 I$ O3 ~! {4 v
    ( q! F( I1 M8 t9 D) {
    STATUS memPartLibInit(char* pPool, unsigned poolSize), d/ G$ w* t  ~
    {
    " a* d- f6 J, i        if((!memPartLibInstalled) &&
    2 V, ]1 X8 J8 V# `9 S                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)$ ]) \# s, h, C  Q& ?; M# v
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    4 y* c4 n* G7 K) o6 M. |4 G        {
    5 w" ?. R, z5 b$ Q                memPartInit(&memSysPartition, pPool, poolSize);  x% h6 h% V# u5 o) b
                    memPartLibInstalled = TRUE;+ f+ e& U" G% s/ f9 O
            }
    6 W2 D: a7 b6 ~  v3 A
    , a5 i% D2 \. x( k( d2 f3 ?' J" A9 @$ u        return ((memPartLibInstalled)? OK : ERROR);" n1 ]0 h1 S: F: C6 d: \' \
    }* u4 r* S5 y3 b3 u

    9 j, E/ F% s$ ]+ KPART_ID memPartCreate(char* pPool, unsigned poolSize)
    7 E$ {8 h( F5 b0 Y, k9 R{6 S  N  j: G- V4 g8 u9 J0 T& m2 J
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);. f# d3 C& N  _5 l9 i
    1 o3 u, M  ~. Q! g
            if(NULL != pPart)# v0 _+ e: o! I/ N$ r
            {
    9 E8 w: x$ h/ V' [                memPartInit(pPart, pPool, poolSize);* l/ o' c3 X- {7 u
            }
    , x7 n& q% B- C4 p7 s7 C& f: i7 ^6 f: E9 f5 g% ~: M" P
            return pPart;0 i" C4 G; ?$ X% s9 l: q
    }# T* ?1 @9 P& D/ B, F

    1 t3 k, M1 {. Mvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)  l  g: K- x) H3 i3 M
    {2 H- Q# u$ R$ o  p2 Z8 t
            memset((void*)partId, 0, sizeof(*partId));
    . ^- b- O: A' \! q, X* l
    ! `; d( W6 j* P        partId->options = memPartDefaultOption;
    # I. t1 U4 R  @, j        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */6 {( j5 g' `- n  J' a7 o
      w$ t! ?! z6 f8 r! y0 V: E+ Z5 o& D
            (* memPartSemInitRtn) (partId);7 Z! E6 r9 ~9 V5 ?8 Q
           
    & k4 p) |9 ~$ t" p, N) t( N4 [        dllInit(&partId->freeList);5 F" o: I5 l0 r* n
            1 J; p" Q) _1 l1 G" ^8 A6 p
            objCoreInit(&partId->objCore, memPartClassId);
    ' _6 `- W9 G$ C9 v. y7 o4 M        0 m& E( T+ H( k, b
            memPartAddToPool(partId, pPool, poolSize);! d6 w1 L$ o  `3 ]4 J* D% X- h- N
    }
    ' e; f2 i+ j- ^7 t( ?" _( D9 ?: P- O, j* N0 l
    STATUS memPartDestroy(PART_ID partId)1 X5 X& Y; R6 G) o5 w- t
    {
    , T+ ]7 r% ^  K. O# h6 j        return (ERROR);
    ' K7 {  P- ?7 a' ~9 T4 e}
    # I' ^% ]; E6 u- u
    . E1 G6 {2 Z% J# K, }( H# }void memAddToPool(FAST char *pPool, FAST unsigned poolSize)2 N% y" a$ w8 M, H/ s* w
    {
    ( c% ~! }% d# e( m, S    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    , e: w4 C, k- r7 w0 s  _2 i}
    * g6 j9 L; K$ w
    . r: E4 r, b( ]- a
    ; M) s  K( H5 u, ~: vstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    * d" N% v5 N% ?9 L) T9 l9 o{
    " Z- e9 Z& |/ U: }9 ~' H7 ?        BLOCK_HDR* pHdrStart;
    ( O- A3 d$ [7 v2 g8 I4 p, a; `        BLOCK_HDR* pHdrMid;
    : J; a# w. ?) f7 d        BLOCK_HDR* pHdrEnd;) J% k( o8 a2 n
            char* tmp;$ ^2 I$ _3 x" ~6 C
            int reducePool;8 f8 S9 [" G  b! Z# A# `7 G
    4 |1 {! t8 w; _
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */( a% W) g" ~1 x7 O9 U9 d
            {
    3 Q, P' p1 t2 _. ~8 L) B5 z1 A% O                return (ERROR);
    8 K* e. A& T5 x( a5 k5 @        }; T% `  Q  _6 G. K/ g9 m1 g
    & A& f7 w: Z. D6 i  F0 Z
            tmp = (char*) MEM_ROUND_UP(pPool);
    ) C* c: X; j/ K) P# ?" K        reducePool = tmp - pPool;( @2 r* d4 I; T1 c; R# M! k6 N# X

    : T, F% a) o: O& l3 h2 Q! r        /* adjust the lenght */
    6 y4 K% Z9 m% O5 C- y        if(poolSize >= reducePool)
    ; ^" \8 s) V, W, C& x& u4 F6 e9 Z: V! t        {0 |/ p0 L/ g( C# E# L! n" H0 Z
                    poolSize -= reducePool;
    # N* u$ b1 y6 H. }        }
    # p# M- i, ~% y        else
    $ U5 L4 l) e; P) h3 _' J1 J$ N        {
    % n& |  I, s. q                poolSize = 0;; n! W6 J% E$ g2 v9 b% N
            }
    4 {5 n$ n. I8 _. k        pPool = tmp;
    1 b( B4 m# c8 ~" ]7 x       
    ) c% z5 q% Z5 H  {) i1 q3 }: `- e, @        poolSize = MEM_ROUND_DOWN(poolSize);) O1 W2 z' P$ Y
            0 ~. l& q: Q9 F) v- e% G) h
            /* at least one valid free block and three header blocks */) f3 [' E/ F( L% b8 U# n
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    ! l8 F9 |( r- F" W1 U        {( f- v5 r, ~5 i( s: |! f
                    return (ERROR);
    ! J) o" X4 k& I        }
    * O+ P" o- i  h/ v6 J; q) O' D9 O8 R4 R% \
            /* initialize three blocks */
    ) S# y8 |$ m) L$ W& `5 \        pHdrStart = (BLOCK_HDR*)pPool;' F7 D8 {9 {+ T
            pHdrStart->prevHdr = NULL;
      K  g- d; X2 t* ^$ h) V        pHdrStart->free = FALSE;                /* never in use */
    " C. y4 N* c% p! \8 l        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;, q& n2 }3 `/ E! }2 V# W; _
    0 @5 N; w0 ^+ a; i# x
            pHdrMid = NEXT_HDR(pHdrStart);  M! ?) o. _( A
            pHdrMid->prevHdr = pHdrStart;
    5 l: r  ?& w2 ?, g, J8 U  d5 Y        pHdrMid->free = TRUE;                        /* the main block */
    7 q* r6 i( o6 b1 p  o        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;" m  h2 ^, ?) T: d9 W1 R
      S% l& C7 U; z6 W
            pHdrEnd = NEXT_HDR(pHdrMid);4 [+ L+ @* J0 F, `# a0 c
            pHdrEnd->prevHdr = pHdrMid;! e( K1 o8 H) g0 u9 H9 e
            pHdrEnd->free = FALSE;3 ^- Z2 ~0 j# N. g
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    ( a+ {' \0 z. y' d% f6 [5 `0 L. K, w0 o) I
            /* TODO take sem hear */
    . w8 U3 H, L  x0 w2 ?        semTake(partId->semPartId, WAIT_FOREVER);+ B& a# v$ e7 q' e
           
    , M8 B+ W& j0 Z5 q        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    ' X6 O1 ~8 P: J3 Q' F) H        partId->totalWords += (poolSize >> 1);2 G+ A8 o% f+ l8 b4 d8 ^" t

    , t' b6 ?3 W- f- y: J6 V% \- Y( ^        /* TODO give sem hear */
    : K" G' R/ H" b' ]6 y8 [( e        semGive(partId->semPartId);* p/ ?9 Y0 Q: z" W

    7 \8 M+ g: E6 M8 f
    6 k  X) @* t# Q" _3 c        return (OK);; S" |5 M$ o% t7 M9 w. m0 q: D
    }1 i0 i* k0 m4 e& y0 L  B# _7 a
    + K2 C) g) K$ W2 S. p
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    % u& X: n5 M; A' \# Q{# [1 M" o- P1 b- h2 N2 B% @
            FAST unsigned nWords;$ a. Y$ E5 _* ~
            FAST unsigned nWordsExtra;, G) [5 ?0 h& }
            FAST DL_NODE* pNode;, o- v  K) f- F! H+ t4 i+ W
            FAST BLOCK_HDR* pHdr;
    % Q& E/ k# x, C8 ^6 D% x8 x        BLOCK_HDR* pNewHdr;( r% w8 s1 O  y7 C! c  \
            BLOCK_HDR* origpHdr;
    ) Y: B9 o, w$ X& p) q7 Y% ?5 ^' u# j
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */  X- J5 }0 `' w5 g" P
            {
    0 `3 X% g/ N$ K- H5 K                return (NULL);
    3 r( |2 W" M6 `  n        }
    ! ]+ s$ Y6 V5 _1 |0 }9 P- y
    # x2 E8 S$ ~+ L2 M4 d# R        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    8 |$ D$ h' f% F& u% Q2 E( X4 \% v8 Q- ^  \* d. J
            if((nWords<<1) < nBytes)
    4 g' \& n3 e$ V! c( r        {
    3 g9 ?$ n& g3 [  o+ V) J6 x. K6 E                /* TODO suspend the task */7 o/ W& L! @: \8 h5 w- @) H# T
                    return (NULL);
    + O' ~# I  g$ w' }/ f        }$ ]; W; [4 D! [6 ]# H0 o
    - o4 {' j+ H8 L
            if(nWords < partId->minBlockWords)
    ' B6 Q* e; e" o: i        {
    6 _# J5 D0 n. T                nWords = partId->minBlockWords;& s) r4 K( w, @# z# a, R
            }
    # n  d& t; v; `1 X* G; D
    5 ?1 h) y) V0 X! K1 c4 c3 t        /* TODO task the semaphore hear */
    + a  c# X! a1 A6 O        semTake(partId->semPartId, WAIT_FOREVER);  ~- w! k: }! f( |% R
            pNode = DLL_FIRST(&partId->freeList);, G+ s( G) k$ [5 f
            nWordsExtra = nWords + align/2; /* why? */1 ~! P( k( I* _! E9 v, p" U7 f

    * M7 n% o! v) _        for(;;)  Z, c& R$ v0 h* U9 h4 i
            {6 L9 d) ~7 q( B5 y4 b3 H
                    while(NULL != pNode)
    3 C; ^5 \3 i5 u                {
    * f. c4 R: I9 I2 ]9 y                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    & }' S, M8 I3 O8 m1 A& [- Q7 T+ ]& R                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&   S: V) k5 e% t+ G7 Y' ]
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    0 V' U& `! n, M* ]9 j                        {0 |: d' K8 R& ?- i: I1 o& N
                                    break;
    / U+ Z4 v6 F* ^                        }
    + P0 N+ f$ y! E4 S: ?, a& g+ p! U" x: P' K# ^
                            pNode = DLL_NEXT(pNode);
    ' O; P+ |) h( y! y0 Z( u                }# f6 b  ]# L3 `9 T; `) s
    2 q8 z# R( p" M1 _/ E9 K9 h
                    if(NULL == pNode)
    ( {6 q* @8 o& T# U                {2 T7 b. l0 o/ Z7 C
                            /*TODO give the semaphore */
    % M7 O3 F2 N4 v% t9 V$ @1 }+ r6 s                        semGive(partId->semPartId);: j* i+ J& w$ k2 p+ n  G# B
                            return NULL;
    " F, t5 O7 b+ O: `( C                }
    $ `" J5 T3 Q) ~# h' S8 k. \% q
    5 t3 {: A9 s2 ~* \6 K6 h* I                pHdr = NODE_TO_HDR(pNode);
    , x7 ^$ |; U; {+ o                origpHdr = pHdr;9 o+ P! v3 N- M' U# ^
    / p" `" u/ N( {! v* R
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);& `" |6 a7 j/ J& B" U8 x
                    if(NULL != pNewHdr)
    5 }$ ^9 M$ Q/ E$ z" \                {
    + Q/ x/ e2 E) D" w9 e                        pHdr = pNewHdr;4 y2 M. p7 g4 k  ?8 {+ }  Y+ W( |
                            break;
    2 o5 V- u& B, L; u- p1 {                }
    6 J3 @/ i" H$ R% p
    ) a9 v3 Y% i. ]9 m5 b2 H. O, q                pNode = DLL_NEXT(pNode);9 ]- p" Z" i5 T+ H
            }$ p6 c3 j( |- y# \& d- x# y& x
    : M% l* t/ f  a: s
            pHdr->free = FALSE;/ c8 D( Q- s- y+ s
            partId->allBlocksAlloc++;4 m8 [- ?7 z! Z
            partId->allWordsAlloc += pHdr->nWords;# z8 w! U* H$ A! E# ~) K0 r5 U/ N
            partId->curBlocksAlloc++;6 F2 x* J! B3 C4 ~3 e, ?% F7 D6 q
            partId->curWordsAlloc += pHdr->nWords;$ D  h. p" y9 u1 J$ @

    5 L0 j* P+ p" S        /*TODO give the  semaphore hear */
    ; [! k' l6 l5 R2 `# ^/ F        semGive(partId->semPartId);
    % |0 Y% Z: _+ b* t4 S0 _# c        return (HDR_TO_BLOCK(pHdr));
    : Z" e( x0 x& _       
    - Q& H! L* H) a0 Z: c! J}
    - t  T9 {4 A  T5 Q: a, w0 \& ~) O# ]; f* g6 V5 \
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes). U! t3 j7 {2 t3 ?+ ?
    {, k' v" H9 o8 A" X2 C
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);  i6 A( ^6 P1 [8 t4 Q
    }
    / l* i# J- y6 @; w  N% F, h) v
    " ]( G  _/ O  {STATUS memPartFree(PART_ID partId, char* pBlock)2 o' K0 Z; ^  q, F( H/ \
    {  I. {( x; ?& n" J* z# k. h; m; f% B
            FAST BLOCK_HDR *pHdr;
    ; Y; g2 `. k- ^    FAST unsigned   nWords;6 l" w3 w+ N6 v1 w' K! [
        FAST BLOCK_HDR *pNextHdr;
    4 T  n1 G7 C0 p- |. Z  ?1 j' X$ i! [& I
            if(!IS_CLASS(partId, memPartClassId))
    * m0 Z/ F* M, S8 J        {
    ( b2 X$ M' M* b4 [                return (ERROR);$ C; `  q# ~. ?+ @& k
            }
    7 N; p4 r: n2 m$ Z& |' g9 r; Y& c4 L
            if(NULL == pBlock)
    & [! ?0 Q! q( [( Z        {
    3 Z' }! H% f3 F% g                return (OK);1 R3 E" t5 Z* b  ~, K
            }
    - R2 G( z6 P8 T  ~+ T# Y
    ( }  Z/ g4 i! E! Y4 e( x( C. A        pHdr =  BLOCK_TO_HDR(pBlock);
    % N6 s: M7 _+ _% T% ?/ J! r/ P7 ^: L9 b$ g$ G7 H/ N! g
            semTake(partId->semPartId, WAIT_FOREVER);, P$ d" ]. \/ ?6 T" m4 P5 T: f5 u

    : P% L. \. S2 n4 g2 I        if((partId->options & MEM_BLOCK_CHECK)9 {5 F+ ~2 o( F$ A) g3 a8 E
                    && !memPartBlockIsValid(partId, pHdr, FALSE))
    6 k' R! i4 c4 K0 I        {
    " b/ f7 c) \6 P0 a, s+ I) M1 R                semGive(partId->semPartId);# B( o  R( y/ ~% Q. ]
                    return (ERROR);
      K1 ~+ t2 s; l4 n; J. d& Q# ]7 Y- |        }& u4 d; W" e- b  Z5 e
    + ?& A/ g4 G2 V  l& a
            nWords = pHdr->nWords;: p0 z9 ^% t& g0 Q4 u
            if(PREV_HDR(pHdr)->free)* H0 w9 W6 a8 [0 T1 T# }
            {/* the prev hdr is free and than coalesce with it */
    / e* v" M& y) t* o3 `                pHdr->free = FALSE;) {. z% D8 W- o0 H" t
                    pHdr = PREV_HDR(pHdr);
      W! ^: @7 a/ ?5 K* N0 z                pHdr->nWords += nWords;+ |$ f! }1 P. n
            }
    " U. C7 c. w3 z$ O+ F! S4 y9 v4 J        else1 m! ^' O& S* u) C
            {
    0 k. `; g3 _- W! C) u! V                pHdr->free = TRUE;0 |1 h: ~- z7 C) _1 [% v4 J
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));8 ^3 h' B4 _6 ]0 d: w! y+ l4 D
            }
    - H$ I7 C% X7 l$ ~* N
    & F# V6 g; x% i; x0 t7 f  {        /* check to coalesce with the next */
    9 _$ ^- |+ |+ V  {8 m- t/ C; g        pNextHdr = NEXT_HDR(pHdr);
    . T& t& o9 V7 k        if(pNextHdr->free)  ~' t# c/ M$ h9 F4 ~
            {
    9 [1 j/ H: v! Q" [: R& _' W% W                pHdr->nWords += pNextHdr->nWords;/ _- [- j  B# U8 f! ]
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    3 ^6 k$ p5 p0 f0 [: [9 d        }3 u3 o8 A6 N, Q: t* o  D

    1 Q9 S  P9 ^1 \( J- {        /* cannot use pNextHdr->prevHdr=pHdr hear */  f: ]- o4 S( h4 d4 @2 ~
            NEXT_HDR(pHdr)->prevHdr = pHdr;) M. @; h9 ?& P8 K: b* c+ B# g; A

    / [% B* R1 m1 x. B" Q& c0 @, l/ S7 ]        partId->curBlocksAlloc--;
    6 U# j$ ~# r3 {        partId->curWordsAlloc -= nWords;+ j3 Z( r* ]' \1 T2 P
    ) T, m# a1 W/ `8 q, [7 b3 O
            /* TODO give sem hear */  t. I7 D  h. i1 @+ W, J
            semGive(partId->semPartId);
    . E4 b  |7 ]( D( E5 @) p* L5 S       
    4 ^/ z$ `7 x; w( y. P2 F        return (OK);. D. Z% T+ o) L7 }& n
    }
    . ]- s& v, j2 S9 z0 e
    5 A. S0 q( M: |" `$ L3 ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    ( T, t. o; e1 k- n/ L/ r{
    ( Y- B( i- G- C5 t- H; Q        BOOL valid;( E) j7 s- I& \7 `" R; N

    2 _1 x4 r" n: l2 t: e% I4 a. f        TASK_LOCK();" X. D) n( D' ?- \* h- @
            semGive(partId->semPartId);
    ( g% @6 @9 k) {+ T) W        6 b) S+ X3 n/ [
            valid = MEM_ALIGNED(pHdr)
    ' f3 k  T8 B  H3 ~9 }( I        && MEM_ALIGNED(pHdr->nWords*2)
    . I. P& ~! S  _! t        && (pHdr->nWords < partId->totalWords)
    ; @, |# h: W) G        && (pHdr->free == isFree)8 Q# O- S7 f/ d- S# D
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))0 a; ^, d- ?- Q
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    1 p# I  y4 ^% g        . K7 [3 D, ~( S& O
            semTake(partId->semPartId, WAIT_FOREVER);
    % m5 B3 Z* I) J5 j' w$ \        TASK_UNLOCK();7 B" u3 E) \- ^& \# i: ~
    5 r$ E) Y2 [4 a9 p" I
            return valid;' B2 i) Z" w5 W9 K. U. b8 j
    }) e2 i" ]( ~6 O
    % }  s9 L  G1 w7 o
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: Y6 i% `( @, B) N
            , FAST BLOCK_HDR* pHdr! u' f  W$ d# V
            , FAST unsigned nWords
      M$ w# X- G+ ^0 N6 [7 c0 O        , unsigned minWords
    / }  h. `% f7 D) a7 y0 E        , unsigned align). {% ]; i4 _7 Q2 C
    {
    6 ~$ I1 V0 ~+ W: M, l+ G+ y) K        FAST BLOCK_HDR *pNewHdr;
    7 u9 n5 q- `* A  |( g; y3 Q    FAST BLOCK_HDR *pNextHdr;2 t0 Y( V2 D! T' Z& L2 t  H
        FAST char *endOfBlock;
    ! `: v& v1 c5 u/ M% P# f6 R' E    FAST char *pNewBlock;9 s; c/ u' j$ V+ c
        int blockSize;) K! @) [& D  w6 s. M* P4 G5 U) }
    ( J" [9 Q2 ^# l0 r0 u1 |
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);* h( k# I7 e( V) d) ~

    1 }# F+ B+ M0 B, \        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    ) s8 H3 y3 B) s* Y4 K
    - O2 _- |: g9 E# n- X        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    , w4 D: E% B" `9 k; C) W$ e4 H0 W0 C. J
            pNewHdr = BLOCK_TO_HDR(pNewBlock);
    3 r0 ?" `7 I! O$ k4 h! H. L2 k- V, w" w+ N* j% p5 B; Y
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;1 N( \) W! i4 s7 {9 [

    . n/ t4 c" N  S        if(blockSize < minWords)* I2 s2 \- F* M. |# {
            {
    * x& I$ l8 S( q6 y# d; @& c                if(pNewHdr == pHdr)
    1 A9 v3 j9 \( Z3 {8 v" I! j( ~                {4 C& R9 w1 z( N( n
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ; d& g" [, T# p( i% l                }
    ! S4 g$ L( G: K4 P' a                else- {* E* C& k* P' j$ {( n
                    {3 v3 H2 n" D3 f
                            return NULL;
    3 l7 }" ]- @- l1 `4 f0 \                }
    % f- H5 `4 o/ S% \9 V0 p        }9 i( E2 N* h$ u/ L8 b) V
            else* Q" J  }( ~" S
            {        /* recaculate pHdr */
    3 l1 Y3 x8 S/ u' n8 [                pNewHdr->prevHdr = pHdr;
    . |3 m+ I- C; r6 l' V* k  t! w9 t                pHdr->nWords = blockSize;
    - w2 B  R  B# k; D/ `4 e        }
    # d; S1 P4 w' i( w" w2 ]8 u& l  w- q* I0 Y0 B7 O# t6 z
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)); f$ ?/ l0 \1 f! I8 y
            {
    2 p- ~, A" r4 p. j8 n% l+ |                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;3 O, D5 e. H$ D# M2 H
                    pNewHdr->free = TRUE;) t% l# X: p& ^0 M5 k' I' C' d

    3 E: V9 s4 Q! b3 N0 V( T                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;% q2 i" v$ ^4 w& J; k( B9 R( ~# N
            }% v6 r" ?+ U' K2 |6 d
            else
    * G: _0 H+ R- I; G1 K        {/* space left is enough to be a fragment on the free list then */
    7 Y4 y& O+ R: B# V* s: A                pNewHdr->nWords = nWords;7 P7 s* q( U1 P9 o9 {
                    pNewHdr->free = TRUE;
    ! {( L+ o5 ?; l" m. k2 m6 f6 b9 A
    * w1 ?3 z+ T# l                pNextHdr = NEXT_HDR(pNewHdr);
    1 W0 `1 X. w' o; q                /* words 包括BlockHdr */( H9 C! F0 U7 I% L8 E5 W+ o8 [( Y
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 f* v% t, p0 T9 _0 N
                    pNextHdr->prevHdr = pNewHdr;; J4 R6 a+ }5 J7 D4 r
                    pNextHdr->free = TRUE;, b0 s) j9 y6 W" Q$ P: s1 c- i

    7 Y2 ?8 j* Q& A2 T                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));, M& q) ?" ~# n3 t. Q2 v6 N7 ^- \

    . v4 Y  ^5 k, G5 k3 n/ q                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;& m6 v- C; U3 u* D' m% t: }
            }
    * z: o+ _  ]6 C# d( r& \2 D. o  ^" Y7 P5 Y
            return (pNewHdr);
    0 F7 w6 A- {$ F3 E, m5 [3 k. ?}& E5 L& e2 P" {$ I& N  u! |
    # R- `4 P, v9 @8 O$ d% e1 O
    static void memPartSemInit(PART_ID partId)
    & t) G: U: v4 L& {* p{9 t+ q5 I, a6 @4 r( s: ]( L5 a
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);0 D; t/ D* S9 W$ D; c

    7 c5 f9 J5 R& O5 s9 H8 w/ g        partId->semPartId = &semMemSysPartition;
    3 I  w9 t2 b3 u* `! w}+ b; T! L8 }% ~, ^+ Q, L
    ! K; y0 ?" a5 E' g4 n
    void* malloc(unsigned bytes)
    / \% C" ^& c+ Q/ p- R2 k. j{
    4 R: O8 u6 g8 ^        return memPartAlloc(memSysPartId, bytes);
    3 S$ h7 |5 Z& Y: Z}& Z2 u+ l- Z) w$ x2 K# B

    9 O! t$ u+ T! B( vvoid free(void* p)1 V9 T  B" f8 Q* d+ ]1 k% J6 c) g" l, j% i
    {1 X, v$ c% a: D* l; H+ S
            memPartFree(memSysPartId, (char*)p);
    & N! _$ B" y% l" X}
    & K0 F$ Q) C/ y% Y- b. c
    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-9-3 10:07 , Processed in 0.432121 second(s), 50 queries .

    回顶部