QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2902|回复: 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++下的版本,更方便调试。有需要请留言
    . v6 @  S9 V' G, ^  m
    , ]$ C- Q3 x' P8 W6 P2 E/ c9 v* p2 R

    ) k" b6 H& u5 K$ d5 U *\file4 f1 Q+ x9 j' L: m
    *\brief                : _. p8 |& k( T- F6 x5 V
    *\details       
    ! k) Y5 b$ E% _6 L, _# ^8 R */ Z5 E0 _7 Q; @/ C# c3 [
    *\author        Janson4 {& G- _9 q5 X: q# [1 i9 O
    *\version       
    8 S' t; c% q" u; ~" a5 ^. B% Y *\date                04Jan12
    2 p* U' I7 Y/ O5 p *
    + z% Q6 q" v' u1 q4 S0 C9 C7 d2 D. B *\warning        : R& |' I% S) I4 T7 O* e4 M4 t- e3 s; `
    *
    8 V, z+ J  W, Q2 G' d( S. V/ R *\history \arg        30Jan12, Janson, Create the file; z& E9 M& O2 `; @; R8 q/ j! {
    *        modify from VxWorks source
    + W$ F; X( V3 C4 C* c *  Legal Declaration: it is for studying VxWorks only.. j# n7 V. r# H/ [# k! `
    */! u: q5 P/ V0 }1 A* W9 q5 X/ a
    #include "includes.h"
    + U2 B7 N7 f  [* ]) W; |* v# W- u  o! I! J
    /* The memParLib.h file is hear:9 T6 T: K2 F6 S: Q: n
    https://code.google.com/p/vxwork ... rivate/memPartLib.h7 z" Z% f7 U! E/ p4 E5 m
    */5 G* A) {: i# `" X! F3 @* l
    0 g3 d2 Y9 M, ^+ _) W8 E
    /* optional check for bad blocks */
    . C! D; G) @$ F/ s
      G& {9 i  D' y+ W4 J& k5 h#define MEM_BLOCK_CHECK                        0x10
    ; p" f% l# K  q5 D* r/ y+ I
    ) X. D% j7 |* O/* response to errors when allocating memory */+ R2 T, Y+ U8 E3 G" F1 Q) C

    4 |: H4 H2 z, J% z! y#define MEM_ALLOC_ERROR_LOG_FLAG        0x20, v- V5 D' Q* P' T( O
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    * M0 `3 }2 q% g6 H  H; }8 D
    # m) N) l9 l' J7 C( {; @" R/* response to errors when freeing memory */$ [" ?, s: f% M- M2 O+ {: m

    ; m4 t! u2 K6 C/ ?8 {; k#define MEM_BLOCK_ERROR_LOG_FLAG        0x80; G& `! |; ~, ?+ |* E  ~
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    ' D. f, {& Y* w1 d% ?% K( C4 i8 a. k# u5 [  |
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    3 v9 k1 y6 \5 S7 T, y#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    6 [9 _! \  }) Z" P% F0 a7 D6 R( n" R5 }' C- [; M
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    - {% w1 L( ^$ n. @. \. f5 V#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \, l, Z# _: f5 }8 F; `: Q4 c
                                                    sizeof(BLOCK_HDR)))
    ! p% L/ F; s; h
    & R4 r  P' G: L2 B  m! i5 V& n8 ~, X#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    + ~- N! u8 V6 ^2 [  p7 N8 ]- W4 f#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    # L6 u, ?& w$ ~2 f% o                                                OFFSET (FREE_BLOCK, node)))
    9 b$ X4 {5 z  h7 A
    1 I" p% B$ P% Y: q7 ~/ qstatic BOOL memPartLibInstalled = FALSE;
    ! t3 S4 A1 C6 q. D! `: U: {" G+ D1 V- [0 O3 y% \
    static OBJ_CLASS memPartClass;
    9 r( }$ Y9 }0 e& v& k2 tCLASS_ID memPartClassId = &memPartClass;
    4 v1 Y- V+ Y* H2 `  U
    : C+ p+ S' L+ T- u: B1 {static PARTITION memSysPartition;  x6 ^% J; L+ s
    PART_ID memSysPartId = &memSysPartition;% K5 B& A4 K, ?$ h8 `, J
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    4 k: L+ w' @4 d4 r7 F8 @
    4 F1 a) h$ Q; p  Cstatic SEMAPHORE semMemSysPartition;1 t0 r0 Z1 P! ~7 o) u" ?9 h" Q# c3 L
    1 f' j3 e) Y) y
    static void memPartSemInit(PART_ID partId);
    ( C- ]1 |& u0 g0 C/ y" A6 V
    - a, ]6 @7 |, `' G1 s4 I' [4 i" x) tFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    3 J8 k5 O# _1 R  ?* u( o# ?; h
    ) D3 q8 j: y' y. D: y% N$ ]unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;0 D6 e6 W" O6 s' ^& _  J
    + z+ X: J; i9 P6 Y
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);, E6 S* _: n, g9 L6 y9 G' k% m
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    8 S6 \  U  w5 _# b% F        , FAST BLOCK_HDR* pHdr
    % g. ~5 G) V; W# Y        , FAST unsigned nWords# ~9 R0 ^' T; [  o% A2 e
            , unsigned minWords7 l/ _  T8 G4 P% G) P
            , unsigned align);# d% x! K+ S6 w! @1 C
    # W$ L9 {" o' _, K3 t8 a! M- p& v3 g
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);9 u. o9 K/ y; s9 C$ o) N
      E# j" _5 p+ P( _: {
    STATUS memPartLibInit(char* pPool, unsigned poolSize)* Q6 A  j; w' ~: X
    {4 W6 {0 I8 b; \. r5 x/ p
            if((!memPartLibInstalled) && 9 ]. h( x3 u. G( Z1 [" p( _: h2 X" ^
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    # E: m+ g; f9 }                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))! L, F, `+ G& K: g
            {: a1 J% b- ~# m, i- a( y6 t* K
                    memPartInit(&memSysPartition, pPool, poolSize);
    " R. c' _0 A7 g1 l3 A1 t* [" h) n6 [                memPartLibInstalled = TRUE;
    . _2 C, L, |2 p, l2 |        }3 e3 L+ Z& Y' [8 i, B' B
    ; @4 i8 l8 o+ w9 M* ?
            return ((memPartLibInstalled)? OK : ERROR);
    6 }4 Q( A7 p( Y( ~0 H$ n" U}
    6 k* C" A1 Q; w0 N; s. r+ v/ T5 _" L
    PART_ID memPartCreate(char* pPool, unsigned poolSize)
    & Y& m6 {- z' x8 M1 \% N; x/ _{: X+ M/ u+ A. ]! [  x
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);& J: |+ @" I, T" m8 Y1 ?

    8 S6 p: B, W! ?' u. L        if(NULL != pPart), W! U; w) v  v- y
            {
    4 x+ T0 B: u. i8 c# n4 _6 D/ f- E                memPartInit(pPart, pPool, poolSize);
    5 k' ]* l& r- d( S  M( o" H( H. [        }
    * y+ E1 \) B% Y& \6 I/ T# e/ }# L: f: n" Y2 U' }/ X7 K6 |" S% l
            return pPart;
    / ]6 O5 r4 g' E/ ]) E}4 r: G) d( x) H, E+ n" g& c

    . _- f9 s: [# y0 t$ ?void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)' @0 X) ^% I" Z  E; o
    {; x$ I' J9 Q" E' k# Y3 ]! `
            memset((void*)partId, 0, sizeof(*partId));! g8 u: U4 A; e8 c4 A/ n

    , R+ x6 l7 q0 [$ `6 q% u" Y* Q        partId->options = memPartDefaultOption;
    : p% [  Z) A$ `" H1 i$ T# ]        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */0 ~3 r; g# X# [, v5 V8 }: Z: ~$ o
    ! c: T2 I8 A7 G6 [( Y. m% V
            (* memPartSemInitRtn) (partId);
    & `, d1 L$ j0 [6 T% B; c& O       
    . S# ^3 ?8 J3 F! O! m" X/ e        dllInit(&partId->freeList);9 d1 W$ s) g: B3 a- |  i+ u
              s' d" @' O) h3 Y
            objCoreInit(&partId->objCore, memPartClassId);
    $ C9 s( o4 d% G* A       
    / p# E, r' A5 l        memPartAddToPool(partId, pPool, poolSize);
    / {6 \, i0 v& z8 `4 u}  S# f3 s# t2 @  r8 j% Z" _$ F
    ' k6 i% `7 u# Z1 Q1 x* g$ o" I
    STATUS memPartDestroy(PART_ID partId)$ Z. J3 [/ A( P) v+ l
    {
    $ }4 z9 n4 M! e  \# l  n8 T1 H7 g+ |        return (ERROR);; V3 u7 _7 l. I
    }& A& K. g: v$ ?5 m6 Z0 M) V1 G
    + c2 w$ U4 Q$ Z$ k2 s
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)+ E" i1 ^' m9 M  X
    {# x/ H& }4 U( S+ d3 S
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
      q" }/ N3 Y( \9 V! {$ |$ b& l3 O}9 }- s( u/ @$ Y6 o! @- ^5 `, Q
    & y& f$ Y: _4 Y  C* M
    # Y( V. Y7 q" t/ {
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)! x5 J7 a0 ]8 V: ^" A4 p$ y1 o
    {
    - k" T8 G4 R) b# F        BLOCK_HDR* pHdrStart;. @' c. F& u! s, e  o
            BLOCK_HDR* pHdrMid;
      H. o- Q' P# o; Z! P# F        BLOCK_HDR* pHdrEnd;
    9 U6 u7 G) @8 F: w1 [% B) k* O        char* tmp;2 m6 I2 I- W. @0 y
            int reducePool;
    8 k: ^0 K7 U7 z) C$ p/ r& s- t1 T: I+ R" O. d- d6 J
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */: o" U5 Z. H6 K: [
            {( |) Y0 i4 k( H, y  G0 K0 `2 X
                    return (ERROR);+ z4 Q: ~( X# `# k
            }% S/ c" i, S1 ?" a1 z+ M' d# }4 k

    " V, Y3 @6 t0 }% c1 M        tmp = (char*) MEM_ROUND_UP(pPool);  H& J5 B* R0 X9 I" e
            reducePool = tmp - pPool;
    7 E- k! d) n, Y  f& D4 t& `+ L) U# [0 R
            /* adjust the lenght */
    % h6 r' R, ^7 z7 C& Z% B        if(poolSize >= reducePool)
    1 @9 J- Q; T0 o7 C7 i  L        {
    ) A+ r% F) ]' Y3 E; f8 y                poolSize -= reducePool;
    : E5 l$ O. \8 \& x        }
    % o& v' ~( {2 u' \" ]8 C        else
    5 C; A2 e8 a: d( o8 a        {
    $ s; R( E" K; ~                poolSize = 0;, A. Y0 d' A' S( I5 J8 s- d% ?
            }
    4 _* @: ]  `* h' f7 Z        pPool = tmp;
    % K$ }: c& \* E: y          @$ \! z" H- \) K3 s( s
            poolSize = MEM_ROUND_DOWN(poolSize);
    ' Q! d- I/ o& k6 `9 H. K, Q7 e5 R3 K        , H+ V9 ^; u3 h/ P
            /* at least one valid free block and three header blocks */
    6 V* }, Y+ f; M, P5 v. O        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)& ?' |9 h$ F5 D
            {
      A8 f, ^1 q5 h* g/ U1 s( Z9 [                return (ERROR);
    ( p  i7 R; L. h+ \1 k        }! G. ^$ m! O, ~% ^8 n
      N  Z- V9 n) s8 x# d! h- \2 N
            /* initialize three blocks */
    5 r+ ]$ i1 X( {; B+ ]' b        pHdrStart = (BLOCK_HDR*)pPool;
    ( q5 ?. D$ t  E( Q; _9 H. m        pHdrStart->prevHdr = NULL;
    / U  a! X: n! [; i. H/ @+ y        pHdrStart->free = FALSE;                /* never in use */
    ' w; H  f# D6 G9 _        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;% E5 g# _. q1 j# C* {, G

    & F3 r. a- p  F: l" s8 y        pHdrMid = NEXT_HDR(pHdrStart);
    % o; m" Z, ?2 n- `" D9 U5 y% X9 k- h        pHdrMid->prevHdr = pHdrStart;$ L; [3 Q; {# Y( y$ A
            pHdrMid->free = TRUE;                        /* the main block */% T7 g# t- O1 S
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;: ~9 |% b+ C  {1 Z

    / Y8 u; Q: y: i/ W3 ?        pHdrEnd = NEXT_HDR(pHdrMid);) @7 S3 {  B% V
            pHdrEnd->prevHdr = pHdrMid;% ?) _6 ^8 a# G  h
            pHdrEnd->free = FALSE;- s" X2 J: T" o' b# g/ n
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    8 l$ D0 A8 a" j$ n- U( g' I( M' D% j$ D
            /* TODO take sem hear */
    . f  `, f- C5 r8 `' k5 e6 X        semTake(partId->semPartId, WAIT_FOREVER);( g+ S9 x- V7 J# D7 _
           
    . d/ {% F4 c" ]7 e        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    7 U5 A! o9 E, g6 L( J        partId->totalWords += (poolSize >> 1);4 |2 K$ g* R; x3 p9 J1 ]
    - B% B' M7 w! y% {% a" Z
            /* TODO give sem hear */" Q3 v: A" p$ n
            semGive(partId->semPartId);
    0 N' i- s3 X6 |) h/ K4 ~# w1 Z& g0 x/ o
    2 s$ b9 s% n) Q" ]# y
            return (OK);! i' M! E/ k. K# A# W
    }
    ) n9 M! S, C7 D5 S1 k% N7 q3 i! _: f/ g$ _; ~1 K. e2 I% S" x
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)$ c/ x$ }- W5 w2 l
    {6 c/ l/ Y, }" y5 M) R
            FAST unsigned nWords;
    4 }- M3 v) }* l' C: N# K" s, P1 z. {% `        FAST unsigned nWordsExtra;
      w" z5 \" x: _! }1 h        FAST DL_NODE* pNode;8 U# Z  k4 m. X+ x' K4 U
            FAST BLOCK_HDR* pHdr;
    + `0 K% o. k# i        BLOCK_HDR* pNewHdr;  @/ M1 j/ _/ ^
            BLOCK_HDR* origpHdr;
    % s9 F' g9 ?- D1 o% S6 g; l  }8 t* p  G- D% p4 s
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ( c* F4 f9 T- ]5 r        {
    5 c* T. j3 e. I, `3 T6 G# [* ^: j, ]! m8 N& v                return (NULL);6 z3 {( K8 P' n) _& f. U/ A, o
            }. N8 t& ]# T; \) {0 d1 D5 o
    / q, r9 r) o7 ], F( N' g8 ~+ A7 d. a
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    $ [9 C! k) J6 t( ^* W4 ^9 k- k' y+ g) |' ~; q
            if((nWords<<1) < nBytes)
    ! {  C9 n: H/ z# g; o0 M        {
    ' I: v% D% g/ ^7 ?4 r; b5 J                /* TODO suspend the task */) O" R2 q- Z# ?- P
                    return (NULL);8 e- k! d, l/ z+ h
            }
    " |/ I' v0 k) K# H6 O3 I# e; g/ p
            if(nWords < partId->minBlockWords)7 N0 Q1 z7 D# {, l& c5 x
            {9 m) Z8 d" a( }) n% {
                    nWords = partId->minBlockWords;) W8 d) u! E+ e
            }
    & l% N0 H8 h$ ~& t- u( Z' ?  L
    ; I$ a  t  \4 H2 s$ y        /* TODO task the semaphore hear */7 S0 [6 U0 q1 j& B: u2 [* c; Z
            semTake(partId->semPartId, WAIT_FOREVER);- R1 u3 C2 a* I: _0 G
            pNode = DLL_FIRST(&partId->freeList);
    9 }) z' y" p  m, q        nWordsExtra = nWords + align/2; /* why? */
    ! i3 [6 `1 D/ B  j
    / V' E* b2 |* I+ @! D        for(;;)+ N* f* I1 Z5 R
            {
    / U( E  N+ t4 G0 ]                while(NULL != pNode)) q( [8 R: Q+ G8 T& V/ |! Q
                    {
    ' w9 l' ~: Z# F3 J* Z1 E- E                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||; N# G! R; j3 D% N! |, R
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) &&
    3 B+ y  X, E! \/ D7 A1 O' q                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))), _' S: Y& F3 W7 C
                            {
    % ~8 t5 y6 x% v8 V2 c0 n, f& E                                break;
    % L" I! [" S, H                        }2 \: F3 r' Y$ U, J2 R$ J9 s
    & \; h# T! x, T2 Q9 i. S
                            pNode = DLL_NEXT(pNode);
    ' X4 _$ s2 p& ?                }, [/ F0 i8 I# M0 Y0 ]# N
    ' |& V' E; E0 |; @) Y' g. Z
                    if(NULL == pNode)
    9 C- L' \9 {' h4 l                {
    . x( @! D# v. e( A% `                        /*TODO give the semaphore */
    8 j9 f4 P3 T+ K9 O$ l                        semGive(partId->semPartId);
    ! }1 q/ [8 m- R% ]* ]                        return NULL;
    7 x# @  C2 f$ y0 c                }
    1 s9 G6 ~9 p9 u# K# C9 ~* N4 @9 F5 {! ]% Y0 o/ c" E2 y2 j
                    pHdr = NODE_TO_HDR(pNode);0 m4 B! Z5 i! ~5 ?7 g! ?+ I2 _6 y
                    origpHdr = pHdr;
    2 B, p1 _0 V& ?& C4 j
    " h9 E+ q* r3 m7 G( H( @$ j                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    ; I0 V# M6 @- R0 O- ?$ d% _                if(NULL != pNewHdr)
    9 O; g& C2 e1 m' @2 R                {. l8 F- k% y5 p1 [5 ]6 N. H
                            pHdr = pNewHdr;
    ' E/ ?7 k7 T2 X$ E- D9 u                        break;7 `  A: c1 s$ \4 I3 n5 x9 v
                    }
    + ?! w' h8 A0 w; T1 O, C
    ! `4 y# s$ O$ K! V                pNode = DLL_NEXT(pNode);
    3 |& {9 Y, j  w3 Y7 @3 B! k        }
    % M& V6 {1 N2 V. Z  Z  ]  _
    , i7 Y! F8 q. O; B        pHdr->free = FALSE;' k! p. q2 t2 O8 Z4 V! U
            partId->allBlocksAlloc++;
    4 D# z1 U# }! {- R/ N4 l, M        partId->allWordsAlloc += pHdr->nWords;
    2 m6 u: I/ z; ]0 E) x6 {- j        partId->curBlocksAlloc++;) i( X; @6 m0 E# c% [1 P
            partId->curWordsAlloc += pHdr->nWords;
    " _" W* v+ J9 }0 x) O2 C: F' U/ k9 N  o0 \
            /*TODO give the  semaphore hear */! |! a7 P; |$ o3 O; c% O/ T
            semGive(partId->semPartId);- A7 z" O( x  T  i' A
            return (HDR_TO_BLOCK(pHdr));7 b0 ]# N2 q0 p+ Y' N# E" M
            . d' t: e4 p  V7 `
    }
    - j/ p" Q! u& F8 Y2 ]' Z7 D9 r
      C8 `% f+ w2 S7 l- X) ~, zvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes); m2 A9 Y, P1 o1 I. k8 d. X' e7 U
    {, ~2 ]4 ~6 Z: n' s) I( \* z
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    ( H3 W" x; d$ Q1 t: v+ [}
    " N8 T3 h- H( k3 B& r
    * E+ D7 _' o" P% Y  |STATUS memPartFree(PART_ID partId, char* pBlock)' K) e. n% P* x: k
    {. t4 R2 K4 J; n& K/ s9 `
            FAST BLOCK_HDR *pHdr;
    6 k! o% n+ [( ?7 p* N# c. ^    FAST unsigned   nWords;3 e  k7 Y. K; M3 o, W/ }
        FAST BLOCK_HDR *pNextHdr;
    ' i/ |. k  J; N( x) ^9 H! A# x( ^6 E' ~
            if(!IS_CLASS(partId, memPartClassId))
    7 F* |6 M7 \) U- Y3 ~) |0 n8 f6 B        {; @; b4 o" t# B1 }
                    return (ERROR);
    & R! G* s- F' J: l        }
    % @1 F4 q1 P0 F. `; G& L
    ( R% P, \% m4 [+ @: D5 B& ?        if(NULL == pBlock)
    * M4 C+ ~% L, [% t% y) x        {1 E8 ^3 u) M+ D7 b7 G: R3 i
                    return (OK);4 p2 y  G6 Y* v
            }
    8 Z( m' I* V6 ?2 N' g( L( _
    ' Y4 ^3 A2 W" V        pHdr =  BLOCK_TO_HDR(pBlock);
    : U1 K  `* U8 p3 }6 |; F8 C" j! y9 a8 F! i. L! @, F; g0 v6 i, w
            semTake(partId->semPartId, WAIT_FOREVER);3 ~& I9 o4 m% |" k2 E; U( ]2 d
    / m7 L( T' p4 ~, j! G& u8 Q" Z& b
            if((partId->options & MEM_BLOCK_CHECK)$ ^5 Y0 n# S* V1 c2 `; l7 Z
                    && !memPartBlockIsValid(partId, pHdr, FALSE))
    ! `0 e/ Z$ E4 `) V$ _* y8 B        {8 w+ o& Z3 h, J! {4 I  G; g% b1 ]
                    semGive(partId->semPartId);5 B. N* @' h" b6 y
                    return (ERROR);" q* z3 d) T! k8 ?& P9 i( J9 W+ S; O
            }
    9 p# J$ Q9 t' P3 ?
    7 x6 p; j4 b- l- M$ H        nWords = pHdr->nWords;
    ! X3 y, p* W0 M3 Y        if(PREV_HDR(pHdr)->free)) [9 B1 p4 ^7 w
            {/* the prev hdr is free and than coalesce with it */
    9 v' H9 U# F* n                pHdr->free = FALSE;0 M& U. L" i  [2 ]. f
                    pHdr = PREV_HDR(pHdr);3 h  B, G  t5 Y, S9 Y; u
                    pHdr->nWords += nWords;# x3 N+ w5 M% S/ D8 p0 H7 k8 i  g
            }* f- s6 }0 X/ j
            else, |2 D1 q2 ]# D* y
            {! y( I' w. S2 v. y. u' g4 U; L* K5 x
                    pHdr->free = TRUE;
    8 o$ D, a. M' M' n6 S3 ?                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    % z" E" P0 F* [1 t: T0 [        }" z8 L" s$ a" |# ]) H
    4 A: {5 l: u/ h3 n' t# c# d
            /* check to coalesce with the next */
    , E4 R( w4 X+ T; g1 _) N1 D0 @  L        pNextHdr = NEXT_HDR(pHdr);
    - Y! A6 m7 X8 f( C* S7 q2 |8 E6 z0 I        if(pNextHdr->free)
    2 p3 o, A, A: _( N) j( ]; _8 c" N        {, [, ]( j! F6 Y: z# @* ^1 v9 I, Y
                    pHdr->nWords += pNextHdr->nWords;* a4 J7 R, U* r- o
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ! B0 f3 X6 m; T        }
    # S0 ^' O  s. a
      T4 W% k1 r+ A5 e, v$ {9 B3 y        /* cannot use pNextHdr->prevHdr=pHdr hear */
    / C, \& A9 \0 a  R0 {        NEXT_HDR(pHdr)->prevHdr = pHdr;5 S7 X' E! u% z# a) l# q

    - C/ `& w. Z& S/ F8 Z3 |        partId->curBlocksAlloc--;7 k  e  u6 T/ s5 U1 S/ m
            partId->curWordsAlloc -= nWords;; N  g/ L: e0 `! U" H  w6 _1 P
    % m+ Y& _& n) O7 |, c2 [2 @! c2 S
            /* TODO give sem hear */# f3 X2 R3 K6 b5 m$ z+ z9 x
            semGive(partId->semPartId);
    0 k& }# k/ @: S' D/ Q/ `' _5 D        # x* ~/ y5 y& c( b
            return (OK);
    . [  _  \- A1 r2 C}  N1 @, e3 g/ W( j% k7 u3 u

    ! n! `0 H$ ?+ n7 Vstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)( y* U/ t% t: Z! X: P' D0 L; s6 a6 h
    {
    + C2 E* T7 l- W        BOOL valid;5 y2 O1 @2 K0 h- k5 t: I
    : G: ]# J4 l) g- ^
            TASK_LOCK();
    2 P& |  I4 L9 G- Z% d        semGive(partId->semPartId);
    # k( _4 R: L& @  {        8 @2 l' a$ v1 ]; {
            valid = MEM_ALIGNED(pHdr)
    : S4 Z, \; K1 E" U" u1 I        && MEM_ALIGNED(pHdr->nWords*2)) E" b% r& j' O. J; {
            && (pHdr->nWords < partId->totalWords) 6 D6 S5 A7 L. i9 z
            && (pHdr->free == isFree)+ D! c; U/ H9 A# ~' b
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))* }6 o* s3 T* k1 m' [
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));. Y" N  \8 V8 J8 Y# M2 P; J# l
           
    # Z& m; k0 O5 V% r& K        semTake(partId->semPartId, WAIT_FOREVER);8 d/ b) v! B$ e' S0 z* h9 T
            TASK_UNLOCK();
    # V1 [7 B0 L* @
    / z9 V: c$ S6 [, y# l$ N3 c        return valid;3 {: n! E, n1 i/ P  V( k% _
    }) Y% Q2 P' n  D0 Y5 l, @

    , v2 x$ ~" C3 Y3 R$ H- ?/ u4 [$ Z- hstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    1 q+ r4 ]" ^0 p" P# e" n) [$ h        , FAST BLOCK_HDR* pHdr# H  z/ j6 Q& A8 H. T
            , FAST unsigned nWords
    2 W- f' a" N6 U4 o, o- Z7 }# e+ a2 [        , unsigned minWords( i4 x! U" p* s6 v5 r
            , unsigned align)' ~- p5 L4 t+ D6 F+ R% X/ @$ O% Z
    {( ]; C1 b. T5 V
            FAST BLOCK_HDR *pNewHdr;3 B' S' @# v  I9 K6 ^& b
        FAST BLOCK_HDR *pNextHdr;( c- X9 \+ S0 Y$ w/ x. q
        FAST char *endOfBlock;8 _, \+ Q- o  v7 b
        FAST char *pNewBlock;8 c- Q5 w6 p! b+ F
        int blockSize;) _0 t+ [4 s7 R# n' Y, ?

    # y! z0 {3 E* q3 a% W# `        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    * P6 H  X2 T& n& P3 B+ {. j
    : E+ M9 @& l/ J% r- o        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    " ^) F. N+ b' ?4 d8 v' T6 Y3 F, A9 M* Y
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    ' w' a/ y" n* i' R
    ; Z$ h- g6 `2 i        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    " }) g( A5 ]/ A5 G, H' c1 i# N" b; i+ G( x
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;2 K7 G8 E, h3 \  A% z& O! b: W
    2 b# C. e' v6 `* S$ Y
            if(blockSize < minWords)+ ^/ X; x* Z: T( p
            {% p0 w* R" ~. O" r: s
                    if(pNewHdr == pHdr)- U4 {5 }4 b0 G: }6 ~8 ~
                    {3 z8 t/ K: V# L3 a. p! A
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    ; c$ q/ V3 @& E, k                }
    " P0 r9 M8 J6 ^" l; h4 R* |                else( H$ E* m$ j! {4 |  P
                    {
    5 ~; O& y" K* E' U                        return NULL;6 t( d( W3 \1 L8 D7 n3 A- h8 s/ A0 [
                    }6 C% B# Z4 D6 a7 a
            }
    9 F  w( T3 D+ ]0 ^        else
    $ Q8 S# Z9 e0 ]3 G        {        /* recaculate pHdr */' n7 B0 t+ L& F
                    pNewHdr->prevHdr = pHdr;% |& a7 L' x0 i* x1 ~, |
                    pHdr->nWords = blockSize;
    0 J1 B, C% D/ E        }# e) u4 m( f- B0 V9 y  Y; s6 q

    , T& y: Q9 k1 |( O( ^; x8 G8 N        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ' q3 b# G! ]( M' w6 r2 i        {
    ) i* M5 _; H0 s( Q% d                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    6 ~1 `" {$ [$ F5 t                pNewHdr->free = TRUE;
    / A5 R  L2 O  U$ y: f$ N9 P; }) h; k. d& d% o( Q  S, B5 Y6 S4 B
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;' J4 y0 M$ z5 D: {3 F% z. g! u% G% N
            }
    % h4 U9 o* H) d( G" @' u! o' ^& |- S        else9 i4 w7 V( @- b* Z% B# E" z
            {/* space left is enough to be a fragment on the free list then */
    6 Y0 k0 N' f5 Y2 c                pNewHdr->nWords = nWords;
      |# M- `3 _) X& o3 y) {                pNewHdr->free = TRUE;) P1 W( r, y4 ^
    % J2 s, P/ h/ g; S8 z
                    pNextHdr = NEXT_HDR(pNewHdr);
    & @0 e. f/ q% n% P6 Q0 [                /* words 包括BlockHdr */; D7 f# R1 w7 [' k5 Y
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    % \/ y% k" _/ ~5 y                pNextHdr->prevHdr = pNewHdr;, ~; ^4 V2 F) ?0 e" W
                    pNextHdr->free = TRUE;
    # A% y+ b5 ^2 q
    ; T# ?8 S# k, B                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    . J& f# K/ S/ i3 c& o1 {0 m( c# U7 E$ C- d" y
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;6 B! g+ U% y* {$ u+ }8 P- m
            }
    ; l: G  A' k( C3 @: R
    4 d, O7 a5 ?1 x0 F( O2 u5 n        return (pNewHdr);# n' R0 h" ]$ |: b
    }! [3 G0 Z0 T! g2 k  f+ l- [

    & O: j" v& L! l' ]static void memPartSemInit(PART_ID partId)
    2 z) ]0 W: Z# H; V+ `9 ]* p  `4 Z{
    7 o- }7 Q, _$ X+ U        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);; ~+ _( [2 C. Y* e

    1 F9 `- S- D$ v% `( O: K" n" Y        partId->semPartId = &semMemSysPartition;  m' ]. ]5 r9 Z
    }' U3 j) \! h8 K2 T4 {6 e3 @
    ; B9 m+ Y7 N. G& ^$ c3 q
    void* malloc(unsigned bytes)' j& k. S: u2 R
    {
    " l  i8 o6 x7 }        return memPartAlloc(memSysPartId, bytes);$ ?, t' \' P% ^6 a
    }" v; `& O5 c* U7 d0 Y1 J

    7 ~2 v% w+ d0 D, _& e, bvoid free(void* p)
    4 X6 s% x5 h# c{
    6 o  c# v- }# }& S( E& w0 E2 p        memPartFree(memSysPartId, (char*)p);) S; {  |2 P) Y7 k% H
    }4 u2 m2 f6 [7 k4 \
    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 05:46 , Processed in 0.837937 second(s), 51 queries .

    回顶部