QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2833|回复: 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++下的版本,更方便调试。有需要请留言
    1 D. T  L& w8 w) D( J: a2 K7 [- \+ ^! X8 J
    & Z  Z  D+ K" x; Z/ l

    4 W) f# ]  Z* L1 r *\file
      V$ g6 H) g, g# g; L *\brief                - p0 V/ [$ e; c
    *\details        ( i7 C3 q* ~; y
    *' ?, S1 c' F( G$ t8 k* F& @
    *\author        Janson% [/ B; ~3 s. ]4 G8 N) b5 L2 }
    *\version       
    $ w' N6 L4 L8 N* G *\date                04Jan12
    5 q/ }, q  j3 i, E. h# W$ M/ d+ H *( P# ?2 i3 C" }% f; j- I
    *\warning       
    " f4 q& X( ]1 U0 z  N8 f5 m *, J* s( v) J2 m$ {2 O/ r
    *\history \arg        30Jan12, Janson, Create the file
    + j, x* e! B) O! d4 ?1 w *        modify from VxWorks source
    ( [# ]& d; T% t) B$ v/ y *  Legal Declaration: it is for studying VxWorks only.# B5 d: G- G5 h; b) x$ l4 U/ ?
    */3 I3 n# T; s# I: r" d) u' o
    #include "includes.h"
    $ H- V: u; C2 l& R
    / F8 ^' _! F' Q6 A/* The memParLib.h file is hear:$ W1 S9 j( V% a/ b
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    & z6 T" |+ g8 s6 B+ l- G# K*/! u' `; L8 \) [" w* S8 B0 h
    . }- Z; [2 z# \8 v
    /* optional check for bad blocks */2 A" Q/ h9 b* s6 i

    + B) {6 d  a% h- {, ~% `" ~#define MEM_BLOCK_CHECK                        0x10: \8 l7 V" K* x6 ]) q* o
    2 P& Y8 h$ w8 f* b( x, h$ ~
    /* response to errors when allocating memory */
    9 E0 W& S1 h2 i0 q+ c* O3 |! F+ A$ s1 A7 }& e" _! I0 \) `- k
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20% H' F9 a, i9 k2 t
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40/ @, @0 J% s$ `! i+ ~
    ) A$ e. ?" l( h9 L  l
    /* response to errors when freeing memory */
    9 V0 J: n7 Y% V; C5 X9 y' R/ }# u) V" V( j0 p
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    - b& R, D: L( ^, [. ]#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1005 F0 U$ h6 s0 T6 ^" d: @; T

    ( J% F& x) M9 l$ t0 A- G7 q#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    $ o8 h1 I6 l& A# k# n3 q/ W#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    ) q4 d) \! S" v
    6 f* }4 U& B7 t% r) j#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    * V) K* l) t: l) [, e* M#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \( ^9 c! W9 }5 A7 ]# u
                                                    sizeof(BLOCK_HDR)))4 F3 B3 m0 A; I. S) N% ~/ g# }

    $ ?" s! Q$ K+ `9 X7 u6 Q#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    9 H0 `) c7 o8 d0 A; o#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \" p- u) k) J" V
                                                    OFFSET (FREE_BLOCK, node)))
      t- x& C! P3 L  c! t( `- d
    " y# L( O+ j  }5 x+ nstatic BOOL memPartLibInstalled = FALSE;% d6 @% G5 E0 ~- O
    - @0 l2 `& ]( M* e
    static OBJ_CLASS memPartClass;
      `( ~5 @7 N8 Z1 X# l) {) ]0 e6 bCLASS_ID memPartClassId = &memPartClass;5 U( M0 ?( p0 e3 Q
      n1 D3 C  K& P% L
    static PARTITION memSysPartition;" @( K- [0 H  I
    PART_ID memSysPartId = &memSysPartition;
    % q; C  y) e& w' RU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    4 C7 x' @$ D+ }6 Z( y$ F
    ' j) _. L6 j% fstatic SEMAPHORE semMemSysPartition;7 X! `) l% u" i' R0 R" j0 q# l

    - Y, f! C  @! T9 f+ astatic void memPartSemInit(PART_ID partId);, D0 p) f. u9 h; l. |% _

    ) G8 ?6 S) l# f! C9 x. }" LFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;2 P( X- L2 f& B3 X
    , f( i- c* W* D& e0 K
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;+ y% m7 |: A0 Z

    1 F0 i4 F# z/ i; s! t& S1 G/ Wstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);( m& f& L$ U1 a* s: m
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    ! X& y) y7 l, [& ?6 ]; P7 S0 E        , FAST BLOCK_HDR* pHdr
    ' e$ ]4 V7 u3 N9 T        , FAST unsigned nWords2 H1 f2 |( R; X: F+ |# J+ }. q
            , unsigned minWords( n8 p4 b3 I$ k
            , unsigned align);
    $ W% L6 D) D9 `" ~/ Y3 w4 i/ c& y
    0 R. Z4 \3 O- ~" S4 Q& c4 qstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    ' ]2 E' g  a; k. R: X9 M! ~  O- \! B( d
    STATUS memPartLibInit(char* pPool, unsigned poolSize)
    1 O/ ^5 u0 x$ J7 p1 M4 q{
    - z" x! r1 Z  C  H% `        if((!memPartLibInstalled) && ! c! R5 }5 g) }2 h* h- u# R
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)5 B  V  `0 b* O  M
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))1 y/ q' e5 w) F' u; g7 z6 ?8 k2 y
            {
    * b  H. [' C* s6 p5 t                memPartInit(&memSysPartition, pPool, poolSize);
    % }% a1 |3 X- |1 e% _, E$ M                memPartLibInstalled = TRUE;
    1 f: ?: S5 \2 \, a/ A: A        }
    8 q' j3 I8 i  [+ Z8 v* r4 t/ M3 p' U6 h- V9 X; J
            return ((memPartLibInstalled)? OK : ERROR);
    ( c$ \  ]) R, Y}9 K2 o! P# y# {) q2 b+ B
    / f8 b: ^& p4 X7 q$ b, B
    PART_ID memPartCreate(char* pPool, unsigned poolSize)
    / }- E+ D( h7 H' F5 O: Z* U0 ~{, G2 o7 _/ ~9 [% }/ r! c# M
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    " n. m. _: u* N' q6 j
    ( R8 p/ O. c9 u: t# y        if(NULL != pPart)" Z1 P/ X$ S0 c( V" A6 h3 l
            {" s7 J2 |' |9 ~, \8 l. e; e- |
                    memPartInit(pPart, pPool, poolSize);
    . A( L; t" P% q0 \+ c8 O6 d        }
    1 [- \, c9 S) O3 g) Y; ^
    . m7 M0 s% L5 q$ a# X& v5 y        return pPart;& n  x4 q- I# T1 u
    }& H( [: i+ ^6 R9 ?4 o  W5 }! F- u

    + m1 ?0 O+ E; C; F; qvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)- _% B( z# T  ^/ x- F  `
    {
    - r* |5 V# e* }* V- e        memset((void*)partId, 0, sizeof(*partId));
    8 M6 v$ Z3 M! b# d2 n* o- _7 L3 F) x8 R: p
            partId->options = memPartDefaultOption;
    2 h/ m1 V  q; i. I        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */  p1 C) J# E0 b- b: a6 B" k

    4 r  o0 i& e/ a" B" Q% ^( r        (* memPartSemInitRtn) (partId);
    2 y% a( m0 u7 z/ I; Q- K5 ]% S; A       
    6 o% c; k; r# t+ t4 {7 h( W' P& i        dllInit(&partId->freeList);1 m+ z0 q# h5 e: W( h% V
           
    ' i+ z% p5 d- A' n. F& D3 m        objCoreInit(&partId->objCore, memPartClassId);
    5 R% `; \  A- z+ l, x       
    , \7 d6 ]. C; \7 P. j( |        memPartAddToPool(partId, pPool, poolSize);
    , R& A: B1 b8 ]}4 W% R+ @. L* c! M5 W
    ' J5 Z% K- o& h; w
    STATUS memPartDestroy(PART_ID partId)7 c! E  _% }1 {& T4 Z
    {
    + J  ?" C% x2 m) s8 Q        return (ERROR);
    . t' E) n" r+ [; U6 V/ x}0 W7 z! f5 `4 c7 {

    * M8 @2 V) m; K7 B9 Lvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)6 P) b0 X4 ~$ [' S4 m* s2 r3 b, X
    {
    1 w$ i' T6 q0 C; A    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);9 l3 i. w2 q; ~( ~: Q+ r0 Z
    }
    ! j: }* y* I: _' d
    : I2 ~' [$ i" Q' I8 u5 o2 E
    $ E- h" v' h  w+ c! T4 J. ~9 ~static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    7 X8 K8 {& Z; r" z1 \+ ~2 `7 `: u{
    , ^( D4 ]5 I3 b0 I' k# o        BLOCK_HDR* pHdrStart;" W7 y1 L, J1 x  f! D
            BLOCK_HDR* pHdrMid;! E6 a2 C2 Z/ H/ d; z0 s
            BLOCK_HDR* pHdrEnd;; ?8 S2 x5 f- D/ u
            char* tmp;
    ( B$ w5 f" }5 f' {9 }# t        int reducePool;
    # e7 ]8 x5 ?! [2 ^9 c. I0 G; e, ]% h" Q9 E6 V( i$ K" p) a
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    0 |2 O- \& v  ~% h4 z        {0 D+ A1 w5 u, k1 ?1 v
                    return (ERROR);
    , N: g% U: I+ `% @4 N% r2 i* P9 R; W        }& B5 D  ~% b- b# S) Q
    % L0 @7 P% h4 d1 m. e1 m+ `
            tmp = (char*) MEM_ROUND_UP(pPool);
    : M7 y8 \4 T  W        reducePool = tmp - pPool;+ Z& l. T  T2 l9 J+ d2 Y
      a+ X5 d; k4 e$ A) }; d% J
            /* adjust the lenght */: \# j0 X0 V( }- B* S6 n
            if(poolSize >= reducePool)- A# P, ]- a) G6 V" R
            {
    ' A# v' i, k$ r0 b# S4 f3 B                poolSize -= reducePool;1 }. f# a1 s6 b. g4 J+ q8 R3 z
            }
    / ]$ {$ p6 H5 s8 s* k        else
    ' l, m; J3 o8 s6 d2 t3 l        {
    2 a9 W" m$ a( W8 a                poolSize = 0;; o# f$ `: ?2 m0 ~
            }  y2 g6 K% e8 o/ w0 Y' p
            pPool = tmp;. @1 q' O5 \$ s$ b
           
    ! P3 {) A% x; n: {* [        poolSize = MEM_ROUND_DOWN(poolSize);
    - O+ f7 \1 b/ h       
    4 u% T- K/ n4 ~) [        /* at least one valid free block and three header blocks */- R; `  o/ x4 `
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)3 h0 \3 j8 d% [0 R9 P
            {* @, e7 Q  h( L& e
                    return (ERROR);9 x7 p- r7 M0 J1 z* n, O8 s" e
            }+ i8 B. t7 j  G+ _3 g' _1 }
    7 C+ l/ K9 a* k, l  n1 }. |: x
            /* initialize three blocks */
    . z8 I9 H% i( n" ]0 i1 m3 k        pHdrStart = (BLOCK_HDR*)pPool;
    - _- l9 i/ x1 W' V1 J: |        pHdrStart->prevHdr = NULL;3 ^, Q+ |5 [/ b% c: U7 l  e
            pHdrStart->free = FALSE;                /* never in use */
    ) U  s# o' j0 N5 j+ Z        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;( H. _+ F4 r( O; [
    " S) @2 A% v7 N  p; ]5 M
            pHdrMid = NEXT_HDR(pHdrStart);
    ( L# H6 u2 ~: D# H( V) d        pHdrMid->prevHdr = pHdrStart;* Y4 J, ]+ O6 q) X
            pHdrMid->free = TRUE;                        /* the main block */
    ; H" R/ K  _2 r/ K3 ?& k        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;. X- \% m, j' l6 p4 p

    5 f$ B  X7 N+ c  r( e) T        pHdrEnd = NEXT_HDR(pHdrMid);1 n3 ^; p" o4 L7 W. g, a3 {/ L4 _
            pHdrEnd->prevHdr = pHdrMid;
    + C. k3 A1 E! m! P        pHdrEnd->free = FALSE;1 ~6 k1 o3 x3 e8 m+ T& a0 W
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    7 [4 h2 I; A* f3 r! `. J- ?1 N( h2 y' O8 o0 J: a. X
            /* TODO take sem hear */- s; D$ `" Z1 T  @" x" B; `
            semTake(partId->semPartId, WAIT_FOREVER);; g/ w& h1 V8 t. ~* x
            6 b$ z4 t0 Y3 r( l' z9 F4 G* }, n* _
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));" T/ X/ i& \& _! X& K7 }2 N
            partId->totalWords += (poolSize >> 1);7 R! O3 }5 v* B; e) n

    0 w6 p/ y, _, R& `        /* TODO give sem hear */1 ]& q# Q' U" \# k
            semGive(partId->semPartId);, h- J8 Z9 ~1 l  X
    6 A- m, B  x7 q. M) J9 s! H. W
    $ c0 a7 j9 n0 u0 y! K+ m4 M
            return (OK);# {, U9 Q: l3 d# Q& l; Y
    }
    . W, X$ |: W+ i: L. [
    ; f8 ]8 }4 o4 p1 x# q% d& Vvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)4 C( ?* \5 Q: p7 U( ~' ^# p5 O
    {3 V* c# J! S5 N( H
            FAST unsigned nWords;
    $ J, \" P4 ~+ I  _        FAST unsigned nWordsExtra;
    - ]2 z* C; g1 d        FAST DL_NODE* pNode;
    4 H& n0 Z) ?/ r        FAST BLOCK_HDR* pHdr;
    3 u3 D% n: ^% C0 b1 J' m        BLOCK_HDR* pNewHdr;7 ~( J' v- R' F& n0 }) S( |
            BLOCK_HDR* origpHdr;# d7 w1 H% n: @; [: P

    4 ^: r7 D; h' [3 a2 |, [4 q, H9 w        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    9 K2 P7 L0 M: m: p0 n( Q( X. Q) Y        {: B& s, W8 F/ V- H) z" s$ d
                    return (NULL);
    , y# k' a$ V9 c) Z4 [5 z; }% Z        }3 o3 k+ c% i) u) G0 l/ P, D7 q

    5 P) F# D9 T, Z4 z        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    1 ^- @2 V% ]6 X* u, F7 C9 d3 |; m6 B
            if((nWords<<1) < nBytes)
      I6 g! g. x4 v+ n4 z" {        {- ~% g8 R# |7 r# J/ W
                    /* TODO suspend the task */7 m% f% Z: U% i& D! q- a
                    return (NULL);: z+ L) o. r3 t! L
            }/ k5 s- O4 K# I

    2 r8 I7 l; ^9 g. t& a7 u        if(nWords < partId->minBlockWords)0 c) ^2 e0 @% f! Z$ H' |4 B8 H) U. x
            {
    5 A4 l7 E' C- V                nWords = partId->minBlockWords;
    6 d4 b( ?# f5 Z$ C( B. Y0 x        }
    & D$ r( z4 E! D+ b) ]
    3 v0 s' j+ E" o        /* TODO task the semaphore hear */
    $ M' [2 ~' w% c9 w# l        semTake(partId->semPartId, WAIT_FOREVER);9 J; Y5 O9 f+ l! Z
            pNode = DLL_FIRST(&partId->freeList);
    ' S& Q! `3 n4 ~        nWordsExtra = nWords + align/2; /* why? */
    ; t+ l) o2 G5 U5 J4 x) I) X$ Q& f; L' i7 U! T) ^) v
            for(;;)
    & @0 `& A' [0 o        {
    $ X  M  b) ~) c' n                while(NULL != pNode), a. ~2 ]" |/ f; s/ ]3 y
                    {
    ; k& S% N# l3 ~  n8 [* f) J                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||+ S( O" A+ S4 R8 m& y+ F
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && # B2 K7 X) ?  a
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))/ {$ C8 i* Z: U) s* N
                            {
    7 M- _& n) f* e5 @, E: t! R' l0 I- X                                break;
    9 u& ]8 r9 K$ w. h* w                        }
    ! s) E- u. r5 _" k8 D6 X9 E/ R) ~# ?
                            pNode = DLL_NEXT(pNode);
    5 H6 {2 C  f- {                }
      `2 o& u- C* ~# |; P. l3 p- O7 J  I$ w3 }% T& d, }2 j: I
                    if(NULL == pNode)/ e4 S: T# Q5 q2 t2 W  ~! L# Y
                    {
    1 b. L8 q! x* T1 q                        /*TODO give the semaphore */
    - h9 ~7 |5 [2 D5 l( l                        semGive(partId->semPartId);' ~7 P, G9 T& p, A
                            return NULL;6 C! O! M, c' ]$ l# `& ~
                    }3 I: N3 P4 Q. y1 `" h3 V
    - m. d2 K4 U4 J8 p1 n& I1 w& y
                    pHdr = NODE_TO_HDR(pNode);( e# i# u3 `$ W
                    origpHdr = pHdr;& u0 y6 v4 f, H4 h- C

    : x4 X6 v* a7 y% V                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    , r5 z; j- ?! R: \2 _( T                if(NULL != pNewHdr)
    1 v3 B& x5 [- V1 j1 n( {4 \/ e1 N                {
    # n& e& J* @3 s                        pHdr = pNewHdr;
    4 x  s, N) m" q" G+ \5 ^% l# b, b2 Q                        break;
    $ I5 D) Y2 {; y" [, v. G  x                }  y0 V; P* y. S( h% F* d

    . }' ~: l6 X" t9 p* f, Q3 o+ _                pNode = DLL_NEXT(pNode);
    . R8 u5 |' w$ F" [' i+ f6 I        }% Z7 ?) L0 N. X9 T/ v& g
    % `; h5 [+ Q* l0 E* s
            pHdr->free = FALSE;
    & t" `0 _. T3 Q8 @8 O        partId->allBlocksAlloc++;& Q( c! X9 K# a# P) s
            partId->allWordsAlloc += pHdr->nWords;: l5 W3 z5 D, B1 i! u8 Q
            partId->curBlocksAlloc++;0 O# q) E, L9 t0 E& d3 w  d
            partId->curWordsAlloc += pHdr->nWords;0 i/ l2 H3 J5 }9 z/ M0 a

    0 O, F  d: `/ J        /*TODO give the  semaphore hear */
    . _3 g. N9 _6 p        semGive(partId->semPartId);
    ) `/ z5 N+ @. y- u6 l. ~        return (HDR_TO_BLOCK(pHdr));
    ) A/ ?0 h0 c& _# r; S       
    2 {# x6 q; k1 x$ \! C9 E$ M/ E( y+ P}
    & {. }* R. L3 f5 o' n5 R" B: t* H# s- C1 L
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    % Z" }/ o& m" t) b+ K{
      [- T/ w0 a2 V! C. z        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);4 d( |, N- @8 y  L
    }
    3 Q) D. w+ z5 _" b9 g" j; h& }0 q. |" m, E3 p& D
    STATUS memPartFree(PART_ID partId, char* pBlock)
    5 ^* f; M) a" _. _" F1 E{
    # a% ?& h% p' k9 |7 Z3 c9 d) O# l: V        FAST BLOCK_HDR *pHdr;; a9 F& x- C0 d
        FAST unsigned   nWords;
    / N% E, I. {! w    FAST BLOCK_HDR *pNextHdr;" G/ z# g* m7 t8 D
    * i8 s3 Y( F9 V2 W6 S9 `% J( l" p
            if(!IS_CLASS(partId, memPartClassId))
    6 L  n" O% m% K: X5 _        {3 R" A" x+ z/ K
                    return (ERROR);
    9 `* y1 c& j3 p& j        }5 X8 D" {# j1 v

      c& U+ Q7 p. P4 E7 I        if(NULL == pBlock)& {2 c$ e  ]+ u7 H- j
            {
    % c+ L3 G' L# Y; P; G                return (OK);
    / a& G7 p. r- k( \/ R& M        }
    , W1 D1 v, S+ B: _7 M- U$ w8 L9 w# v" B+ e3 ]% Y
            pHdr =  BLOCK_TO_HDR(pBlock);
    . D5 R2 }& R3 Y& ~- `7 c0 R8 }& R  |. x
    + d. d3 y. g- ?! T& Y( |. t* A1 A        semTake(partId->semPartId, WAIT_FOREVER);
    + j4 u& }  l: {( e; `
    ; \% {& s/ _5 Z" T) \        if((partId->options & MEM_BLOCK_CHECK)5 `5 M8 b& v* i7 ~+ ?( ~
                    && !memPartBlockIsValid(partId, pHdr, FALSE))
    1 b: @$ {. U. r        {! ]( B0 }5 `9 n! g: S. y$ F
                    semGive(partId->semPartId);$ k, x& R9 u+ a. \9 ~
                    return (ERROR);; F+ R# }7 G8 e8 m# e  f
            }
    % `1 J) t' n  a' T5 w6 o; u3 U# D/ e$ U0 S0 K0 q
            nWords = pHdr->nWords;
    # M2 U, S# _; X1 C" f9 D        if(PREV_HDR(pHdr)->free)
    1 b' z; E% p7 S0 K* E        {/* the prev hdr is free and than coalesce with it */4 i4 A, [* d( ^$ [; l' y7 z
                    pHdr->free = FALSE;
    ) y& U2 I0 d) G2 W* L2 A3 W! }! _                pHdr = PREV_HDR(pHdr);) F& l- R% r9 p, h
                    pHdr->nWords += nWords;
    0 b" c, L5 [$ ^' X        }  e. {& _* n4 u2 Q8 W( A2 L7 H
            else) F* C' q9 f. H  z
            {0 A' c( V3 d) w" @0 h
                    pHdr->free = TRUE;1 D" O) |' e9 U0 ~- c
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    $ g5 q. L5 n- p* N) z' j        }
    * x7 x% H! `+ U+ i+ p! p0 w, {4 {
            /* check to coalesce with the next */
    + x, i/ {1 X- K6 K$ y& t        pNextHdr = NEXT_HDR(pHdr);1 @: d5 F* B6 c, o5 B
            if(pNextHdr->free)
    & K) D! v* i: {; Z        {, G. I$ }8 x4 R) x
                    pHdr->nWords += pNextHdr->nWords;
    # F3 p0 I3 j( a4 Q9 i                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));7 Z- P9 V9 A& z' n9 K
            }
    * I! T- L, w* M# o$ S1 G( [8 O% q3 [# D1 T/ Z4 f9 v5 E# k+ ^) Z3 H  q
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    : [% Z( |$ m# _4 d  l* B. `        NEXT_HDR(pHdr)->prevHdr = pHdr;5 [6 H$ ^5 z$ e' p7 z
      T7 i( ?' w% r0 G, x3 U
            partId->curBlocksAlloc--;5 _7 \. E8 Q9 a$ u3 u( I
            partId->curWordsAlloc -= nWords;6 l! E5 W  Z1 M0 q" |6 d8 c% u

    8 M* m' }  p9 d        /* TODO give sem hear */
    4 k2 I' P: E) R4 w3 K. C' f1 E        semGive(partId->semPartId);5 Z  Y+ J3 k; I; @* `  y
           
    + w4 u5 d; o5 V) n        return (OK);
    ( U8 U, \) e1 H! K}
    : ]( S( o. t- ^% s! J* C$ u5 f* o- ^* M8 @0 \$ O! a+ `
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    7 n9 r6 X4 _5 U/ p- n0 A{
    5 C$ [0 p+ U% a9 c+ u8 z        BOOL valid;, Y1 ?3 L4 l1 G' ]0 M' ]" x
    # R9 a; d% S) r  a6 O
            TASK_LOCK();4 C" s) ^6 f- U  q
            semGive(partId->semPartId);
    7 ]0 Q: |9 k* Q& p' s5 ^       
    - L/ w/ I1 t# }& D        valid = MEM_ALIGNED(pHdr)
    & x$ X" m+ v/ m) d+ H# Y        && MEM_ALIGNED(pHdr->nWords*2)
    / |) G3 O8 w9 M  F9 I9 `7 d        && (pHdr->nWords < partId->totalWords) ' r3 C& D& j( B
            && (pHdr->free == isFree)
    ; G% `$ W1 X8 g- V) l        && (pHdr == PREV_HDR(NEXT_HDR(pHdr))): X4 r4 a" k! c
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    - C$ k, T; q3 l4 d0 H7 W       
    5 F6 F3 O' p9 F2 z  N, L1 T        semTake(partId->semPartId, WAIT_FOREVER);0 O% _& H0 i# |& ^5 h
            TASK_UNLOCK();3 y2 z9 L0 w! x- s$ ~
    2 g) S, C6 x; B) v; u
            return valid;
    # i* h! I- `- \% T* L- @  T}* |3 z: q0 j5 t# i. @
    & Y4 B9 e, y3 j* q3 p
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    1 J/ f7 V9 v3 B9 P/ g/ o        , FAST BLOCK_HDR* pHdr
    . I, [9 n/ M; C6 O! P1 ]        , FAST unsigned nWords: ^$ m" D1 _6 c$ A
            , unsigned minWords
    * R' X! l: d. D  U# }        , unsigned align)+ a. f" [8 W6 Z; x3 Q' i
    {
    : ?  `/ k. M8 f% P' k8 Z        FAST BLOCK_HDR *pNewHdr;/ L( @& a+ H  `- Z  f7 h
        FAST BLOCK_HDR *pNextHdr;
    + j1 K" Q8 d9 Q, s/ P    FAST char *endOfBlock;
    0 P) v' t. V, S( y' D    FAST char *pNewBlock;3 s( h/ F( t5 P
        int blockSize;
    + ^4 a8 K3 V1 v" y- l, x1 q, \# r8 e1 ?6 Y
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);8 S: ~8 A* F2 @0 a; t" Z1 L3 v
    3 B9 B1 \* \8 ]0 R
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));2 K! k# k9 l3 s& g) r) a1 M( l. V
    $ u4 U7 w+ O. [  h3 A$ q
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));/ B  \1 l0 B$ p0 ~1 y

    3 {" `% ~3 @" u: L7 \        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    2 f- i; L/ }# g( _
    ' t5 m% n( i: t, q$ I8 \        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    $ N3 r5 h  o5 ~0 S+ K/ G4 P+ @1 V0 S- J8 L6 A
            if(blockSize < minWords)
    3 k, v1 d4 P7 A/ F# c. \        {: S! i9 `  B; X- T( a
                    if(pNewHdr == pHdr)) s5 Q/ \0 b+ m8 ^9 o8 n2 N$ V: [
                    {; d+ c" {% G4 g4 `) [& o% S
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    : I+ Z( s/ r; |! X5 W( F                }# i5 H0 P. i$ s2 I
                    else
    ' I/ Q/ M6 k- ?2 ?- v7 f                {
    % o, z. H" }6 ^, H2 p                        return NULL;" o  V' o3 S$ o5 R. L' X
                    }/ U! T& r) B* q8 H2 _
            }
    6 i  q, K- ]" A% F# a        else& U, I8 H, v! d7 ?4 @2 B
            {        /* recaculate pHdr */. h$ B; p0 }4 ~, R8 N2 ]
                    pNewHdr->prevHdr = pHdr;
    + g5 l1 M) k7 d# }& E# r( t6 E  i                pHdr->nWords = blockSize;
    6 p- R) U. x5 V/ F) \/ I        }
    4 I" w1 F1 }$ Z- }5 n1 Q- Q- b: V" {4 A5 |2 S: H' C
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2)): y7 Z! v8 t9 r
            {
    ; m- P5 u# p" V' i+ ?. v                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    0 Q& m  z* ?$ z! z" }                pNewHdr->free = TRUE;
    ( J( Z, {/ @# f) H6 B5 F8 Z* w7 A. k( C( Z7 G! P% u& q
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;8 g$ L3 C* t' j" F: T5 M9 C3 @+ W& j7 I
            }
    4 v: d- U# U; J/ E6 \, _5 b, E        else) ^, Y/ j% o5 J0 i6 f  U
            {/* space left is enough to be a fragment on the free list then */
    7 W- L# f  L+ p0 h9 |) G                pNewHdr->nWords = nWords;" u, h& o, g5 I) N/ A
                    pNewHdr->free = TRUE;% J0 w9 T! E7 h2 S7 v% ?. `% w) c4 ~

    8 `% T7 @. {1 }( L6 z$ y! ?: d6 L& Y                pNextHdr = NEXT_HDR(pNewHdr);1 e4 D2 |4 V8 }2 `  E" |
                    /* words 包括BlockHdr */4 y3 W- k: S# ]
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;7 H# E. f% P) |- [6 V, Z
                    pNextHdr->prevHdr = pNewHdr;% `2 K* x( d1 m
                    pNextHdr->free = TRUE;0 ]9 H5 G% l; R% H4 ^- E
    ! f9 q1 j" F2 q7 E
                    dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    8 V+ z0 `  V) @. m: b2 k/ H6 J! @3 w0 W* U- w$ d8 x8 G5 @3 B
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;+ K: G0 Y1 G6 |/ x% s% H  E
            }
    $ x& l& @% Y) z% J. D1 i! d; @
    " j4 Q( y. v$ W  l* i( L, U& i4 O        return (pNewHdr);8 [) f: f4 d1 [; k  V
    }
    # E  E- [0 K  }: K2 y% D( b' A2 y' b) `
    static void memPartSemInit(PART_ID partId)+ R! V% d4 H9 ?+ ^. a
    {; J/ c, y6 s; ?& G
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);9 E$ @( C" }2 a. d- z: y

    # j5 F6 X& H5 x3 ?2 l" s: I        partId->semPartId = &semMemSysPartition;
    ' X0 w& |1 R4 C7 Y}4 p2 `& k& d& o+ r4 G# ^4 x% w

    ( I. K6 w) B% ~1 _8 c4 V) uvoid* malloc(unsigned bytes)7 `. D; d8 R' L/ E3 r
    {
    $ W2 k! i. a& A5 t: E3 p        return memPartAlloc(memSysPartId, bytes);
    2 r) `$ b/ n4 h8 x; S}, l7 e' `# [1 S4 \$ c, x+ Y

    # G3 P( t& c2 w7 Z& B, U% O' }; lvoid free(void* p)- Q2 h% r5 t8 @! _
    {9 p4 d8 ?7 f$ v8 z- V0 {7 d( ^
            memPartFree(memSysPartId, (char*)p);; n4 G: [8 W- a/ M# l
    }
      X. d+ C' u4 y9 S
    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-15 06:31 , Processed in 0.413898 second(s), 51 queries .

    回顶部