QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2670|回复: 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 w8 e: a: o# s8 }7 C- f; a1 [5 T8 ]( o! I9 F
    0 n' z' K9 n+ T9 g6 o+ g/ S* R- m
    9 {: q' p& }& o, V& x, l
    *\file
    ; T/ g. G2 G) c" k+ U *\brief               
    ' g& f* n) b, K. l *\details       
    3 q" {$ ]0 G+ T2 R% O *3 Z. b/ R! M/ s* T$ p% S8 D* ^
    *\author        Janson2 [$ _$ h; _  u: j0 _
    *\version        3 m+ Q  B9 F' V4 p
    *\date                04Jan12" t9 g9 n5 M' r: a# G
    *3 J+ n, _; ~: m( p
    *\warning        ) l9 g' }$ H- a
    *
    / H$ p+ ~3 s) o *\history \arg        30Jan12, Janson, Create the file
    + @& U- x. U. }0 z9 F *        modify from VxWorks source# _5 ~* q* ?& ~1 _
    *  Legal Declaration: it is for studying VxWorks only.
    + q# {: D, b9 p' y */
    9 V" E* W, R/ j& I#include "includes.h"' i, m3 Q& o  u0 ?
    , c# J+ q; }& B- [( g4 Z4 a+ I( e
    /* The memParLib.h file is hear:4 J( k5 i, a" P9 \% O. ], \
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    3 {$ h' n' I  z' T- l- u*/
    ' P, j; o4 T- b. U& K& B8 d5 c
    7 B0 [* [$ g# v/* optional check for bad blocks */
    # V8 R  ?# M# r8 R1 q+ m% n
    . R+ @$ p$ J' U; R1 Y#define MEM_BLOCK_CHECK                        0x10- i9 P8 N& n0 s% k+ |. m; ?

    6 a- a5 f) K, m2 a' f) R# Q1 j/* response to errors when allocating memory */. W0 G, T* d) S' O0 v8 M8 w$ z$ ~

    ' R6 U9 l2 a& g! a8 N#define MEM_ALLOC_ERROR_LOG_FLAG        0x20) E8 @4 @9 p9 X0 E9 M& h- N9 }
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    $ R1 Y& c* [. p' A" I5 p2 e% }& ^& a0 ]
    /* response to errors when freeing memory */
    / t& W5 V8 y7 Y2 ]- x6 m+ F  o  N! q+ Y* [) [
    #define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    " D$ {4 [- _( e% X  }#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100% ^! L' U# h8 [* p3 S0 L- Q( J4 P
    1 X; b5 r+ |) i& ^
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))! {$ ^1 A' O' E7 o# R
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    ) M! L3 X6 z5 L, [
    $ [. s. O4 F" m' s  {7 {#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
    & F( G8 ~  Y' q+ `. }( A9 A#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \" o0 M2 I6 T, N0 ^" ]% `- O
                                                    sizeof(BLOCK_HDR)))( L. m& e* w5 ?" S. |% @6 A) L/ t
      Q) s/ I+ B2 {
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    ! X7 e4 b- {% W- F( V" Y#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    ( t; F" }1 ^+ q* ^! G                                                OFFSET (FREE_BLOCK, node)))2 s. {3 Y$ v; R. f) Y
    0 _6 \2 c7 m* l" d9 n& i# H8 s
    static BOOL memPartLibInstalled = FALSE;- n9 c4 i9 O$ s) H& O6 ?

    9 \) [, f6 G8 G  F8 p4 O7 `static OBJ_CLASS memPartClass;
    . e! J$ U8 D0 R# pCLASS_ID memPartClassId = &memPartClass;
    , s' e4 P$ G9 g: B: |3 p# Y) {* c, U  f' ]: v4 t% E
    static PARTITION memSysPartition;
    : V, T! Q5 V) C' P+ CPART_ID memSysPartId = &memSysPartition;, Z" A! ]' ?. I
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;5 ~$ z4 b* _6 s

    ) L* @3 B4 ^5 s+ e) u0 e  astatic SEMAPHORE semMemSysPartition;, R! g* A/ e4 r) N* C
    7 a" W8 b9 ~( X7 z$ Q2 h
    static void memPartSemInit(PART_ID partId);
    " G7 n9 Q( O  e: h  u7 R& s8 z
    4 {  e! B4 D) EFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;, Y0 f" U4 A/ s

    * p5 W7 ?5 o* U. Z$ Qunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    - m5 _+ o9 c% S  S8 g, j) \, F  \& O: I3 x
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);1 O* t* d# Q# P
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId# Z* q2 f  k5 |" O$ R2 B
            , FAST BLOCK_HDR* pHdr
    " }, u$ z, M) K  j0 W7 X        , FAST unsigned nWords' o# l2 @0 |$ e5 r
            , unsigned minWords. O; u) D" z) O6 q& L& [6 O
            , unsigned align);2 Z. q' u- p/ }/ J) _# g

    6 ?( X3 w9 V# s, D2 m" S5 c7 Xstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
      }# o+ [$ K" E: p  {- I% m9 O* I: R. Q0 q) ^% ]! x5 X7 x
    STATUS memPartLibInit(char* pPool, unsigned poolSize); y0 k2 F  z$ t7 w
    {- o+ W& f* E. J, ?0 F
            if((!memPartLibInstalled) &&
    & {; Y6 F7 o4 V6 ?$ L                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    + F& d. X# |8 i. p* T! T, W                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))1 [2 V7 E4 W0 F. b' p
            {
    1 _. g, K3 X6 d+ R4 P  G: W: U; e                memPartInit(&memSysPartition, pPool, poolSize);' L; m3 [* m) q+ [" Q4 n
                    memPartLibInstalled = TRUE;
    7 k8 ?+ @: x0 y  H/ b- ]' ?) ^        }
    8 D  F# i  J$ v1 |8 d0 R" p% R# C6 o. V
    ) G% w( \. K' ?. U! z. p! [        return ((memPartLibInstalled)? OK : ERROR);
    4 \# |  d! K2 I( b' L1 R}) h/ y, K% C7 I# t& d1 H+ j2 R
    2 L8 x  D  Y) c/ ~; [
    PART_ID memPartCreate(char* pPool, unsigned poolSize)' G8 g% |1 \$ R  d: Y1 M8 r$ e! J
    {
    2 D1 D# Q) c' E" q: M( P- P        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    ) |* q. ^) o( d& V! @6 m5 L6 N" Z& |' t$ P0 o
            if(NULL != pPart)
    2 n* g3 u* K/ [3 |! J6 i( Q4 c/ H) ?        {
    ) V1 U) H/ \$ r& U5 D                memPartInit(pPart, pPool, poolSize);
    2 K. V+ s4 d7 D7 c        }
    ) W9 X, e$ _3 v0 w3 m) z
    ; }# H. @( Z5 l/ P# s        return pPart;* Q7 F8 i2 p6 J. U2 z3 G
    }1 \9 K$ n& `6 a" |
    4 z- w# a8 s6 W+ j9 x& Z; R
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    * z1 q/ k) C+ x; R  t% F{! M3 F7 G0 B  M
            memset((void*)partId, 0, sizeof(*partId));7 h+ a6 S8 I+ H/ b  S3 `6 A: n. M6 z

    ' i( k& G3 m. E* I6 q& z9 }- h        partId->options = memPartDefaultOption;
    + Z' `; j; r& X5 S        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */+ r, v# d0 |" x( g! X
    " k7 o" j2 {0 g7 S3 G% ^. W
            (* memPartSemInitRtn) (partId);9 j# ]# C/ _! i2 X
           
    ! p. I- _) _- g/ a; w3 P% }        dllInit(&partId->freeList);$ U) \( X8 ^9 o9 }8 O" o
            9 ?1 ?: ~" r: x# W1 ~
            objCoreInit(&partId->objCore, memPartClassId);& Z- G" Z6 V. p* x7 `8 @% U, {4 _4 Y
            6 s1 _% v4 G9 p- G8 I
            memPartAddToPool(partId, pPool, poolSize);: e' R# T) _6 q+ E1 ?' G5 ]; e
    }( e& w) A) f, C0 s4 |# A5 e

    0 L+ q% O% d- JSTATUS memPartDestroy(PART_ID partId)
    & H% s) w' a& C: d6 ~/ I{# n9 [+ H3 Z% ^7 t$ M/ z
            return (ERROR);3 e# J& Y# d- W( |& d! m8 ?
    }" H! g0 M/ y7 @% I. D: N+ ~1 x* K

    3 E' y: g; r% O7 H+ `6 L; @void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    ; I& w; i! V) i* _! ~1 E{9 S* d3 [% T: Y0 U6 @( L; l4 V$ S
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    5 l) V7 \; z( U}& |+ L: I2 F7 p; V
    ; l# q6 T6 V) L4 S# F% @

    7 s5 u5 i: @( i6 S+ gstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    . ?( _0 X  j/ i' G2 q2 |6 m, c: @{) [# h1 s% N* ~/ N% i# T3 r
            BLOCK_HDR* pHdrStart;7 k/ |, u2 t" d% _
            BLOCK_HDR* pHdrMid;, O8 K9 I8 e) N) Q1 T) H0 z) a
            BLOCK_HDR* pHdrEnd;
    6 B& g7 E! ]  z0 @0 ^7 H6 O' k& K% o        char* tmp;
    ( |" U) s( `3 W( A+ D        int reducePool;; }* J) L; {" O) G( u

    + I* a3 X5 L6 |/ G$ n2 U' y        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */9 d8 Z- C( |% y) T0 K8 P7 w: `" b
            {6 T' o+ l9 x0 v) v3 y0 q7 q8 V
                    return (ERROR);* t9 O4 I: n0 T* x& V9 Y/ Q) @* U
            }$ a  c4 z& d2 D6 I: T" j
    + v. w9 u% h# Q" [
            tmp = (char*) MEM_ROUND_UP(pPool);- Y" M0 `7 B( Y! v9 e/ M
            reducePool = tmp - pPool;4 y( c- m/ n7 J: y

    ; d0 d0 m& [- i6 ~, ~4 V        /* adjust the lenght */* B6 Y, c9 {6 m3 V# O
            if(poolSize >= reducePool)
    $ h5 S& S% q8 L. V2 o5 b        {
    5 V2 J4 S! w' H& X                poolSize -= reducePool;4 f7 |! b) U& I9 L
            }: n, ^8 u. e5 \5 |
            else
    / i4 H  X1 H+ l2 K3 V# y        {+ Q- V5 o9 D# S$ X
                    poolSize = 0;, I# n4 u* y) b
            }0 _( `) _7 n5 L& M% e, ?
            pPool = tmp;
    $ Q1 d4 |$ y6 r        + t: [* E1 H; @6 B$ P
            poolSize = MEM_ROUND_DOWN(poolSize);
    ) [5 J+ c4 ^7 u( [        ) B- K. l5 f9 _4 N  O: R0 \# O, W8 ?
            /* at least one valid free block and three header blocks */4 ?/ G0 f! q/ E9 C
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    8 o; }( F1 N2 j% k# D6 p0 \0 @+ Q        {
    3 `; M5 S9 w+ l0 F2 i# v1 o                return (ERROR);$ N3 G, ~* I/ J2 y- a# W
            }
    0 }, K( p# Z; o! K$ F) O  G, O7 T1 L- e8 ^4 b
            /* initialize three blocks */4 D- L, d/ {5 f$ F. x: |+ g
            pHdrStart = (BLOCK_HDR*)pPool;
    0 a5 w$ n, X- X! l8 y        pHdrStart->prevHdr = NULL;
    , B$ E/ _% H0 s* T2 {; w        pHdrStart->free = FALSE;                /* never in use */5 I$ F7 i+ ?9 t* v$ O  [& T( Z
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;4 C& ~) j1 p! u

    : |" M" e/ `8 f. G3 P( @. h        pHdrMid = NEXT_HDR(pHdrStart);
      b) }% \" Q7 c5 h        pHdrMid->prevHdr = pHdrStart;) |. V( b7 U, }0 X6 m+ S0 y* ?
            pHdrMid->free = TRUE;                        /* the main block */
    & |, b% u  N3 B7 J$ h. f/ Z        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;6 ^9 Y6 f6 u2 [) i5 J3 A: u
    ; n  k' A8 R9 q$ r* e, |% k
            pHdrEnd = NEXT_HDR(pHdrMid);
    7 r2 B6 W- u  V8 V' V        pHdrEnd->prevHdr = pHdrMid;
    * n$ ]  l0 h0 a# J' c' |        pHdrEnd->free = FALSE;
    2 B- G* V5 l: w, m  S$ O' r        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;8 F7 A9 X$ J# h0 p2 i8 g1 u
    " I  F0 u# I) T# w" w' N
            /* TODO take sem hear */
    % K- ^, j; @  o( T8 O& P  K: Q        semTake(partId->semPartId, WAIT_FOREVER);) N4 R! P9 N1 A% @- b8 d  P
            : _: W5 A% r# {) \) G  J  u
            dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));
    - k: x3 x' j! t4 J3 K( E  i5 j        partId->totalWords += (poolSize >> 1);
    . f9 o, ]% l9 Z& U' }' ?! U
    % c9 r& ?' W8 ]' C  P$ S1 |0 F1 K4 _        /* TODO give sem hear */
    8 v  Z) V3 F9 D# n" W        semGive(partId->semPartId);
    0 N2 J6 T) _; y( I* y- J1 u& N: \
    ) U. i( L8 {0 F; ~% d4 m4 V0 e; j1 B( A; A$ z1 K& b' O7 O
            return (OK);
    * v# k$ H$ |3 [! ?1 ^5 T( `/ s}# j5 E4 A+ n& C2 d

    + q% j$ F4 q# W/ `$ h/ {void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)+ U8 u$ f, E" l9 n
    {
    ! W8 Y; w" ?+ P* b9 |        FAST unsigned nWords;
    7 ]3 }5 R7 U: @/ d        FAST unsigned nWordsExtra;
    2 r( J4 M$ v; K  K        FAST DL_NODE* pNode;
    / R2 K# l5 W% \+ A* k! s        FAST BLOCK_HDR* pHdr;! y0 X1 n0 L2 a. K. L
            BLOCK_HDR* pNewHdr;
    $ Q# x1 o) ?/ E: `5 l4 t5 a        BLOCK_HDR* origpHdr;2 C4 a0 }' W. q( k7 e

    6 v6 O6 h- {- `        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */4 G- P( Q- H0 w6 w+ F
            {2 ^- N2 `# L8 T
                    return (NULL);+ ]  D; |0 [: c8 U
            }' D$ j# |7 O% C- }) X2 w/ `4 d; n

    " E, `6 l. V; E# ~* c* P( p        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;# w1 |0 u2 O" r; E3 c' y& f
    * ^# R% `& m. [
            if((nWords<<1) < nBytes)8 M9 R; f% V7 k" e' ^! M. E! S
            {
    : z3 q! E; W& O* H/ j/ r                /* TODO suspend the task */
    8 g# X5 m" E# q# U( }- t6 l                return (NULL);
    ! ]9 x- E* a, o. l: z        }
    ( \4 l1 o/ H' s2 v, x# x) V/ }! W( ^& [# N" m4 W: @
            if(nWords < partId->minBlockWords)
    ; c; A$ T; m7 `        {/ u& X" [/ [  \: A7 K& _
                    nWords = partId->minBlockWords;
    * L0 e* ]& F* W        }. X5 |( w* L) m! w1 B3 c
    $ B- Z; ?7 _8 }9 A& h9 a4 l
            /* TODO task the semaphore hear */3 U; [/ s. i: D6 n7 V4 w* D
            semTake(partId->semPartId, WAIT_FOREVER);
    6 G. u. ~$ Z/ L4 T; G: |% A, ?        pNode = DLL_FIRST(&partId->freeList);
    8 Q+ {5 o8 ]  Q3 M        nWordsExtra = nWords + align/2; /* why? */! Z& P8 P- R" U& X$ }

    " H( P! o! L* V! A  h! v* h        for(;;)
    1 j% _5 F. U+ [7 X        {
    4 G5 f. `( c5 S5 ~. Q; O6 ~* h& G                while(NULL != pNode)3 v5 }/ Z! Z3 u6 F
                    {- ~0 `  c% T7 O$ D* z. A
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    % b, m) i. K6 d3 z' P# \                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 3 t, H( T/ x. F' I/ K
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    0 w: ]5 S9 Q% F$ z1 s$ x- ?                        {/ [0 [0 ?/ J: h. s  H4 [
                                    break;0 M; c8 S* `5 `* V  O. u: U
                            }
    % T+ L. C2 ^# r# K: G7 A) c; P: q$ g. o$ b5 T
                            pNode = DLL_NEXT(pNode);8 _- y6 Y" N6 _  \, a
                    }: C4 M( ~( C6 p, r
    0 b( H$ K, i, R; d' F
                    if(NULL == pNode)# }. v$ s7 \# m
                    {
    % }# V- Y* i5 t. l4 V/ l) I                        /*TODO give the semaphore */
    4 I: L+ B$ t% |, K4 g# m                        semGive(partId->semPartId);
    ! Y6 D9 M5 Y0 O* K( |8 V) K) A- C6 ~9 J                        return NULL;
    6 d, P0 s, _; Z% A                }
    " K8 M- b& I- ^. g1 T  Y( v# [
    + k# {7 Z0 e& ^1 Z                pHdr = NODE_TO_HDR(pNode);
    - n/ ^2 [! o9 N1 H                origpHdr = pHdr;; Z: p: W0 f7 L8 a! P
    8 C. N' i" A$ h/ N) d
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    # Q( w1 t* U- W% ^1 P( e                if(NULL != pNewHdr)% O* \% v! p# m! h
                    {
      S* h, N& d0 Z# M$ M5 f                        pHdr = pNewHdr;5 q4 r- E6 }$ O* ]6 u1 D6 I5 M% o
                            break;4 O! \3 ]8 S( Z+ c* Z+ S* L1 h
                    }! h2 {% ~9 G% _, Q3 ^: n/ S

    0 b5 a  ?6 ^) a8 S                pNode = DLL_NEXT(pNode);
    , w& D+ S- w7 [9 ?8 J        }
    ) K% T' e! c$ x' {9 D7 S8 O" d5 P) \% U! K
            pHdr->free = FALSE;
      I6 p$ h+ s! D/ ]- B        partId->allBlocksAlloc++;
    $ V: ^6 \& G" B* ?4 @        partId->allWordsAlloc += pHdr->nWords;" P, ~7 P. f9 V
            partId->curBlocksAlloc++;
    - H& ]+ j/ J# @! x& r; Q& ]        partId->curWordsAlloc += pHdr->nWords;
    ; d9 `  S2 D+ Z/ j9 ~; |' {/ a$ \- ]+ [" e+ E4 ?5 }- m, Z
            /*TODO give the  semaphore hear */
    / `0 X+ v& Z5 q        semGive(partId->semPartId);
    , j& P  E6 m; L! z2 O7 i, ~" {- @        return (HDR_TO_BLOCK(pHdr));
    0 ^) Q1 i" B" p        $ a* N2 @/ a3 ?2 a1 M, U/ X
    }
    ( G4 E# ~; I2 l! X' g) ]* C
    % H5 P& q7 u0 m5 Q# P/ tvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    6 I6 j, n' z! d6 {! T8 Z/ W" B{
    8 T* \) X  Z% I3 J, O        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    - j6 ~* |; N1 |}: T2 ?3 y9 M4 P$ s6 ?* g8 v8 r9 F) S& S

    9 K7 Y, L5 L. P. D/ DSTATUS memPartFree(PART_ID partId, char* pBlock)9 n! u, @- i1 }' Y2 M) Q# y& ?6 S
    {
    " ~5 t$ j: y" b7 y; ?        FAST BLOCK_HDR *pHdr;! h* C& O: |& n
        FAST unsigned   nWords;; `* |- K7 \- A
        FAST BLOCK_HDR *pNextHdr;
    1 X. P/ W9 i) Z1 U: B- V0 _$ p5 I! @0 V
            if(!IS_CLASS(partId, memPartClassId))2 M2 [# m, }, I. Z) r$ |, _
            {, p6 [7 b2 m/ [# o4 q$ `* z: T  j
                    return (ERROR);
    1 V# y( H  o' F- d0 u5 Z& O2 v        }, n9 L5 d, I' ]* S  J8 w
    * V" o* {1 H% q6 H/ K3 I
            if(NULL == pBlock)  [7 l& X% O: w9 Q. V# l% c
            {
    + p5 U; C! D0 q/ O3 m% S                return (OK);: S0 e6 Q6 h. t7 w
            }
    9 Z# {: f6 J" {8 x( }
    / b) i- O' |( z$ o: f2 d        pHdr =  BLOCK_TO_HDR(pBlock);8 t4 L. f2 a# W: W" K) j

    & i8 Y' i5 N! _9 A. X' `" q) h        semTake(partId->semPartId, WAIT_FOREVER);% T* y9 }$ ?3 g) T% ^9 A/ _

    9 H8 \/ f4 j, T9 y        if((partId->options & MEM_BLOCK_CHECK)( C0 F" q3 \, q0 p6 K. X% S0 z
                    && !memPartBlockIsValid(partId, pHdr, FALSE))4 T* I8 f! |1 p, z) f# k0 H1 @
            {( c% B$ C0 J* t! U1 m' P
                    semGive(partId->semPartId);
    2 h* j+ C- N3 h# A( i  `2 Q3 s                return (ERROR);
    . m+ t/ E; L8 @3 @* d        }
    . V' ?0 s  x/ N* s9 t' a& I6 `. E" _9 T# |$ N" ?
            nWords = pHdr->nWords;
    & I: l  }: z$ O! {$ k' D! n        if(PREV_HDR(pHdr)->free): a* j4 l# \; S7 J# I
            {/* the prev hdr is free and than coalesce with it */# C! E( D) l+ T2 b: a9 X
                    pHdr->free = FALSE;; A4 z2 a& N& w2 b- j& I% _9 e
                    pHdr = PREV_HDR(pHdr);2 `, ^3 ]/ u/ G3 F
                    pHdr->nWords += nWords;
    - B4 w6 x" T* Y: G0 K6 V  \& [% ?        }
    ! h: ], S8 v! ?9 w& L8 e9 W0 Z        else
    5 v& ]8 G  N9 a& G: \4 j# K        {
    % \) N: {) Y/ B9 E                pHdr->free = TRUE;4 ]4 z; B+ P8 L- X& M
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));' q1 \7 Z! v3 `% p( t& ]) @; T  W
            }
    0 V; s1 @9 O! v4 e2 u# J1 f9 }5 P+ f& ~7 P: b9 j
            /* check to coalesce with the next */: k2 @8 R: S) L( @5 S
            pNextHdr = NEXT_HDR(pHdr);* g5 O. F  ]1 I9 K. Y% [3 u
            if(pNextHdr->free)
    . k. a* q3 R9 `8 s# L        {3 C6 e8 F1 a/ S" q
                    pHdr->nWords += pNextHdr->nWords;
    1 Z# ^% Z# C: a& }5 f4 T                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));7 ~" L4 X$ F& m
            }
    3 ^* e5 P# u' m: g  Z. ^) k$ o0 B7 u6 m* F5 q6 C
            /* cannot use pNextHdr->prevHdr=pHdr hear */
    / ~9 H% M* J  f3 B! J        NEXT_HDR(pHdr)->prevHdr = pHdr;& k% G9 d2 N- z9 y

    * U( L6 S: N- R! g5 X        partId->curBlocksAlloc--;  R1 F/ _* w7 h% Z
            partId->curWordsAlloc -= nWords;7 P6 V) B7 h, {9 r
    " W9 u+ H+ b$ j. s5 A% |
            /* TODO give sem hear */: p7 I7 o8 S3 n
            semGive(partId->semPartId);/ t0 j  V1 `. f8 U/ F' u$ X- s& b9 ~
           
    ' a6 S( [5 Z% c/ N) p, J/ f        return (OK);% Q! P6 B7 n. A% v/ v
    }" y" ^) E4 O9 w* i% Y

    9 W# \9 n# Z0 c: {( k7 b; |/ h5 N+ i' qstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    9 i! r. w7 K; q0 R; q+ P{
    . [5 ?: d* p$ H- d" {3 i/ D- t        BOOL valid;7 i& J8 M" @) [$ W4 {; Q+ c# q$ W
    6 {* p8 O* d/ S% t+ T( l3 ^
            TASK_LOCK();
    9 q: H& P/ F% z- x  o, l6 U0 k        semGive(partId->semPartId);
    3 }, j5 Q! H, C6 \0 j* A& o        3 \- K, \4 J5 o
            valid = MEM_ALIGNED(pHdr)
    ; o7 U7 o' p9 e7 }. Y. Q        && MEM_ALIGNED(pHdr->nWords*2)
    % c$ ~7 |1 a" x. t$ o        && (pHdr->nWords < partId->totalWords) % x0 s$ n7 }/ j; X$ ?2 U' ^
            && (pHdr->free == isFree)
    3 l& I7 x9 a6 m" [6 ~, h& I! w' P        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))/ W( {, y/ H/ O9 v/ {: Q) c; E
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    . k5 j. z1 k6 u$ f       
    1 n& P2 m- \) a' @. J        semTake(partId->semPartId, WAIT_FOREVER);
    & W6 ~* g- ]  z% t  {, h        TASK_UNLOCK();
    4 v3 K; t+ G+ a' x/ _3 O2 ]- [- ?6 v& ~, u
            return valid;
    # W% c  p+ I; ~3 T& \9 y}
    $ [( S7 ^  {6 l$ ~+ X5 ]
    8 J2 X3 M1 Q3 o* kstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId- v+ {! k6 _6 l
            , FAST BLOCK_HDR* pHdr
    8 p$ H% l7 U7 X/ Y! F        , FAST unsigned nWords
    1 a" v1 X% F, L' F        , unsigned minWords7 a% Q( t0 I! i
            , unsigned align), S4 J1 ?+ \5 d& w
    {
    4 ?2 ]0 w- o0 j  K$ Y3 N        FAST BLOCK_HDR *pNewHdr;: I" l( q/ T2 l+ L& G% ^
        FAST BLOCK_HDR *pNextHdr;, P/ T/ x6 x! q8 X- n
        FAST char *endOfBlock;. Q6 v. ]& E- w# p9 a
        FAST char *pNewBlock;
    - D  E+ \& @8 ]/ A3 J5 N& ?    int blockSize;
    5 s1 z8 S( X. L3 A, ^! W# l4 V* a, T2 D
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
      T/ f) W6 M3 l. c5 M% }* G, e: W% O9 {) ?7 B; V) e
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    9 A/ z! w, S8 G' x( A3 X
    7 l- m, F" x. x3 G3 Z  d        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
    2 ?# O# ^: K2 i" A8 C% {5 ~; m, C0 s) P6 h  @+ b
            pNewHdr = BLOCK_TO_HDR(pNewBlock);6 g2 f5 x& X" L8 K9 X

    1 k. p3 `! t: A7 b        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;' Z- g. K* D/ R

      Z4 l, Q: m* o3 f        if(blockSize < minWords)4 W" Q+ q" Y5 w* m' V
            {* [; ?% ?4 w& D  c! h; D
                    if(pNewHdr == pHdr)
    + o* y! a% ]# u/ s                {* U  d& Z/ ?+ D; g, B# ]1 i; e5 ]
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    & R" V4 i& P1 T$ [7 l# m8 {                }
    " }: s( ^! _7 {9 ~2 }2 f                else
    ( x# j5 N; o/ I0 a4 z                {. C9 m. p0 M0 v$ \5 a3 s
                            return NULL;% t& I0 x, @# N5 _& E# l7 I% r
                    }
    ' G- Z/ t& F9 u6 B        }( r) S3 Q/ q2 U" P' u5 q& e6 f5 a/ i
            else
      f, f" t" M5 g, `0 ]1 |        {        /* recaculate pHdr */' @& [: H. o) O% ?! P
                    pNewHdr->prevHdr = pHdr;
    / t( U  I& v, N/ p( L+ x                pHdr->nWords = blockSize;
    # _4 i% I1 y  ?! I! m, D- F4 K3 B        }5 a' \4 w, o- a$ Y, V; {$ Z1 I

    ) U( g6 _2 v* V' S' Q0 p% {7 ~        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))% X- r( P; U* I
            {
    8 C7 `9 q' N3 ]9 O: T6 s! o" G                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;7 m5 Y) c  ^7 D
                    pNewHdr->free = TRUE;
    ! z% E; k- N9 W/ c. `7 T5 |1 h+ a, y/ j' V6 f8 g  E
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    9 {) b( m9 A- c2 A# Y4 {! @- k        }
    " b, N- Q9 J% p$ q8 e4 Z% o        else
    " W9 ~( t" s# h3 C, n: _        {/* space left is enough to be a fragment on the free list then */
    ( [7 y1 d$ W2 G" y; Y9 [9 E                pNewHdr->nWords = nWords;
    " [9 i2 F6 ?4 B" m0 T3 o! o& \1 g                pNewHdr->free = TRUE;3 U. P" ~: Z8 _0 d7 M+ e

    : X5 H8 ]+ v5 J$ @                pNextHdr = NEXT_HDR(pNewHdr);3 Q. d" h$ P4 c4 X7 F8 n) f
                    /* words 包括BlockHdr */( }+ G* P8 X9 Y7 ^+ @
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;' Q2 @" q* m0 Z& _* p: W1 y9 Z0 i
                    pNextHdr->prevHdr = pNewHdr;5 ~: u9 \" U9 V3 j- \# V5 \
                    pNextHdr->free = TRUE;
    ; \/ w5 L' y! B) {8 f! m! b
    9 a0 y+ H0 P+ o" B; n                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));0 k  I  u. u7 p, b$ D* j9 ^
    ) F, F" D5 k1 O$ v3 E% [0 i
                    NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
    + P1 n5 e  e, D% U4 s7 I, k. D( x- A        }
    5 }5 V, c8 A* ^/ R6 f6 _& F2 r' Z) a7 g) v& W2 W, z
            return (pNewHdr);
    % X: D# Z' q5 u8 `}: N' C* w- E( o% T
    " z; |, c/ g* x
    static void memPartSemInit(PART_ID partId)# i; c; L. q$ h! k* m1 o
    {. z0 Y" i1 ]" {, B# D5 g
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);! O: Y6 N0 V- Y$ i
    & k3 Z$ K( g3 @+ c: f
            partId->semPartId = &semMemSysPartition;
    % P1 z8 n  J, e}
    1 a# Q# C8 `/ C+ y. F0 [
    ( d5 j# j$ b& a' ?: H/ k# Bvoid* malloc(unsigned bytes)
      d3 E. z3 j5 {{
    ) _% G: G6 L$ e. p0 h        return memPartAlloc(memSysPartId, bytes);
    % v* m; E% ?$ ]. q* `}
    ; }/ Y& [) b7 l/ `  t4 @; o4 g' v
    void free(void* p)- g7 h. i5 `+ ]1 F* e+ I) Y- H  w
    {6 f0 w. l1 S6 l: b! f
            memPartFree(memSysPartId, (char*)p);1 b! ?8 R& X6 P  l0 P( o
    }
    4 ~. S7 `3 |' j, w: _5 w+ u
    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, 2025-7-28 16:51 , Processed in 0.702627 second(s), 51 queries .

    回顶部