QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2886|回复: 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++下的版本,更方便调试。有需要请留言( b) r( Q) @  S( w$ R/ W* c

    ( Z; [3 o6 s. m: p5 j( |. K
    8 M7 D' ~2 k6 O5 W2 t! W
    ) W0 g- d1 n$ M) i *\file$ w5 ]2 A$ o  w: {' X
    *\brief               
    2 M; n% X4 Q, Y. m9 j9 ] *\details          h) ]) U9 H1 K2 K% P
    *! q5 ^+ u9 h7 C3 y
    *\author        Janson1 i) [* o& A9 R# |, p
    *\version        & W: _" j: [+ ^! ?  ?. P, H$ d
    *\date                04Jan12
    ! ^* H6 ]& u2 H1 v- Q *
    6 b4 u# _' Z( S$ G* r; c  m( P *\warning        9 X4 q6 E5 A' g2 v7 h. g
    *8 x% p3 R9 w8 q' a! M! F4 A
    *\history \arg        30Jan12, Janson, Create the file8 l' h* k0 s/ r/ e
    *        modify from VxWorks source
    , d5 }! L; V- _  }8 z. F6 D *  Legal Declaration: it is for studying VxWorks only.9 H- i, r+ z. r" B( o9 O
    */5 L4 l9 p; ?6 q9 c' P
    #include "includes.h"3 D6 ?0 ~) g; u4 p

    , K; s" w. c+ Z0 {8 S$ |8 P/* The memParLib.h file is hear:
    0 f8 o3 H3 a) o/ U0 thttps://code.google.com/p/vxwork ... rivate/memPartLib.h
    0 M& t, y$ K2 p- _$ ]; q*/; S. R' ~3 U4 o0 N" L6 k$ r% v
    - {( D/ S! X: F
    /* optional check for bad blocks */% p1 b: \- D' ]+ s

    : C* P. Q' i$ s4 D#define MEM_BLOCK_CHECK                        0x10' v1 ^; @9 K# h& Y5 E4 a
    1 A/ m. A/ N1 Q/ {" |
    /* response to errors when allocating memory */1 p5 w3 e- h; g- y* C7 z8 @) R; |

    $ [# l( O( A2 m% A9 D#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    4 [% S$ y7 `' y0 l% [) T#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    / H. _6 \/ R$ w( q9 ~: k5 I2 @3 I. k0 X0 E$ |: J+ x# x) y: m
    /* response to errors when freeing memory */  K2 g% p, R* H6 t
    # J/ [; e% q/ I' K% I
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80- U  T( d2 [# x1 o
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100/ y9 e9 o. R6 ]; P

    3 I: K9 U$ U' s! s5 Q#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords))), K4 y0 E, h1 G5 R0 {9 i
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)2 b% ]3 x5 `( P& O& G% E- Y" _+ y

    - y1 a, o/ V" t" n/ |#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    . `0 M8 i. a8 b! q/ }#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \! v) |5 w& P; r9 m
                                                    sizeof(BLOCK_HDR)))
    : [: e; t) W* Z6 Q# @+ ^8 o7 G* |& |# B0 V/ B/ w# f- R/ u
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    / G$ x6 f1 i8 C) e, L; Y#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \3 }7 W/ f  k1 {& f& G
                                                    OFFSET (FREE_BLOCK, node)))+ l, w" R) n& t

    1 ]  L5 `+ E( I4 I. ^& _( Xstatic BOOL memPartLibInstalled = FALSE;
    2 I$ E9 w7 \- E" W- M/ ]1 W3 R+ N5 b6 H% g( ^0 t! k
    static OBJ_CLASS memPartClass;8 j* j* M4 X% L+ Y: G# G, w
    CLASS_ID memPartClassId = &memPartClass;) B) y: \8 K& Y- k

    : V2 h) h) m' q6 }% @* ?2 Tstatic PARTITION memSysPartition;
    % y: {: p9 A4 L) Z. B( T0 U; B: TPART_ID memSysPartId = &memSysPartition;
    , ]4 c% ?3 `: ]" g: H" UU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;5 W5 o/ {1 p  Q5 i/ }: @: Q
    7 T1 p8 z- ]; j
    static SEMAPHORE semMemSysPartition;
    # c5 n/ w; x" h  p' z% V0 o+ q( |; U" M1 J& F
    static void memPartSemInit(PART_ID partId);2 }- ~9 ~+ ]+ y2 Y3 `4 `# {
    , i2 t2 ?0 T& Z9 t! E8 d) s& ?
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
    ! J- }4 x+ g* j/ J: F7 e
    7 Z. [2 T4 w+ V0 V. }unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    2 M5 Y% C; z/ z0 c2 y# b; k- [' V% b2 r
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);/ q* f: d$ T! b: t. V
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId1 z$ z5 f3 a0 j% [# C! d
            , FAST BLOCK_HDR* pHdr
    - c% m- j2 M; j; w  b0 Q: }1 H9 n        , FAST unsigned nWords
    ! g9 U1 C9 l8 V) h' J, W) R2 o' I        , unsigned minWords
    4 q+ N* |8 R6 q+ Q        , unsigned align);
    . N1 H* b, q6 b; f
    : d& X& w4 b3 i' B: G$ U' rstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);( v9 q& a- O# V. e& o3 J* e# _

    ' ~. M4 W- f; E. F( `  `& }STATUS memPartLibInit(char* pPool, unsigned poolSize)0 O9 [6 [+ ]0 b# w: i" X
    {
    & N$ Q% U2 [/ P; a' V8 n        if((!memPartLibInstalled) &&
    3 y6 h+ U3 E# `2 J! |                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)4 d& c. Q" k8 |) X. ?  ^0 @
                    , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))1 u) F3 P. i; s* c7 m4 L+ @8 q
            {
    " `3 P5 t. Z0 g1 u                memPartInit(&memSysPartition, pPool, poolSize);/ w; c* @# Q3 |
                    memPartLibInstalled = TRUE;4 H5 F' N: _6 E1 i
            }5 V* n, \5 H' m8 F9 A' ~

    - p2 o  A% ]3 S0 L5 K: s! B" s        return ((memPartLibInstalled)? OK : ERROR);
    # G' O8 O4 {# w$ A0 N) _}
    5 _/ Z" }# |3 P$ i7 y: R+ @% p0 M* B  q- J  r
    PART_ID memPartCreate(char* pPool, unsigned poolSize)3 j0 h8 S$ d5 u+ D% V- G
    {
    8 b  W7 F; D( f7 [) _* t1 F1 C        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);/ f3 m3 P8 h$ Z3 x* |
    * D- I1 @) S$ G* `* s
            if(NULL != pPart): F" @  M3 d6 `; X& D5 d7 u5 l; {3 {
            {
    % O! O' H0 t- c* u0 n  e/ Z' ~& {  F1 Q                memPartInit(pPart, pPool, poolSize);7 L& ?+ L) h* ~$ ]( z+ V; m( Z
            }6 ^; K% e$ R/ M, z7 C' U

    ; i9 s0 B5 C$ h        return pPart;
    % h* R+ r2 C2 B$ Y}
    % p( W& c3 N( U! ~% c/ }' [( {" Q* N; T" [9 o/ s, D
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)4 |7 {) g& V5 K( {7 }' b* F
    {' N0 \( H4 N+ ?3 o' V# S0 y  @
            memset((void*)partId, 0, sizeof(*partId));
    ' f" K1 o+ x8 I- V' |$ ]
    0 a* t" Y9 ~+ X& T- V        partId->options = memPartDefaultOption;
    + B) d- M$ i0 r( j8 I& d        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    / y5 f& u0 b5 |. ~  H, s6 I! i
    ' e/ o: c8 r' ?" ]6 x        (* memPartSemInitRtn) (partId);
    3 @% W  d4 d4 B7 K; |9 n1 z6 E- S        9 _6 p  Y+ t* w, }1 x5 z. Z
            dllInit(&partId->freeList);
    $ ~( A* J9 J2 J9 f5 `: b2 v3 Z: r2 a8 U        2 p! M0 c8 f7 `) O/ S  k
            objCoreInit(&partId->objCore, memPartClassId);- r5 B0 P2 m, w6 N$ E, F* |& g2 z4 @
            9 J1 V' `5 P# n" d
            memPartAddToPool(partId, pPool, poolSize);
    2 o; J5 V, x9 t: g2 a}7 y! E6 Y8 o7 X0 M
    % C; W/ H) c) \
    STATUS memPartDestroy(PART_ID partId)! W, Z) E6 i% V" x& `( f* _
    {
    2 a! F; i# n4 a0 |1 P6 a0 K4 ^5 v& y        return (ERROR);
    : z( `$ P7 e" ?- ~}3 p; e( J: Q  N! g

    % f$ F8 F6 Y9 M3 A1 Uvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    # Y* S& O, Z6 x! O( G. P# v' R{
    , Z4 T  Z0 t# ?' i2 b    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);1 m2 q6 a2 \) L+ ]! N
    }
    ; e+ u+ X4 F% A8 k# L: Q5 f# ?. \/ \; ^8 b

    / X' |" J2 d7 E# lstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    , M* c3 S' |$ K/ k1 `{
    & b% E6 `9 s+ ?! T) k        BLOCK_HDR* pHdrStart;' z/ W' ]+ Y/ }1 Y4 J
            BLOCK_HDR* pHdrMid;! T8 p! F6 z8 g5 H, ~
            BLOCK_HDR* pHdrEnd;2 H. ?5 c% }  ^; U
            char* tmp;* C% |  \; s7 E$ @9 c* L7 Q
            int reducePool;5 b. A2 ^0 j  ~- Q

    1 |& u1 s, z: h        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    1 N4 M2 y3 u! j1 X- ^6 O7 }        {
    & B3 Z$ w9 k- S9 @; D6 j/ B                return (ERROR);& E! Y  }! p) ~- m
            }8 {/ W* _( |: W& S# m9 d% c9 Z# Q
    % [) I" l7 w$ y# s6 C! x  R8 |. F" n
            tmp = (char*) MEM_ROUND_UP(pPool);
    9 _$ ^: a% t% ^0 x* J% v0 \        reducePool = tmp - pPool;3 {  C& e1 @! N1 Q8 q1 K

    9 l" Q) p3 N* _$ D# N) z" M1 k        /* adjust the lenght */( M! e! q* l5 z
            if(poolSize >= reducePool)
    % v  \5 n; s5 i4 j* q7 {% Z        {  c: g6 j: J8 j" b1 Z
                    poolSize -= reducePool;! O6 {6 p* z& S$ I6 `7 }
            }
    9 s5 @3 i" @+ z3 m+ s: C        else
    + a% e8 {5 Y0 Y# L        {
    % {) I' n3 D# r3 u% v                poolSize = 0;* `0 d& t3 Z, Y9 s
            }2 {! {% R9 N) y5 x" X
            pPool = tmp;
    3 M9 W  t# M/ P# q8 {        $ f0 k- h0 p9 B
            poolSize = MEM_ROUND_DOWN(poolSize);  {" z* e: c) m$ g$ b
            3 I# O2 {0 |- B8 a+ ^2 Y
            /* at least one valid free block and three header blocks */* Y7 r# i6 ^$ b: v4 c
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)/ i8 P6 s- ]0 }8 k6 s
            {
    # e, {4 o# }6 d9 Z                return (ERROR);
    ' C) h" Y# }' s        }
    7 L* H7 ]9 c. \+ b
    # F' F; m9 a2 m8 n$ F; k* n        /* initialize three blocks */
    4 ~8 m* C  ?. p  A5 f: F. {        pHdrStart = (BLOCK_HDR*)pPool;7 I' K( N( J6 g" u: D# W* k
            pHdrStart->prevHdr = NULL;- O% W& L4 O+ f; X5 _$ M) w/ E
            pHdrStart->free = FALSE;                /* never in use */
    ; n- v3 ]& ?2 f7 E        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;+ `; S  M7 K& m+ R. `+ Z# y
    3 h- c% b- U+ w/ V" f
            pHdrMid = NEXT_HDR(pHdrStart);
    - V. J7 l4 w& G        pHdrMid->prevHdr = pHdrStart;5 d# {. I; L6 ?# Z) Q9 g6 N
            pHdrMid->free = TRUE;                        /* the main block */
    4 L7 @( g& B$ s) q+ D        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;* Y* b# b9 s5 }" T

    9 {7 W* ?* o8 `2 N/ u  e  G1 h        pHdrEnd = NEXT_HDR(pHdrMid);/ r' [6 [$ Q  D- H3 V$ A
            pHdrEnd->prevHdr = pHdrMid;5 T* P. `' N4 E2 p
            pHdrEnd->free = FALSE;# f6 I! L- O8 s* L& }+ Z
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;% w% J# \7 I  a9 g9 ^0 E

    ' S* H" z( K6 v- V+ ]) [' w        /* TODO take sem hear */
    " {2 I- i9 X* n: S/ R        semTake(partId->semPartId, WAIT_FOREVER);
    & m( B4 ^3 p+ q8 G4 P       
    ' _3 N4 q3 T8 V        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    / G3 W4 X6 E+ u- n6 M7 m0 i- X        partId->totalWords += (poolSize >> 1);
    ; C5 O. k  b" ]- y$ z- |1 g
    # ?8 q* s$ t) {+ ^* ]/ b" X7 V        /* TODO give sem hear */! |! {: y" v* A) T9 Y( w1 ?! X
            semGive(partId->semPartId);
    9 N$ _$ Q( A. p$ ^- t; i% M: _5 J( ?8 ?9 u8 ^. H/ I

    * t" z- V+ C* b# v6 d9 c        return (OK);
      Q* ]" D; h: Z2 O* a0 I$ Z}* g; N9 O4 t. v' n; `+ D
    # R! i% u; ?& D
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)6 u- M; E, j1 X9 P: E0 j: l- P
    {7 V, \' x  ~, {' N, W
            FAST unsigned nWords;
    ) c6 t0 c' D' b0 L3 v6 x& v        FAST unsigned nWordsExtra;/ l# U6 U/ I, i6 O
            FAST DL_NODE* pNode;* W4 C+ [" S  H% W) t3 U* w
            FAST BLOCK_HDR* pHdr;# [3 ]- F; z) [2 {/ ~
            BLOCK_HDR* pNewHdr;- I* r* d$ l6 n- ?5 ^9 z9 a* d
            BLOCK_HDR* origpHdr;1 w3 z! s# ^- w8 ^8 ?' [
    - R: w7 l7 [! r$ c8 M( M
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */' F2 `( t  S" j, [; V
            {
    - p) d# n: t9 I9 o2 _3 B* s  F                return (NULL);) R% n: u. Y6 e7 U9 L. i
            }
    7 j# S7 u+ a4 W0 e% c  j+ |% _: w$ v( `6 }5 x# I" ^  ]; Y; A% C
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;# H: d+ p! s  Y
    0 G/ F; v7 D( H5 h
            if((nWords<<1) < nBytes)
    9 l5 M2 v5 k7 T+ w: J, T        {9 k+ Q1 n/ e& A* ~: w
                    /* TODO suspend the task */2 L$ z3 C7 M1 C  D9 H2 _! x  }. p
                    return (NULL);
    2 r  [+ ^1 @7 d        }
    ; q, d6 l' g3 v& Y# S8 B2 J3 B) t, X% A- ~
            if(nWords < partId->minBlockWords)- c, a. i, M" |9 G4 b" w
            {! p. o8 w. _5 h
                    nWords = partId->minBlockWords;+ |6 z! j( q5 W" t  u0 b1 ~8 `4 v
            }
    # h; P5 S; b% D8 h, e: ?- e; J3 h# Q) O) x
            /* TODO task the semaphore hear */
    + c( W8 U: Y5 Y2 W# o( G3 M        semTake(partId->semPartId, WAIT_FOREVER);' q  h4 s1 @7 F( u: O. T
            pNode = DLL_FIRST(&partId->freeList);8 o( {3 z4 m9 |; i$ e
            nWordsExtra = nWords + align/2; /* why? */$ [$ r$ l. M/ o% R  [
    % M  \2 b% Q2 O, \
            for(;;)
    1 P0 Y" o; ^' y        {
    / }& X9 {. U; n                while(NULL != pNode)
    3 ^2 g% P+ F/ v                {3 }! u: m$ {/ z
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||8 B" X7 c& b/ q7 d9 E  I* h
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && 6 ~6 p, Z. Y* i8 n1 [7 ~' f
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))" ]( i6 }2 U8 R+ w* O0 B
                            {
    , G) S3 p* n7 p' I9 A! ]                                break;7 }6 ~+ K. s2 N1 y3 s, K) y& |
                            }; @/ b. U7 K5 B9 u4 q( \1 \

    9 |# C8 z( l+ h' l6 k) c! P                        pNode = DLL_NEXT(pNode);
    1 U: ]9 ^; ]) m1 d+ D& \& @                }2 ]+ ~/ H8 r" n2 T
    - n0 C2 I. y) c9 J& V) ?$ S
                    if(NULL == pNode)
    & `) {2 \8 S8 y  H" k( m2 t                {
    7 {3 ]7 O  v' _. s7 e5 w                        /*TODO give the semaphore */- R+ R4 D* Z* ]4 ?% V( |
                            semGive(partId->semPartId);
    : V3 n/ H. c* p9 c7 @" F$ v                        return NULL;4 `9 g- a  c- b
                    }! A& ?3 q5 c) x1 U/ o( r+ J
    ) t# |* `- [3 w$ R" `. {* E
                    pHdr = NODE_TO_HDR(pNode);
    2 T7 n/ L4 o7 g: B  e& W. n                origpHdr = pHdr;
    6 r* ~; I; z: |4 B0 j0 V( ^4 Q9 \* r
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    8 v' Z; k& D" |1 i                if(NULL != pNewHdr)
    3 V0 L5 M; O/ c" u, ^$ Y                {; ?+ |6 j7 j; \' C7 T
                            pHdr = pNewHdr;
    ; e- n* Z# t/ U7 _3 U+ a* V5 q                        break;
    / p& |/ m/ [0 g$ m! v: A9 n                }
    4 {! v/ t1 O9 `; j
    / ^2 \1 Z6 m* m2 Y3 f                pNode = DLL_NEXT(pNode);- G' T& `3 K7 T; G: J( B
            }; v* v! K* D5 a$ H' g; p
    5 U5 v2 s0 i) e
            pHdr->free = FALSE;( V, }* i4 N8 o/ _
            partId->allBlocksAlloc++;
    8 r) A0 l' g# [; A- E! u6 t: G) U        partId->allWordsAlloc += pHdr->nWords;
      n2 W  ]$ B2 V) f) V        partId->curBlocksAlloc++;
    9 f7 ]+ ]4 |/ `/ d$ G% T        partId->curWordsAlloc += pHdr->nWords;
    ) {4 b0 |8 v( z! F, Q' \3 b) ~* r. A! p& q
            /*TODO give the  semaphore hear */& B7 R' F/ H, c: M
            semGive(partId->semPartId);
    ( \  A  ^: e+ D- H        return (HDR_TO_BLOCK(pHdr));. x1 c, C/ X# Z
           
    : [* l) {* {- ~6 Y( }, {. W+ E}% F# {" y, K  W# V1 t" `5 K" q. p: e
    : a+ U3 f# D1 J/ S- j# \6 k: D+ o' w
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)$ q( E1 k- h5 T) Y$ J
    {
    . v: D) B4 O' i        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);6 N/ R1 j/ G4 j. P  G  f: K
    }- b" @* g" J2 }+ q

    3 O! r/ p/ y& o& J: t% h; aSTATUS memPartFree(PART_ID partId, char* pBlock)
    # A( v" y+ ?* W7 r0 j' K; O" b5 p{
    4 I6 E' E. r5 Q+ k; O        FAST BLOCK_HDR *pHdr;0 e8 h8 Q' M3 w1 C5 I5 k) c
        FAST unsigned   nWords;; A7 r. V; t+ G3 v* O
        FAST BLOCK_HDR *pNextHdr;. I1 c1 n6 P* e

    6 C2 R8 ^( G1 {+ A3 D$ x        if(!IS_CLASS(partId, memPartClassId))4 x7 Z! J/ `6 I8 f) l3 u
            {6 H; B; A7 a: c3 L3 J# p. J, ?- e* z
                    return (ERROR);
    / ?6 e( x1 l- ?9 V: K$ k. A! M        }
    ; s2 `! L' e8 i  ~
    % a' ]6 `* R! _/ [3 C        if(NULL == pBlock)% m; u- K4 ]+ v
            {
      }- k% ^) p( a5 F                return (OK);
    , ~. d4 y( `" h8 ~  f4 I7 c0 q! G        }
    4 ?5 L3 D( @- I, S" [1 \/ x- E/ Q
    1 `5 y/ k, m1 h& O9 k        pHdr =  BLOCK_TO_HDR(pBlock);
    ! y# `: g& k' Q: a/ Q% {- H; r  F2 v6 p8 T# f4 A# Y6 {, n/ ^
            semTake(partId->semPartId, WAIT_FOREVER);; L+ e% T- m. @' U! Z2 b+ O% Y
    5 c& N0 p0 l8 L8 j; T
            if((partId->options & MEM_BLOCK_CHECK)( X: K) k1 _; I# g8 Y5 t) B2 S
                    && !memPartBlockIsValid(partId, pHdr, FALSE))' R* c. Q+ W3 {) D0 t
            {
    9 n# R9 ?( d; I9 b" R( @                semGive(partId->semPartId);
    6 b; k, X8 o0 C( r9 x: R                return (ERROR);
      \, ]2 M* E) E- e, r        }' p8 N* ~: v2 k( C7 V( ]! g
    * L. H* R5 S! L2 P4 u
            nWords = pHdr->nWords;
    6 B3 L* b6 L+ Y% }/ u, h        if(PREV_HDR(pHdr)->free)4 G4 q) ?% {" M/ N: E
            {/* the prev hdr is free and than coalesce with it */' a2 N. M; e$ k1 d! \+ r
                    pHdr->free = FALSE;+ u! T$ Q; }/ J6 E' e2 g) [
                    pHdr = PREV_HDR(pHdr);
    , N6 P" `! Y( F( s/ C                pHdr->nWords += nWords;2 ?- `3 w6 b+ v3 b" l4 @
            }& v; o! j1 ?2 i7 d2 O$ p- G
            else
    4 P- \' N1 J/ e& d! B: o* j0 n5 K        {
    - r8 m7 X. \8 b                pHdr->free = TRUE;
    ! ?7 r* ^- J5 M2 ?                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    0 s, |: F! Q0 V! F* A8 k        }
    6 {4 _5 O3 D: U! J" \
    . v. S5 Z5 P* g) ^4 P, @        /* check to coalesce with the next */
    5 r; b: ?9 p* K' @        pNextHdr = NEXT_HDR(pHdr);: }7 I, z* k( }5 v1 c4 H! ~
            if(pNextHdr->free)4 z. f. J% ?9 J$ @
            {
    # H% Y: z; N, r2 _% P" G, z                pHdr->nWords += pNextHdr->nWords;
    * e2 I- i: w; Z" s8 c                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    * O' A, _& s2 n* K: z        }
    , C7 ?# d" k: Q) D& r6 I
    8 v2 E$ Q1 a& _  X. q+ x; L* V' e        /* cannot use pNextHdr->prevHdr=pHdr hear */
    : b7 o" r( |2 Y9 E' R% {/ ~        NEXT_HDR(pHdr)->prevHdr = pHdr;: @# O  P7 W: z

    - [7 m4 ^$ v) R# }        partId->curBlocksAlloc--;+ U7 n1 g* v; M; M
            partId->curWordsAlloc -= nWords;: g9 z  U9 M* N+ X* J
    ( P, f; A, X1 c5 q9 q
            /* TODO give sem hear */
    / y. Q5 L7 x4 G2 U# e4 F% Z        semGive(partId->semPartId);- W4 z/ c- U; L5 C. J7 b' e* O
              ^+ g6 D, M4 C5 L" w
            return (OK);
    ( Z) x; u5 q+ Z2 T}' P; Y3 b4 K' T; C7 N/ c* G

    0 K! e9 j+ e5 S2 U' U/ Tstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    4 q& `! E( G: U4 U# D& Q. j. q{
    ( O; E6 `) f8 x0 p        BOOL valid;8 R$ f/ b; D5 k" M9 Y

    8 p2 o: c3 k2 \+ ]7 L8 Q2 P$ a* z) s        TASK_LOCK();2 D: f4 i( |. ~9 ~" p
            semGive(partId->semPartId);
    / ]; c6 |  t/ S3 }; c       
    ( r. s+ C3 a" ]# r$ w2 K7 k        valid = MEM_ALIGNED(pHdr)  c; n- K* U- p# M# l$ g
            && MEM_ALIGNED(pHdr->nWords*2)1 E5 U8 Q4 m, c5 c. [: [1 e: t
            && (pHdr->nWords < partId->totalWords)
    - j( l1 }+ E  Z8 I5 d# @        && (pHdr->free == isFree)
    , {# M  F. C& F2 J. L        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    4 O) M) M4 _, M& L        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    ! a) t/ z+ W! H; u1 f( o        # t, n3 L' {4 }, E& M  _
            semTake(partId->semPartId, WAIT_FOREVER);: G/ h5 a7 q2 _/ H2 ~% s6 }: Y' E+ x
            TASK_UNLOCK();
      `: {$ D" R' p/ F1 _5 n) `$ U- S, Q/ \9 `( d
            return valid;
    0 d8 v( C+ Q# y8 G1 p  t3 h}* P/ C/ ~# ]. I( M! u3 D* w

    7 N0 V  e( H% z. sstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId) X% p  d* k5 Q  L  f% @
            , FAST BLOCK_HDR* pHdr/ {- N& ?4 U  S& N0 g
            , FAST unsigned nWords1 I: [* I3 s0 j4 R. W
            , unsigned minWords
    ( t5 N- v( d+ I8 {        , unsigned align)3 N5 E) S" t* D) N
    {, X% G! J, a6 q9 f. \
            FAST BLOCK_HDR *pNewHdr;- C. p0 e3 C! q
        FAST BLOCK_HDR *pNextHdr;
    4 T$ P9 |+ ^( m. X5 g, F" W    FAST char *endOfBlock;
    , a/ X  v* @1 f# h- C2 S3 {' N    FAST char *pNewBlock;0 M8 M( _5 A! `7 a) _
        int blockSize;% D& d8 \8 Y8 S+ ~0 Y0 W+ b

    3 [* O6 e  e! L8 p        endOfBlock = (char*)pHdr + (pHdr->nWords*2);: a" w) R( S/ y7 v/ a

    6 K+ R: y+ b! A) ?  y$ [! y        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    4 C5 v' F, V' r8 o& F6 q% u% j- W
    1 S. q! ?4 K7 H% Q        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    ! x$ i' O$ n9 V) n& a4 R/ s
    . R% C7 _/ e3 E* A* v$ w        pNewHdr = BLOCK_TO_HDR(pNewBlock);4 t3 P9 @6 O4 l2 A+ b: C
    ) U$ V. k2 L7 O1 m/ }9 N
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    , R: L/ i* t+ z8 I8 x
    1 O; b) d2 Z$ V1 b$ c$ y        if(blockSize < minWords)/ Y/ p( d) f6 R8 _
            {
    ! A1 m+ u- }* |; X+ d                if(pNewHdr == pHdr)1 D) j* d  ], B" X6 G
                    {
    / A- M$ J4 M; T: `                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    $ }: I4 l  ^: K1 f                }
    6 n; U) t! U2 i! S5 V                else
    2 _3 W* e0 g7 [& K. k, a1 E( ^" z                {
    " `, b# \: o& n$ W7 S                        return NULL;
    1 S/ G* [; f% K9 Y  s                }
    $ ?4 |! E0 _$ w) O0 [. k        }6 f" ^% T! g4 Q0 H. z& t
            else
    - w3 S: ?. {" x& J! P        {        /* recaculate pHdr */
    " F* M/ i, ^7 {- ^                pNewHdr->prevHdr = pHdr;; y; s6 \8 {6 S+ e
                    pHdr->nWords = blockSize;$ W2 _4 w! E  \
            }! }& {2 E4 m+ h: l

    % C# c% }( C8 ]/ x% }4 J        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))0 T5 A/ p: _. j8 e' M6 R# Z
            {
    ; S* {" B& X, l. ?) ^5 P                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;4 w6 e' Z. s9 _) b+ H
                    pNewHdr->free = TRUE;
    ! }7 L: S( ]- g9 i- U1 \  k
    3 f- c- H' \3 F2 d1 d0 Z7 Q7 t                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    6 }0 K+ A4 |3 J' ^. @- N9 h- k        }  I3 p1 m+ Z  s1 [; }6 Y6 s
            else/ I2 ?& Y' n+ b1 y( f0 z8 x4 I
            {/* space left is enough to be a fragment on the free list then */$ w* }# k* D" G: T% K% g, [1 _$ _/ Q, i
                    pNewHdr->nWords = nWords;( `6 a, u4 O! v
                    pNewHdr->free = TRUE;: Q- x. u: `/ Q- r& m

    % F( n2 C! X( i" q                pNextHdr = NEXT_HDR(pNewHdr);/ o( S$ C/ J0 \- E3 q9 j
                    /* words 包括BlockHdr */
    , }+ ~7 a3 _! Y; H6 X. g                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    ) [3 k! U0 f$ I, S2 `6 t# N8 \, U                pNextHdr->prevHdr = pNewHdr;
    1 S5 |& ^& C3 a4 Z7 Z' l) ~- M                pNextHdr->free = TRUE;  T/ x! e/ P! i9 T0 n4 ~

    : Q7 v/ A! T2 l" n1 t; A  N* t: r                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));! |: K. {" z4 }& ]

    4 h# f0 O  p& C5 q                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    7 \& l* z4 m7 `3 O0 f. R- i        }& |/ c7 r: n6 ?% |3 v
    ; |9 b: |/ ?# c6 ]+ y, j
            return (pNewHdr);
    + {+ N' G& F" C8 c/ W1 l( }2 r& h' j}# w8 {" O' {* o2 M9 b+ f
    : R- P+ p5 U* Q4 n8 h
    static void memPartSemInit(PART_ID partId)- u; H( O/ D! f& _# t% c3 I
    {
    & M7 [% A7 b  s3 ^" s        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    6 |6 q! |8 y; ^% Q3 a# }/ x
    ) F$ m7 A0 `2 c% T        partId->semPartId = &semMemSysPartition;. h2 ]% K7 ?; Q/ ], V
    }$ N" M; v# O( C
    - E  D9 r  Y, E5 ^0 k1 ~4 P
    void* malloc(unsigned bytes)
    & m+ V! E8 q) v& C  W0 ~, Q{. R% @' L" u( ?% D/ {0 O
            return memPartAlloc(memSysPartId, bytes);3 P) Q1 k! g- S9 m* ~3 ^! ~: P
    }
    ' d4 `* X& P/ K, v# D5 l5 B
    5 F3 x, I. ]+ A0 k  ~6 a  t3 evoid free(void* p)6 S8 o* B2 k# q1 A4 I8 a5 j7 O$ o: Z
    {) d9 L* T% U4 }
            memPartFree(memSysPartId, (char*)p);
    " W! m8 X" I. g. g: [  F, ]. x9 G( R}
    4 Z# Z. A& E# p9 g* W+ {- G
    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-20 01:15 , Processed in 0.447102 second(s), 51 queries .

    回顶部