QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2841|回复: 0
打印 上一主题 下一主题

malloc(内存分配)在嵌入式下的一种实现

[复制链接]
字体大小: 正常 放大

937

主题

117

听众

3万

积分

升级  0%

  • TA的每日心情

    2020-10-25 11:55
  • 签到天数: 264 天

    [LV.8]以坛为家I

    自我介绍
    内蒙古大学计算机学院

    社区QQ达人 金点子奖 助人为乐奖 风雨历程奖

    群组2013年数学建模国赛备

    跳转到指定楼层
    1#
    发表于 2013-7-26 10:17 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言9 v( j5 f$ J# h) }; o

    ( ~9 G/ [  A8 E# b- G
    * D  F: ^+ b+ T( F8 Y7 B: u5 ?9 ~' P6 S( ~6 ~# b$ k
    *\file8 @! \! F2 O. ~! c
    *\brief               
    8 ~1 Y* x. V+ C" W; W *\details       
    0 n6 Q* P6 e. h; j& q *( ?- a% r9 H) Z& z5 B; g  W
    *\author        Janson( A8 t8 X6 ~( O1 H
    *\version       
    # |* [- X5 Z% [# _ *\date                04Jan12
    : i+ I; R+ s' W. t) `- M *! v/ H* s' y& g8 [6 i  M" j4 E
    *\warning        # n( }0 H. z1 b: h! r1 d% a: F
    *; t* T; k! D: Q8 x3 v  k( E$ Q
    *\history \arg        30Jan12, Janson, Create the file. M" r0 `) t, s/ d0 J6 A
    *        modify from VxWorks source
    . ^  j3 A/ \! A% i, [/ d4 B) Z2 V *  Legal Declaration: it is for studying VxWorks only.# n; W/ N4 [1 _8 w. y  D
    */+ P3 B# N% x0 q+ z
    #include "includes.h"
    9 E, s+ P" {8 D# H" p' Y* h
    3 U% \! `8 F, M% b. J/* The memParLib.h file is hear:
    & R8 [. V/ w# h: x: Uhttps://code.google.com/p/vxwork ... rivate/memPartLib.h) i/ t0 @' J3 t4 h# Y% M
    */& q0 V$ y: G( ?/ l

    1 ~, |; d. A" h, s3 B' F7 ^/* optional check for bad blocks */
    3 i/ W5 w: E8 {# N5 ?: K' d5 g5 H1 T0 ^+ v+ @
    #define MEM_BLOCK_CHECK                        0x103 p' T5 q; Q+ O; `5 A! R" i) ]

    2 G0 i/ {  N5 |6 U+ h0 a2 i/* response to errors when allocating memory */
    ! t& E. k2 ]% M# q& V
    # J( Q, [! `( m' ^8 y7 q5 ]#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    / }/ t9 K: _/ m: F/ m% }6 e6 i+ ^#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x401 p# H: z8 g- m5 L. W. K, J' N
    7 t& ?! ~, H* o# G
    /* response to errors when freeing memory */: t( P2 o- A$ {4 c& f
    0 B" n6 I  |/ _! i- l. Y4 }
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    3 U$ w2 `- m! ?6 l: _#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100" O3 ^+ o, A: o- w: Q; |2 V
    5 P' z; {" M2 N' S( C& h- _
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    8 v6 L8 ]5 w. H# B: U6 \& \#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)8 Q" l- X. V& q

    - u4 J4 Y$ Y* e5 C' K* n1 S#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))- c8 d6 q8 D8 F% N' Z- [* D
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \( k2 ]  v; e/ @3 ~7 w5 B9 ~
                                                    sizeof(BLOCK_HDR)))
    # |% f2 v. G) G* p: f; x
    5 K3 K: v. C7 Y! c  U( B& b* v#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)' ^' k2 f2 [: Z( G) {
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \+ h- R/ ~: k: T3 i5 b
                                                    OFFSET (FREE_BLOCK, node)))
    6 J* q5 t7 U4 V6 \$ s3 H: k& `  r5 x4 C4 g7 M- \+ i
    static BOOL memPartLibInstalled = FALSE;* n+ p+ C* g/ \4 }3 A% [
    " N/ b( X1 M- @0 Z
    static OBJ_CLASS memPartClass;& r, k( O; @: `. y
    CLASS_ID memPartClassId = &memPartClass;# D* h( W6 J/ S  m' t
    ! r/ M% r4 p4 }# f
    static PARTITION memSysPartition;
    ( \/ ?: Z& }1 \; \: X0 FPART_ID memSysPartId = &memSysPartition;: l; p7 n, b" |# _1 t
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;0 M/ |4 d* V3 J7 A. q8 Q

      }0 J7 I( `# F1 Astatic SEMAPHORE semMemSysPartition;0 q0 n, b3 k/ H  i: t8 ^* @" X/ i% X

    & i% G% a" A# j! m1 C8 astatic void memPartSemInit(PART_ID partId);
    7 s, Z; {  n; \. A+ j# D4 m3 ?0 {8 P. T( @0 D6 T/ h' M
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;/ d" }: P% B. T# S

    . `6 i7 o: K) |2 a, Iunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    * k; _& X6 z, ~& K/ B$ a6 j# C4 ~+ u
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);6 U! K2 K* ]+ {; {5 I- H  J9 U- W
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    , w( w0 l# |0 I/ J* z6 P: _        , FAST BLOCK_HDR* pHdr
    ) _7 P; k- E5 _. u2 k, o' R        , FAST unsigned nWords
    2 W7 E6 t3 J( U% W6 B        , unsigned minWords/ o; L- c: l1 f" [
            , unsigned align);
    # f, S2 g. f9 p# u- B" f2 ?1 U1 \9 ^8 X8 o. n
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);2 T& y! V9 U+ A

    . B5 O- ~( F( ^STATUS memPartLibInit(char* pPool, unsigned poolSize)
    9 o* w; v' E) i' n{7 @! w4 g  B% |5 h
            if((!memPartLibInstalled) &&
    $ a! W3 p( i# ^1 D% ~) @, I5 P' p0 s                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    ( Z( I- `9 N& v. |8 d                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    ) b, N7 `% [- W! v$ e3 r$ y        {
    . m2 ]' p) [6 i4 P3 q8 v' Z                memPartInit(&memSysPartition, pPool, poolSize);
    . _" w" C" U1 Z) z* P                memPartLibInstalled = TRUE;
    $ o# n1 C5 [5 L7 K        }
    ' p1 p% v. F% \) m2 \  t3 Q; ~" ^, y% H3 F. }. H9 \
            return ((memPartLibInstalled)? OK : ERROR);# N# W# E% c, P4 Y, C6 @$ E- T
    }
    : ?: _- A1 P6 E- M* Y, [
    8 Y& B1 O. G2 V1 P, `) OPART_ID memPartCreate(char* pPool, unsigned poolSize)! }% x3 v; f! V1 m+ O# m
    {1 ?( N6 N4 h( N9 h
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    7 D! T. _6 `0 M4 y5 S" h0 ]
    3 v6 }1 I% O$ ^# B        if(NULL != pPart)- A+ C$ g# c8 f8 c& p2 E
            {
    . c; D( u) G. [' c% n- L5 C+ h/ k                memPartInit(pPart, pPool, poolSize);
    4 b, W4 ~3 d1 k/ o        }- h9 v7 S/ G( P- J* I
    5 ?6 L0 j, Q2 a" V- O2 E1 P% I6 k
            return pPart;
    ) U" d7 v% k" q& y2 z}
    $ V# }* R- ]# V' n* S' P, j+ j# ^0 W; f5 T6 o8 p0 {% N
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    2 @8 r, ^: ]2 H9 S- Y  Q, d{
    ; ?+ D2 _. h* W3 `7 ?7 |        memset((void*)partId, 0, sizeof(*partId));0 n. x/ o; H" |. c

      u/ B2 h  t* M$ f* T- F: N2 E& d- D        partId->options = memPartDefaultOption;+ _, g6 f& o/ k8 y
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */  d. t% F" \5 p* L. T

    9 j  n. W* ~: }. \' ?7 _- C        (* memPartSemInitRtn) (partId);
    5 D) H3 e; J% G; N; u3 ~8 n# y0 t8 b0 d& Q       
    3 G) n( r0 T. U0 N4 i        dllInit(&partId->freeList);$ o: z. u$ Y/ ]) V
            , ^( N0 P5 P6 @
            objCoreInit(&partId->objCore, memPartClassId);
    % [+ m& c! j0 u' C. F       
    & S- W$ E: J1 l4 b9 z  b; x        memPartAddToPool(partId, pPool, poolSize);# v, t. C9 y$ l  `  r. d- t; ~
    }
    ' h- _- `$ y% z) Z* Y6 N7 k" P/ u; ^2 j2 @7 J1 t
    STATUS memPartDestroy(PART_ID partId)8 g- p. t* `! g* ~* n" S
    {
    5 k7 ^: f, ~+ s/ a4 V# Q2 D' U        return (ERROR);& a- G9 ]5 j/ s9 \# O
    }
    0 ~1 Q( e$ V+ x
    6 x% M* h7 I& K9 wvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    . ~, \& g5 C% v4 F- t{. P8 H  q7 }* J- @* d  Y
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);/ D* K2 ?; a& |& E8 R1 M3 }
    }
    1 \, y5 x# Y: J
    & B4 j! T6 N% ?" @5 p1 z% V( ~6 k2 x& g4 C4 S; f; z1 o
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    2 L7 N" n3 k2 k+ @( _. j0 y: N3 L5 L1 B{
    / l7 [% m, M) o5 R8 d        BLOCK_HDR* pHdrStart;
    ) l  K8 l% M4 _/ j6 o" i/ a        BLOCK_HDR* pHdrMid;& ~/ t5 c7 x* }* h7 T4 I
            BLOCK_HDR* pHdrEnd;
    1 Z# s1 o$ t% Y        char* tmp;
    & t( m; b5 x2 L7 F+ H/ l: P        int reducePool;
    : e+ B" d6 E' d9 [$ o" `3 Y4 x8 b3 o4 W9 ]( ]" i5 w
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
      ]# c( K) l. F  B        {& P1 J0 o, M9 {! K2 j
                    return (ERROR);! }/ B% v  O8 X# L6 q
            }) e- q% a) d9 `
    * s' e; ?2 H3 u; o1 k; U
            tmp = (char*) MEM_ROUND_UP(pPool);
    ) t& ?- g  f) r* J  x- H        reducePool = tmp - pPool;
    , G! Z6 m* U1 ]( ^: u7 T) @. s8 o$ S4 S
            /* adjust the lenght */
    - w1 Q# `1 R  n        if(poolSize >= reducePool)
    % i4 ?8 q9 E) P# ?" d* c  p        {
    ; {' e# e" [* ]2 k0 P0 U) j) @                poolSize -= reducePool;: O# M' X0 @" p. ~
            }; r4 T8 c2 H+ x6 i
            else9 B+ B4 f$ F1 k! K0 _4 I# D* s+ }
            {6 x0 @0 _! u- {2 h* d/ n* q
                    poolSize = 0;
    2 E2 Y+ ^8 Q  P( \7 `$ w. A. U        }
    ! j1 A# t, D' [% A; a: }- C, v        pPool = tmp;; `  X, i0 E1 d
            * `4 v0 b  G. o: {- ?  E
            poolSize = MEM_ROUND_DOWN(poolSize);# {/ f* |' Q! [* }- Y5 K: G# M% t
            * q( f; Y" E8 l) f; A6 o; m
            /* at least one valid free block and three header blocks */
    / S% b4 I# N' w- X7 G        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)1 H1 L& @: P7 z6 J2 N
            {
    7 {( k; t: V& r( Y" @                return (ERROR);3 z& C: y9 S* G' \  B. q
            }$ e* ]" J' Q3 Z% L. D: a) O2 {7 D

    : d! ?2 a7 ?8 }) Q7 C+ y        /* initialize three blocks */
    # K. o+ D# p8 x$ w7 ?' ?6 Z        pHdrStart = (BLOCK_HDR*)pPool;& C# b7 S  T  w7 P9 D
            pHdrStart->prevHdr = NULL;7 x$ T4 M/ [& s" }) m8 q& S/ f
            pHdrStart->free = FALSE;                /* never in use */
    , `; T6 z! s/ Q0 Q  e8 v% u8 k        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;6 c. d5 g" C0 F8 @* o5 m2 i

    4 D# j" V; i- x( w1 M& U% N7 Y6 p        pHdrMid = NEXT_HDR(pHdrStart);
    2 A# n! S0 g* v) ~  @6 }        pHdrMid->prevHdr = pHdrStart;
    ! L2 I1 q" X' N8 U        pHdrMid->free = TRUE;                        /* the main block */: i; d! q; `3 k
            pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    8 c  ]6 y0 E/ X" Q* H, _- N9 ^& ^' {  J5 ?/ e- r! }& V8 }
            pHdrEnd = NEXT_HDR(pHdrMid);1 M- D$ s0 G! ~4 T: e4 R3 J
            pHdrEnd->prevHdr = pHdrMid;7 H8 i9 B7 Z3 _2 M2 V' J
            pHdrEnd->free = FALSE;
    4 h9 @( _& Z% c5 f  r        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    * `1 J& K3 N/ i2 k/ E! y
    6 u' v4 y+ q7 G0 e- Y        /* TODO take sem hear */, A9 i3 H3 D# |2 O7 n7 J
            semTake(partId->semPartId, WAIT_FOREVER);
    7 C6 N8 D, z& ~        ) h/ r5 e* o7 k9 m( f
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# P& o4 `- x6 g! `4 b! N$ ]7 T% g
            partId->totalWords += (poolSize >> 1);
    6 D' d$ j, b. J! P/ A0 d5 {
    ; x  ^9 z3 K( Z2 P, c; b+ k7 u        /* TODO give sem hear */5 v( C2 a! y( ^% ]* J
            semGive(partId->semPartId);. t+ l- A1 i" c2 B) }/ _9 [4 c

    ( f3 h; v% Z$ ~) d9 }0 Z7 G, W, _" W' C3 s5 x* m
            return (OK);
    1 R; ?+ U9 I0 z* G}
    4 n! ?8 c* y: F1 F! j, x0 f& z- B6 s9 k6 J% p: s3 l
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)# N) v$ S' q; c1 P, C$ ?( X
    {% ?0 Y* b0 X' }; G; K& d
            FAST unsigned nWords;" c$ r7 B0 S8 L3 W+ x1 P1 L9 @
            FAST unsigned nWordsExtra;
    $ w6 f% r0 ^9 N  H) p0 y        FAST DL_NODE* pNode;
    ) n1 v  M2 o9 h' g        FAST BLOCK_HDR* pHdr;
    / W) p. |7 V' l9 l        BLOCK_HDR* pNewHdr;# [* P% g+ z3 u4 j# ?# S. L$ ^
            BLOCK_HDR* origpHdr;
      n$ O2 w) v: O  d9 K
    1 s0 z$ R: \3 d' b" }  ?/ ^) e        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    - J) a% Y2 M% {        {2 t1 D" t: n1 O5 a$ D
                    return (NULL);: o  O- r/ @8 j( f
            }5 m/ ^+ _& `% b0 I9 O, I# l/ B

    ' F3 e9 c. y; T# O# ]4 O+ d        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    5 z6 J7 s8 l0 {$ e( C$ z# z
    7 C! l- E! R7 V4 }5 c$ k# j; Z        if((nWords<<1) < nBytes)
    7 d' j! k' \# a% \+ q        {+ L1 _7 D6 W# Y5 z; a
                    /* TODO suspend the task */! B) H; ~5 q, a, w+ l
                    return (NULL);$ _: c/ y3 x+ A
            }
    ) i- `5 O$ ^& u
    0 C6 k+ A' b0 E# O        if(nWords < partId->minBlockWords)4 _8 g6 C, B% d* _
            {
    . o7 E# G! t1 i7 r                nWords = partId->minBlockWords;: v" ?. A( a& x: \/ u9 y
            }
    1 X% _( o) [& r4 e0 P/ ?) _, ^3 |5 p- Q. g0 R
            /* TODO task the semaphore hear */% I" o# z( Y6 e
            semTake(partId->semPartId, WAIT_FOREVER);
    , |: C, ^2 K7 a- N        pNode = DLL_FIRST(&partId->freeList);
    # u/ b7 C0 P/ A# n. [! P; }        nWordsExtra = nWords + align/2; /* why? */, O' P$ A3 @4 a1 Y# J

    , p, B) [: E" K2 b. l, @        for(;;)
    % F% r" V% x: e! o+ [        {( J9 f& J6 r8 k/ P9 U. v
                    while(NULL != pNode)8 c  u# F+ H" b6 M& y5 D, O7 C: c
                    {
    3 k7 g& b1 K! @  G$ V, F/ n                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||. L* x$ _% o3 c
                                    ((NODE_TO_HDR(pNode)->nWords == nWords) && " u# B; B1 s3 p- b/ w
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))5 R2 P$ M: v: U3 q. z2 J: B( {
                            {
    * i! Z3 @' h& ^5 C                                break;
    5 Y. k2 M* [; x                        }
    ; Z, p) H' Y" B1 G1 d! ~% E8 n/ R( J+ m1 r
                            pNode = DLL_NEXT(pNode);/ D( P% |: U4 o: f# l
                    }
    # S; C+ W* u1 Q, t- F6 ?2 m, Y' V7 W% X4 b; {
                    if(NULL == pNode)
    ' G/ B" n! [2 w9 W4 Y# A8 e                {0 J! l7 p6 }8 R; F6 y1 u! {1 ]
                            /*TODO give the semaphore */6 o( k2 C: R* h# w/ y9 d
                            semGive(partId->semPartId);
    2 Z8 {1 l5 W  k7 m% W5 ~5 v                        return NULL;7 |5 ]! t6 U7 i. v. e0 k8 T
                    }
    0 {: C  u! t3 l5 P; X2 P/ Q) x2 ^
    ; G7 X. U: E' ?  K9 l* Z                pHdr = NODE_TO_HDR(pNode);
    # Y7 }2 `6 n" K0 h8 Y4 ~& ~                origpHdr = pHdr;
    ! m: P% H# z1 P1 V8 @7 i; v1 Z: B' D( q5 }" e* s, }2 l+ g! l. y
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);( ?  v) `% j+ E; c) p3 b+ _) P1 {
                    if(NULL != pNewHdr)
    : f; R6 d. \% d+ H, O& N                {4 V: S4 I! Y3 ?  ^9 p3 ?
                            pHdr = pNewHdr;
    + N  }  `7 L# \3 _! p                        break;
    7 M5 L; T4 v* l( @9 i# X2 c                }6 \6 k6 e, V( T, q

    ' `- m- z3 i: w! n                pNode = DLL_NEXT(pNode);
    1 d& k% Y% T2 c0 b$ ^. z' I2 q        }, w3 }# q' G# \; ^

    ; n& b5 ~* t+ L( M        pHdr->free = FALSE;
    " h( Z/ o3 b! i2 c6 i$ |$ i1 u        partId->allBlocksAlloc++;
    3 Y& T9 q; C* [3 ~        partId->allWordsAlloc += pHdr->nWords;
    0 B) b/ b; H  |# i6 s( L  W5 R5 B        partId->curBlocksAlloc++;! @9 @: g6 h' J1 ?( i8 O# G
            partId->curWordsAlloc += pHdr->nWords;! y+ p& J8 l% |. G+ J: K2 L' x- Q9 w
    - V# M- O# R3 Z$ A- r1 y
            /*TODO give the  semaphore hear */: m: C! I. C+ S1 C
            semGive(partId->semPartId);
    2 T1 g7 \5 H3 r& I/ q        return (HDR_TO_BLOCK(pHdr));
    * y8 U1 z0 ~5 U% l* Q       
    ' f' d6 ?# w7 B3 o% E/ C$ H) ^4 P}
    * U8 }, f9 g3 t3 T+ y9 @: a  w6 y# ~3 L, Z, s8 a, Y7 J
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes), P2 M% s' P2 p+ a. Y5 l( d5 k$ [9 A
    {! {% O9 X* `( \, u# e' c  h4 v
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);0 s/ H- r1 v* @8 c+ W1 H
    }' {+ |9 c0 e. _! {
    5 C2 @$ Z9 x' p/ y# J0 O: l
    STATUS memPartFree(PART_ID partId, char* pBlock)0 ^( O) r( {1 l" }! a7 j6 w# A4 U
    {
    9 r* Z3 t+ U- i+ ^' a2 Z8 ?        FAST BLOCK_HDR *pHdr;
    ' d! z+ C: G0 w0 k0 G9 d    FAST unsigned   nWords;- W1 L! A) K0 R: [% D) M
        FAST BLOCK_HDR *pNextHdr;
    9 {4 i2 c- l$ @; e0 E: M( }* E1 Q3 e
            if(!IS_CLASS(partId, memPartClassId))7 [( d: y4 y# A/ {: H" N
            {8 z* ~1 N; J5 J5 g  r6 s3 ]
                    return (ERROR);% M- l9 v/ s8 r0 z
            }
    7 C& T% t& S% C8 f* ]
    ' r" \6 \' J) G8 j5 C( T        if(NULL == pBlock)/ e) k% Z' n3 g* t; o( z5 D
            {, x, n; W& e4 s  H6 y6 V, s4 B2 h
                    return (OK);
    1 \5 y) H  g( ?        }7 e* j. a+ [! {) S1 k6 b
    8 K  [0 ~( a2 B- L: n
            pHdr =  BLOCK_TO_HDR(pBlock);. o- l" o8 n4 b' p3 j+ K7 T$ v
    ' N) b. P$ j; A* ~! ?6 _! P
            semTake(partId->semPartId, WAIT_FOREVER);
    $ B& ~/ O+ l- t; S  A. d+ W1 b+ M& X+ i/ {
            if((partId->options & MEM_BLOCK_CHECK)
    7 b3 n& p& a# t: P                && !memPartBlockIsValid(partId, pHdr, FALSE))! ]- y6 N: L3 H  @- c* G, {  N: P- i$ g  _
            {
    ! B# U7 P# w9 X! I+ [& W7 b. n/ J# G+ j) b; H                semGive(partId->semPartId);8 M! L# Y4 g1 T, k
                    return (ERROR);5 F+ {5 G6 z0 G/ x% Z
            }2 K2 C8 s' z, K* Y4 T+ \# z
    % Y6 @6 \+ m7 ^4 q1 G: ]1 R
            nWords = pHdr->nWords;3 ~- Q* j3 K* z; u
            if(PREV_HDR(pHdr)->free)
    - m" A; o- h/ _1 V        {/* the prev hdr is free and than coalesce with it */2 t; [' |& u+ n/ k! m
                    pHdr->free = FALSE;
    ; Z; z, B7 V) _' ^                pHdr = PREV_HDR(pHdr);& C" g" b1 V. C3 }5 Z& ]
                    pHdr->nWords += nWords;
    # z+ \9 \5 k1 N4 j9 u# h        }7 a) X7 i  l* ~! k
            else' X$ _+ x2 R2 u  x! Y. f: w$ r2 \% a
            {5 M5 C0 {7 X+ B' S
                    pHdr->free = TRUE;
    9 d+ D8 y- p! |                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    , b! t' X) Q$ P7 \; l) }. J( {) \        }
    " r6 E8 H+ v- g3 {" w0 e- U
    9 r/ l/ R0 E) A' I" b  N        /* check to coalesce with the next */
    * e( a9 Y6 H( \  q+ R        pNextHdr = NEXT_HDR(pHdr);: v4 W2 M+ _; g' V& U6 q
            if(pNextHdr->free)
    " p6 W6 i3 K& G& O        {
    1 u; M) ~% b; u2 S9 ]  U. b- R                pHdr->nWords += pNextHdr->nWords;+ O' E( d8 v% q4 g0 }4 t
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    . T) [. A1 _, {7 x$ L        }
    2 n& T0 @8 M, c7 ]) b6 N; p/ m! I3 Q; z6 K! E8 F. x
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    + d, s' S2 M6 @9 z        NEXT_HDR(pHdr)->prevHdr = pHdr;
    2 W6 G. [8 y7 h) J3 l9 J# k) G& X  W2 A5 H
            partId->curBlocksAlloc--;0 ?. j7 }/ y! f+ `  b
            partId->curWordsAlloc -= nWords;
    " v6 G0 y* |; b- {* k  l; @4 H! |: N0 v
            /* TODO give sem hear */
    ( L# h1 P. [( S+ K4 F( h        semGive(partId->semPartId);" Y( X# b' |: Y" n) }! J, t
            " H" \7 V6 N% k8 o) \
            return (OK);8 W+ \, \" S+ o0 P) Y3 [
    }
    ' q' H; `$ D+ ~7 ~5 d- q! I; q% I0 E" Q* _6 b9 F
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)2 M" k) k! ~! }$ ~4 B$ q( S  R
    {' @* W6 m6 t  {
            BOOL valid;
    . ^6 n- I4 b+ ~! ?, i+ Y% w4 _" A9 a& B+ i( O/ [& t1 o- p, u
            TASK_LOCK();
    + Q8 O" j7 m; y4 b; _        semGive(partId->semPartId);
    : p% H# x- n- s! T        6 B6 a" {9 w: V* F7 g
            valid = MEM_ALIGNED(pHdr)( Y& v  [$ |" b% ~7 B! R- w
            && MEM_ALIGNED(pHdr->nWords*2)
    : d/ c, z. w% h, [/ U& k. O" ~: D        && (pHdr->nWords < partId->totalWords)
    8 Y$ y$ j5 K' i# K        && (pHdr->free == isFree)% a+ y! u& P3 y( h
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))) X: u% o' k% P7 h0 \! x, G! r% {
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));* @, K: d, M! Y6 ]
            5 P; l$ ^9 G0 I
            semTake(partId->semPartId, WAIT_FOREVER);3 C( X. W8 Q( {5 t, D
            TASK_UNLOCK();$ \) B- A3 B! g: X  I

    ( Z- w1 I9 R) S! M- K        return valid;
    ( {, ?+ `; p& P3 H( E5 N8 |: l) C}% |" z2 ]  r& p% [- g
    0 L( F! H4 V  S' v
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId$ b7 f9 I; |( X# ?5 x. a; I
            , FAST BLOCK_HDR* pHdr0 i- ]. l$ H* B  _
            , FAST unsigned nWords
    0 `, M$ R: s9 R9 y        , unsigned minWords
      n5 O2 @* l; r- d9 u# k/ Y8 r9 u        , unsigned align)
    3 |: o) d7 `# S% z% C. q% Q+ q- @{" C! }; ~: l5 X
            FAST BLOCK_HDR *pNewHdr;
    5 z) o5 H* N* R    FAST BLOCK_HDR *pNextHdr;
    ' z3 E$ U* m! {. v: n" g* h9 M! T& c    FAST char *endOfBlock;; k3 Q& d! Z) \9 P- P7 w
        FAST char *pNewBlock;
    4 {/ P0 l& Z% P) m6 y    int blockSize;
    $ s  K( _5 }: A1 y( @' r" V, Y6 _9 h
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    1 J6 D+ A7 v+ H' R. U' _9 b
    6 I* i% z7 K+ O4 V        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    5 K6 e* F# ~' X& n3 n9 K- X8 K) h' P/ o( e2 f( ], ?
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));% |) `: s. Q- r9 \% H; o  M

    1 M% M* |' g4 x* p        pNewHdr = BLOCK_TO_HDR(pNewBlock);
    + A- @- Y6 L0 f& m
    ) X0 z" Z# d: B% C/ S        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;' n1 \; F6 w7 S. l; t* _$ O5 K+ v
    ! B* Y6 N5 y5 y+ R* C
            if(blockSize < minWords)
    9 H, `, E' W- x# A" m% e3 C        {
    ( }  z  F$ m! t+ N8 e                if(pNewHdr == pHdr)
    * f' a9 W$ P- b: z7 |6 v                {
    . X& V; @# D$ c+ v- s0 D* m' I7 e                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));0 d4 h$ L% x: s3 H$ e! x
                    }$ V# e( S% U: U
                    else5 S( @1 K9 z+ a5 K. ]4 R' s: {
                    {4 k. p# S) N0 r- p# @1 j, [9 [( D
                            return NULL;
    - v5 n* S0 Q* `7 }9 ]0 }0 I                }6 T& f4 R2 v, d, R; n  v& u. w
            }0 z5 Z- a/ Y2 L
            else( ^! i, J6 _; K9 M- ?  ?% H
            {        /* recaculate pHdr */" f2 V! }+ y+ x; m! {$ F
                    pNewHdr->prevHdr = pHdr;
    ) V/ X1 s" v. x( H( S0 x1 j                pHdr->nWords = blockSize;3 g' `. Y  i2 A. b# i
            }
    ; o9 G1 u/ R7 G) N: s4 n2 M% [- X, R
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    5 D+ v. o- q; @7 Y6 x  b& s3 v        {
    0 o. N: Q1 m9 g3 n9 s. h                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    , [1 Y6 o2 U+ R& b" N+ a8 f3 q$ j                pNewHdr->free = TRUE;
    9 E+ e! V1 _" e9 r: U
    , D, r- [4 U7 e+ L' o                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    : L8 _; b0 }/ b6 C/ g# q+ A8 y        }" V$ T; T3 c9 O6 p  d
            else% v: \! s7 K+ {; }% P/ b& A% \
            {/* space left is enough to be a fragment on the free list then */9 y- `5 H( D$ w* ?& U% ^2 w
                    pNewHdr->nWords = nWords;# L! Y7 M* F4 {$ B5 |( @
                    pNewHdr->free = TRUE;" t  s* E. Y7 Q7 R' @( k
    $ j+ x) ?  m1 f6 J7 H- A
                    pNextHdr = NEXT_HDR(pNewHdr);1 N# x$ w; {7 T8 \2 ]- Y$ N
                    /* words 包括BlockHdr */
    ' y6 f$ }3 M( E$ H7 J+ ~/ b                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;/ D2 q3 T7 N4 t* m. \, Z
                    pNextHdr->prevHdr = pNewHdr;2 w* C, t5 A* p4 q; k* g
                    pNextHdr->free = TRUE;+ a) l' x- \/ v& n

    4 F  m4 T( m7 [* U                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));6 E4 O, `/ J9 u$ T

    : _8 z: `' `$ L                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;) }3 P7 S! ?: i: b: u  T. O3 N
            }: i" p: c- F" Z% d% V
    " P+ i0 I( K( ]
            return (pNewHdr);
    , v7 H/ e5 p/ }7 t% h& ^}
      t- T# j7 G7 `, R% I
    # u* X4 ~" Q, P) hstatic void memPartSemInit(PART_ID partId)/ l* h4 c7 n9 ]/ U! o* f
    {' k+ v4 x7 a9 @! ?
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);9 C" r* N$ q, }. U5 I$ `

    - G# k' @" S1 m4 y4 H% x        partId->semPartId = &semMemSysPartition;& U' o# I5 Y9 w0 [3 e
    }
    8 m' X% M( ]! w% I1 e
    " L3 c! M  ?" }& O0 C# V$ dvoid* malloc(unsigned bytes)
    , b5 f$ A# @+ j! h8 W; _{! t, M$ j' F, Z" Y2 c/ B& f+ h* ?
            return memPartAlloc(memSysPartId, bytes);
    . f. U& Q( C3 d6 R3 W% x. I4 N% P}8 V3 |+ ]( t; M) c. P* y: i
    9 Y7 Z2 K$ p7 Y# ?- n: D. F9 }' o
    void free(void* p)- Z, {# J7 d9 h8 q- m4 W: g
    {: O5 N4 s$ L: ^' v
            memPartFree(memSysPartId, (char*)p);! p: C) v# y3 B7 v% D5 S/ W2 P& u
    }
    + k" r5 ~' y/ x" S$ _: X. z+ h' l( ]
    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-21 18:01 , Processed in 0.353153 second(s), 51 queries .

    回顶部