QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2883|回复: 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++下的版本,更方便调试。有需要请留言
    - X. J% n0 q0 w9 q( k& n+ t2 l& F( G2 u! j- Q# |* }

    ) \) `* U& ~, _5 k$ y& ~5 ]6 }" q) @0 v' F$ n4 {
    *\file' E! N9 u$ V* w/ U* T# w0 W# T
    *\brief                3 `1 q1 B# k, W
    *\details       
    & \5 j4 X6 g7 F# B# C( I3 W *
    ! |$ D: a: P) h1 \" z0 D; Y0 d *\author        Janson! Q' g5 ?8 [# s, Q9 y4 t; t8 J/ e
    *\version        7 u" z+ v7 Z# c, Q( W8 P
    *\date                04Jan12- L9 g& u* a1 Q3 v0 ?: h: E
    *7 M7 I9 z% \$ J; ^* O- \: p
    *\warning        , C/ z* D8 G8 h! q$ L8 B3 }
    *& e" F0 C5 ?7 r, j+ x4 m) V6 G6 b
    *\history \arg        30Jan12, Janson, Create the file
    7 @* U4 c  Q% F* \- i *        modify from VxWorks source8 g4 |( a% Y( U8 p
    *  Legal Declaration: it is for studying VxWorks only.0 R. R9 o6 z6 O% }0 a$ c9 }; o
    */
    5 x" e" l9 R" U3 ?+ D! v  I#include "includes.h"
    $ e5 l  W' I3 o: x1 U
    * l$ w7 M3 V' K% L/* The memParLib.h file is hear:
    " q$ g/ I& q1 Ihttps://code.google.com/p/vxwork ... rivate/memPartLib.h
    : c, c0 s7 r2 A( o* f4 R) c*/" D( S* R' q5 ^9 M. J
    4 n. m; T  G# Q1 F" F. N( t
    /* optional check for bad blocks */
    : e: r: g; n3 }
    0 e; R. C* v5 ?; e( S7 |1 [* ]#define MEM_BLOCK_CHECK                        0x103 X4 ?5 K- H; b* D6 x; W/ }/ J

    " o0 }0 w' v* z$ @& m0 x' K4 s, q/* response to errors when allocating memory */
    6 h2 I9 K/ w$ T4 F9 r. i& T
    5 E, w0 _! r- U. `( o( D: O9 B#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    $ i+ b0 t" ~/ r  \: l#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x408 p) R/ U! `& F) n/ d1 K

    7 Q: [: R9 o2 z: r/* response to errors when freeing memory */" E% P$ G7 V% P& M* l9 d, N

    ' E6 N% d* s; T. v% _, J; K1 q6 W#define MEM_BLOCK_ERROR_LOG_FLAG        0x80' D, ]* `' U$ e5 A# B
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    5 W" n- L9 b& U
    ' }; I) y: ?6 ~) W#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
    # S" W( q2 a+ W( y1 f0 Z#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)0 j- U: ]( a/ f# Z. z

    ( I+ U+ ]8 r" |+ N$ g& y7 H#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))0 k' f1 }: k7 v( x
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    " u5 ]; X' B8 |4 M                                                sizeof(BLOCK_HDR))): G. c3 a6 P+ k7 m

    9 k# e+ x4 I; n7 A" l3 E#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)' q( \/ z) ?. V  [8 f
    #define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \1 R5 z/ c4 Q( y/ N! @* k
                                                    OFFSET (FREE_BLOCK, node)))
    ' f; X8 f5 Y0 U* i) K0 m; y( B
    . K1 D* X, c/ A8 m1 qstatic BOOL memPartLibInstalled = FALSE;  x$ n3 J) m2 ~2 y
    4 y8 z/ K8 I8 h
    static OBJ_CLASS memPartClass;
    ( m4 I: i- ^6 a2 e4 ?CLASS_ID memPartClassId = &memPartClass;
    ) ?1 T4 |6 F" d- y0 D4 p% r0 |4 t) A$ e7 C
    static PARTITION memSysPartition;
    - f3 g: n  N( QPART_ID memSysPartId = &memSysPartition;0 Y! z1 l6 f( a) ]
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    . I! m! |; C/ [8 v& d" S1 N/ A( x
    ) H9 Q2 x: R  e9 i/ {( \) c# p/ B# estatic SEMAPHORE semMemSysPartition;
    9 g' c( V/ Q9 x8 T5 H. K/ J5 o9 C% |% s
    static void memPartSemInit(PART_ID partId);
    7 J$ ?5 o# d  H4 R+ s) S  q5 p0 {. H
    & `4 x0 r* M6 c( F$ }% u7 aFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;( |" j! w7 m+ a* m# X7 |3 ]4 e( y
    7 h! ~! Z3 S) ]
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;7 ?7 v* ~. z8 p
    + o4 J6 Z+ V% w. T, j4 Z* }' g
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
      q; S% a" k% M3 H: I$ k+ Bstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId( h& |# O3 x3 J3 W8 z  g% I3 t; `
            , FAST BLOCK_HDR* pHdr6 b% m" J6 p* j* s
            , FAST unsigned nWords
    : Q2 n  U. B, w6 t/ @        , unsigned minWords
    ' V7 ?; `9 B5 T& W' N5 ]        , unsigned align);1 n1 h! n; ^0 u2 O( @8 x
    3 b# H' g# O3 w* i) E
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);5 x9 \1 c* B5 }) n$ ]3 D
    ' E3 F% l; i, Z  A
    STATUS memPartLibInit(char* pPool, unsigned poolSize)
    8 i' v9 {1 }* m! m% w% w9 H# ^{/ h) i. f% i- G, g' @, x0 }! I
            if((!memPartLibInstalled) && ; _" {, ~4 h% H. J: z3 q# a2 l
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    ; P9 Z" j9 B! t* K                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
    , Z6 I, W+ p7 M        {
    0 b7 K; a1 q; x- Q+ ^                memPartInit(&memSysPartition, pPool, poolSize);  L9 @4 k  I, m3 [3 Z0 l: j& Y( k
                    memPartLibInstalled = TRUE;
      b- X+ O  ^& `9 i8 j0 z4 m        }
    6 `2 I% o3 X3 R% J; Q( z5 n5 r' ]' w) @! S- I2 z
            return ((memPartLibInstalled)? OK : ERROR);
    / F& g! Q$ g) Z}
    * `1 K/ }8 Q0 j$ r, q  L3 f! m( J) k% v9 M2 e, ?4 R9 l
    PART_ID memPartCreate(char* pPool, unsigned poolSize)
    ( z! Q: S, K2 T* d- m. z8 C( M. |{
    . w5 ^" j0 b: b  I0 H. _        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);
    ; a- P" D' @) E; h5 _' p2 F. S) J9 n, r
            if(NULL != pPart)4 c1 b1 @  O) ^& o8 k  P
            {* z" z  c; J% j% e% p/ Q$ ?
                    memPartInit(pPart, pPool, poolSize);
    & ^3 P7 R. h% [/ o  S        }4 j% n( T1 P6 `

    ) m. e! Z7 c+ i& F3 ]/ J        return pPart;
    & g, B; y$ k5 x* n}
    7 n- |; R, A; c! S" f4 h; n; [2 K, h- l/ ]3 k! \6 M
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)* p, S6 Y0 _  x7 U% l% D6 a
    {
    ; z  M# _' L( X4 K        memset((void*)partId, 0, sizeof(*partId));
    " g, ~( h9 t8 f, ]8 r. X
    / S# t7 N6 j9 I2 ~        partId->options = memPartDefaultOption;
    $ F$ l" U  p) ]6 S. g5 A        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */3 I# ?& m, R& L1 A# e

    ' ~& t. S) r/ O) E& t        (* memPartSemInitRtn) (partId);
    - n# ^  m5 V0 f        ) W/ @) j& E( R, n
            dllInit(&partId->freeList);
    - R4 `7 e! q5 S( i) W( g! S9 }        : U  G: C1 N5 r# p, R7 e. ]
            objCoreInit(&partId->objCore, memPartClassId);) \9 F) E3 U5 ?& I
           
    0 g1 \* f; b5 B  w. p        memPartAddToPool(partId, pPool, poolSize);' }6 [1 J7 d0 m& x! r3 `/ l  }
    }- X) k! m: u3 W1 D) G
    0 ^* A9 H+ L( W, u/ y9 O+ Z$ Q. [
    STATUS memPartDestroy(PART_ID partId)9 H0 i$ o* D) ]8 \. `* q& Z9 @
    {& }2 k" s# G, R8 l  p
            return (ERROR);
    0 Q7 X4 D4 t) L/ y! X}
    # S6 L; G0 f1 k. n* ~! Z+ H% o) V, _% ?' O
    void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    9 W0 u$ H+ Y; W% V{, o; k0 I; {( ?; X& s
        (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
    + C5 v! t" k2 B, v/ |- \1 e3 V( _}
      x+ }9 h) n1 d; }: _
    , U- `2 L/ S  r* V
    5 f8 H$ `' }, Nstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)4 U8 n5 z4 A3 ?; n) n
    {
    + u& s3 U7 _, U        BLOCK_HDR* pHdrStart;
    2 T) e- _/ |' ?5 m        BLOCK_HDR* pHdrMid;. D9 Z- Z: {) y. D- P9 Y& u- ~
            BLOCK_HDR* pHdrEnd;- p* C4 f% i6 n
            char* tmp;/ D$ @% x$ `& ]& p1 l
            int reducePool;3 m" Z: M6 A4 m% `9 S* Z# l6 U
    7 I* d( l" Z8 t9 A: m
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    8 v) P9 Y( s: u) H% c+ w$ ?9 A1 M        {
    2 C8 `/ }: v% j' l1 l3 w" [# Z( ]                return (ERROR);4 l  a8 q$ ?$ q' e6 B! a2 H. `' S
            }
    - ^% y6 O" m" L6 A6 b4 e
    4 l+ ], e' G; g& P/ }        tmp = (char*) MEM_ROUND_UP(pPool);* ~4 R4 G. d( ~7 v! ~  S) ^
            reducePool = tmp - pPool;
      @0 A; s" Y1 b( m% I6 P5 V3 G
    / U2 T4 e8 z; K        /* adjust the lenght */
    / Z( L, @$ m+ Y. n9 S! E        if(poolSize >= reducePool)
    , C1 y9 @' N( s( W2 m        {. R8 M7 t" b1 V- o# N
                    poolSize -= reducePool;( q* W5 g% N' k, R& |
            }0 v* B( W; |. ^! F' T8 w
            else# D. S1 c. F+ H
            {/ E* R( L2 o2 p! W7 G1 e5 t2 ~
                    poolSize = 0;  U0 P" X: c7 E0 h5 H* z; v
            }# S. Z* R! V1 J7 ^( g7 g
            pPool = tmp;! h7 A( B3 K2 S0 S# M2 E
            " g& O/ x2 L: F6 ^' A
            poolSize = MEM_ROUND_DOWN(poolSize);
    ' v, {0 I7 o% l# r4 W% E7 O# j2 R& w        7 W9 {$ ~1 g( t5 j# ^
            /* at least one valid free block and three header blocks */
    # g3 X1 P/ |9 `$ l, b6 S) }- P& ?  _        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)! ^+ _1 c( h* ]! A* @+ g
            {% }0 Q' k5 b  M2 ^
                    return (ERROR);
    0 c* h2 S; Y; [( e/ A. Y$ ]        }/ d. T6 ~  S5 Y9 C+ m
    6 ^5 \! n: [5 ?; Y* d- {, h! f
            /* initialize three blocks */$ [# X9 L$ l7 L& G0 i. A# @1 J
            pHdrStart = (BLOCK_HDR*)pPool;
    % u6 w% [. E( u& j* k        pHdrStart->prevHdr = NULL;; c0 s7 h, @- e9 x; W$ x
            pHdrStart->free = FALSE;                /* never in use */
    - `+ a7 M1 k# m7 x( M0 l) r        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;8 @. T: |+ B) O* F. W5 n

    : d; V" x( E( B        pHdrMid = NEXT_HDR(pHdrStart);2 l" Y- p8 Z" S; {
            pHdrMid->prevHdr = pHdrStart;/ v/ z2 \5 q/ x
            pHdrMid->free = TRUE;                        /* the main block */
    : V& G$ M' N0 B        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;, D4 l) a5 B1 ?& x: c

    ) @( J/ Q+ h( a. L$ v        pHdrEnd = NEXT_HDR(pHdrMid);
    / [1 |3 y) {+ w4 Y        pHdrEnd->prevHdr = pHdrMid;
    8 b, a$ c) P; m- ?9 s3 M        pHdrEnd->free = FALSE;: U9 Y2 _) V8 e+ m% ~. n2 a/ G( @
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;, S! I# v0 E3 h) i

    * D. ]; T! D/ Y" ]        /* TODO take sem hear */2 p) p. H* g* o  }+ S6 j
            semTake(partId->semPartId, WAIT_FOREVER);
    2 f- v, b( }& K) z8 v- T9 M       
    % O; ~& v( ?1 t' J+ i        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));. S) |1 T$ r4 |  X2 ?/ ?
            partId->totalWords += (poolSize >> 1);# M) G* c3 Z2 }& `( j
    & `' W0 P9 t: {- G8 v# s7 h
            /* TODO give sem hear */
    4 g/ v) x0 ~/ N" d3 d1 q        semGive(partId->semPartId);
    & Z4 K( G+ {# M
    7 ]% O" P( M/ h* N0 p& }+ W6 k- J
            return (OK);& ^1 B4 M, l6 C3 ]% @% K
    }: C3 ?* ^* w0 t5 T5 M7 o3 y' r3 l
    / u/ r3 c% }, ^5 H3 ?
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    $ H0 M8 q( h+ {' X  I; R3 E{
    . G7 @/ y: D7 C/ X; l. V  H+ ]        FAST unsigned nWords;
    - B% P3 D% G' y2 D3 \        FAST unsigned nWordsExtra;( a5 d' }; T" j, d
            FAST DL_NODE* pNode;
    ! @+ |9 D  k! H7 E        FAST BLOCK_HDR* pHdr;# t$ A7 `% {; n& t# m* g
            BLOCK_HDR* pNewHdr;
    2 q7 b! S- y; P4 M; `+ V; b        BLOCK_HDR* origpHdr;$ i( }& n. T) M% h! b% @
    4 n8 l$ G- _$ x0 ]0 A8 b4 t
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */2 l* @. o8 J  N
            {& E6 y* q- \% y( m5 c
                    return (NULL);
    # A  D4 }6 r* o4 {        }, s+ ~" k3 b( u' s% T! L: f

    * s, e7 r( p. N& x/ P        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;+ E! V6 p. l2 u% E- x
    8 A0 j) d- P: i8 [, m  }6 p% V+ q
            if((nWords<<1) < nBytes)
    - ?( K5 Y' L6 Y! V        {
    : X& g; C$ Y, z0 |5 C                /* TODO suspend the task */" A$ _& D! Q( G4 q4 d  S3 X" O
                    return (NULL);! }, w+ F2 M9 s6 C! a2 f: g3 @3 s
            }2 C' f/ m0 y1 ~8 s1 B. Y* s" ?5 n: K

    # H4 V6 Z- R! h; Y4 \5 r        if(nWords < partId->minBlockWords)
    8 o& r* Q3 a" Z% d* Q7 p        {
    ) F3 i% y1 ~9 @3 W3 |; G7 z                nWords = partId->minBlockWords;2 V" H& I  K* H' {6 p3 i( H0 G
            }
    . @' E) c8 F" J: G7 }7 S) n  H% S) Y" d  [) b  l
            /* TODO task the semaphore hear */& G( e! _$ u/ @, ]- }( w# e/ Q
            semTake(partId->semPartId, WAIT_FOREVER);4 u2 O6 n4 a' @5 ~
            pNode = DLL_FIRST(&partId->freeList);9 ~3 Y. b  N  C: ^% P( a8 z
            nWordsExtra = nWords + align/2; /* why? */
    7 C2 Y. _& K9 v2 e
    8 P3 w9 d0 ]) {9 k4 t        for(;;)
    $ J! x2 \& N; Z# t2 v  S! a        {
    - V7 R% M5 |" X) U                while(NULL != pNode)1 W* G% m- o) K  z4 ]
                    {
    4 S4 B7 {  v9 p/ ]- j/ P                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    " D0 @  A  B0 L6 S5 x) d                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 9 J% U8 C" ?! |% i1 E, q
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
    / B) D) {( o& \- x( \$ c                        {
    ; J: C9 d. ]& S% q7 x4 F                                break;
    ! A2 }. v  w' ~  ]0 O& M- A1 G7 f                        }
    % s- H) Z  U+ R* I0 H9 ~# `1 Y# ?0 Q; r  O8 D- G* `! d3 o& s9 q# j
                            pNode = DLL_NEXT(pNode);
    " @  w- n# m. e: H3 D& T0 }9 a+ |! E                }: [: q  Q* o0 o6 h2 Y' T
    4 t' P$ Q  |6 d6 a4 t7 |
                    if(NULL == pNode)
    5 b$ Q1 i) a. M) b/ h                {
    & e! x+ ]' W. Z4 `6 h! t                        /*TODO give the semaphore */; l0 S2 o7 V$ J, u, \
                            semGive(partId->semPartId);
    4 p/ u% e6 g/ m                        return NULL;) A7 `& z6 z( V
                    }
    4 y( O; p4 I/ [. e1 ~2 c, \5 _6 O. I  n* I
                    pHdr = NODE_TO_HDR(pNode);
    6 Z8 D7 f. U: h5 M8 `                origpHdr = pHdr;
    ) P7 ^  B" k0 I8 S; y5 X' p9 }; z8 T" G, z1 e3 H
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
    0 R9 }5 ~0 s  T* |% o0 N6 ?: x                if(NULL != pNewHdr)4 V0 C. w6 X5 @: C# Q% a- O
                    {
    4 p/ c, \" n3 q+ B9 q: n; h* O                        pHdr = pNewHdr;
    4 i8 h8 E- \( y8 Y# E                        break;- U0 ^* b1 Q3 @- k
                    }
    5 E# E5 B  n; ]( c$ b9 |: F6 X( |* D! @
                    pNode = DLL_NEXT(pNode);
    - y; D. {  V+ {2 q2 {3 t8 f4 N7 T        }2 x- Q  S8 m, \, }$ k

    2 @1 D& Q) K/ G7 [; P* ^: q8 x        pHdr->free = FALSE;; t) ^9 p% r# R+ c
            partId->allBlocksAlloc++;7 h4 u& Z4 {5 J
            partId->allWordsAlloc += pHdr->nWords;! _. s7 }9 |: E) e
            partId->curBlocksAlloc++;
    + G( D% Z' B5 C: W$ }; D5 F4 H" c        partId->curWordsAlloc += pHdr->nWords;' ?' z! Q/ U$ U) c2 S; o1 ~

    3 a8 d/ [9 A& b9 i8 d: L0 |        /*TODO give the  semaphore hear */
    3 F, u6 U5 c# \/ X7 B) ~' K        semGive(partId->semPartId);
    4 s6 _8 Y/ h6 T) N5 S+ w% A        return (HDR_TO_BLOCK(pHdr));
    0 C7 {. T2 m% s        , ]3 Q% R7 L6 j% z
    }
    ; o" @! C% i4 P  y& Q( P  b0 y. j9 m6 j3 I
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)$ K# |" R$ D' D. Z) z  m  i- s
    {5 t) n' ?9 J3 L' s) Z/ s
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
    / V4 p0 ?; H3 u( z9 ^8 c}# {1 @- L# m4 L( A$ P

    0 S3 p0 J% Z' u- e, w! fSTATUS memPartFree(PART_ID partId, char* pBlock)3 Y) {' \" }9 a# A/ Y+ x
    {- g  y; ^5 K+ T: F  o* X/ F+ \
            FAST BLOCK_HDR *pHdr;  e2 J. I7 }* w$ J, y
        FAST unsigned   nWords;
    7 P, n6 b, t: T; h8 ]    FAST BLOCK_HDR *pNextHdr;
    , P" u4 T  r3 h
      S1 J9 y8 D7 U! t, \        if(!IS_CLASS(partId, memPartClassId))
    ( D2 M( \' w  y7 c4 {  p5 X  a" F        {
    , Z9 p# q2 [" K: c                return (ERROR);! w8 r. F/ J8 B5 q
            }
    , J) f! T( _* n8 O2 S0 \
    ( w+ @# n9 A0 V6 e        if(NULL == pBlock)6 U/ C3 n. h. ]3 A, j" q# `
            {
    9 n  C. e9 l5 B/ ?! B                return (OK);& z7 Z; @9 h9 \( G
            }! y- l/ i. m. ^4 N; P
    7 v8 G6 |0 G/ Y9 M! \0 L" g
            pHdr =  BLOCK_TO_HDR(pBlock);/ q- F: ^% D, a  }

    6 X, q* \0 }( q) @  M8 E: i        semTake(partId->semPartId, WAIT_FOREVER);
    3 q5 @  v+ v$ N
    ( J- g2 K. ]6 m% {        if((partId->options & MEM_BLOCK_CHECK)" H3 J  F( \- ]# Y. Q
                    && !memPartBlockIsValid(partId, pHdr, FALSE)). W. J6 _; a# c( p- y' Y& D# g6 ]
            {
    7 }% j, ?, B* ?1 ^& L. {* F                semGive(partId->semPartId);; A. e) A7 g2 D( K, I  `* t9 W
                    return (ERROR);
    4 L& |" J+ K* s# t# D        }+ x) V) v! t( h# j0 b- f

    * i- h' F8 {0 X+ K% K        nWords = pHdr->nWords;& z1 Y4 p+ b9 C9 n& v5 c" P3 z
            if(PREV_HDR(pHdr)->free)$ W. R! b: u1 I  A  G4 K) g* P
            {/* the prev hdr is free and than coalesce with it */# \# s/ ^. j/ W! ]0 ~
                    pHdr->free = FALSE;. l8 C* R3 T) [9 R; O6 m% l; K
                    pHdr = PREV_HDR(pHdr);
    0 N2 }7 ], H3 {8 x) j% [) m6 F                pHdr->nWords += nWords;
    3 s, H. B3 z1 ^+ v+ X        }
    % w( B( ?0 v& R% w2 K        else+ K- N$ C. x7 x0 w6 C. ~
            {- ^6 S+ O4 V  N9 t5 w: d
                    pHdr->free = TRUE;4 ?( V: H: T/ W0 T: Y( G( P0 e8 J6 o
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));
    - B8 A% W3 g4 F4 V: V3 Y        }
    $ ~% P+ P& R4 ~9 R7 d- W6 r! U# g- K5 R* Y9 M
            /* check to coalesce with the next */
    / D/ E1 N$ R" g/ p        pNextHdr = NEXT_HDR(pHdr);
    5 J/ z/ I% o+ R( r        if(pNextHdr->free)( z/ X9 H: W8 f
            {9 L. @# _  i2 s( ~
                    pHdr->nWords += pNextHdr->nWords;
    . R  S& Y7 d* z: z) _  U3 D                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));4 w# }& I2 J! M6 n& e! P0 Z: ?; T6 T
            }' k- b$ y9 O1 h4 }  c# s+ C

    # v* c( `6 X1 ?, I% S        /* cannot use pNextHdr->prevHdr=pHdr hear */
    " b! s+ y. J8 N% ]0 r        NEXT_HDR(pHdr)->prevHdr = pHdr;, S: r3 q/ d2 R
    ! m* E( n: d0 R0 `# a$ K+ n" Q; g
            partId->curBlocksAlloc--;
    + H, i6 h0 r4 L8 w" j        partId->curWordsAlloc -= nWords;
    9 M* s# `2 Z9 F, B$ c+ e6 A, v1 s
            /* TODO give sem hear */
    8 Z2 m+ X4 \* g8 t* J        semGive(partId->semPartId);! _: F# ]6 N% f0 }
            * M7 u, l6 V/ i( D8 `# c: U
            return (OK);3 K3 c4 a, w/ g) o/ S
    }# A, X5 Z3 G5 S! }5 U# G: k

    - }4 ~6 N2 g  q0 }6 ?static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    . w" o3 T# P) F( }1 u{
    & V4 N5 I& C4 i( W+ w- n        BOOL valid;
    3 S. m/ I6 _- O8 `$ a0 `% q9 W2 L
            TASK_LOCK();0 D* s( B/ S( Y; |/ F/ t2 t
            semGive(partId->semPartId);
    $ ~3 W( J! V' I, V        6 K% M3 {, H* z
            valid = MEM_ALIGNED(pHdr)1 m. e- \9 \6 u; Z* b9 N; J
            && MEM_ALIGNED(pHdr->nWords*2)
    % N3 s% ]9 j, j& [) S        && (pHdr->nWords < partId->totalWords)
    " U. N; W1 \; }' T        && (pHdr->free == isFree)- [9 f" O& T9 H  l
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr))). o! |" \! W. S( i9 @+ l1 b1 ?
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    5 ]& S2 T" p7 G& E- y        - W1 G; w$ a3 ^/ @
            semTake(partId->semPartId, WAIT_FOREVER);
    # O* ?/ M4 X, G6 Z% t$ H        TASK_UNLOCK();
    + r0 O2 D/ D  I; A4 X( |: t8 {" I' ]/ E
            return valid;# D/ {+ ^) F; v3 R+ O" Y$ t
    }
    8 c! Y% S, U, k. }. d8 r0 n1 f2 N; Q( w0 e' K
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId8 t4 L+ w+ y7 I$ ]9 x* r, w. T
            , FAST BLOCK_HDR* pHdr! v/ b7 M& \$ d- Z# B0 Q
            , FAST unsigned nWords/ l+ w; K7 X7 n% J" ?
            , unsigned minWords+ c* _! y6 k2 }/ r% a( r1 }( a& y
            , unsigned align)' J' `; m. L% F. Y  t
    {  o; ^( P  h* p; m0 F# m- Z0 G2 ~9 }
            FAST BLOCK_HDR *pNewHdr;* @: x* a4 o- u6 f8 B; A- O# o5 t
        FAST BLOCK_HDR *pNextHdr;5 e7 S8 _5 F; `+ j2 t1 H
        FAST char *endOfBlock;) }, ?% ^% O+ k. j. x1 ~
        FAST char *pNewBlock;
    3 x( `8 P2 x( S& c( A" d6 J6 y- V    int blockSize;
    ; z. r; `; J5 p8 P, g. q1 ]2 k* O! o- a; i( V- W# C4 c
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    & S4 K0 }/ ^2 e1 C1 U4 p& ~
    5 H5 t- u1 F" Y2 D        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
    : O% E; S* h7 C' z& h8 t7 w; p
    / G* @; ~0 w7 D) C+ ^$ d; r0 q1 i        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));( d8 ?: p4 m- o9 Q  i6 [6 r8 P
    + M& [) R8 G8 ?4 k. |- \/ v
            pNewHdr = BLOCK_TO_HDR(pNewBlock);& G" r( K3 O$ l( C5 @& X
    6 w$ R: [3 j: Y! ^4 H
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
    7 w6 a7 [* K, y9 K9 N- j  ^4 w* y# D- b$ ]
            if(blockSize < minWords)
    ( L" x& R( h5 {; W4 y5 Y! R$ H. s: W% G        {9 m3 I4 z$ Z7 g* O1 m. d" o/ E
                    if(pNewHdr == pHdr)& I3 J/ `" ?/ W) E( J
                    {* ~) A, [' D& z0 |. n8 W/ ~
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));9 I" b8 Q8 b. W5 C1 `( m6 N
                    }
    ( n9 g! n, p7 L. f                else, J( `+ L% k5 B" H$ d% F/ s
                    {
    ; Q9 A- t" L# c0 H4 [% Z1 a                        return NULL;
    ' [/ D7 ~/ G4 N+ l: B                }
    * [. ~5 w4 Q" o# m, c' ~$ B+ [        }* I8 t3 z: w# H  N, C* L4 T
            else
    * L; r& r, h4 D0 F3 Q+ F        {        /* recaculate pHdr */
    , J3 ?1 B) P; g# x                pNewHdr->prevHdr = pHdr;
    & R! h5 p* M, E9 K1 N6 i0 u' S                pHdr->nWords = blockSize;
    + J0 m5 ]# a: m: g, R$ J        }
    6 x, `; l! C" ?4 r1 }; n) h1 ~8 C- M$ w4 O
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    % g  a9 s5 l3 R% p  ]        {! n. O- X! A+ T- S8 J# m0 _
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
    : `' g9 ^. K* U9 O1 q                pNewHdr->free = TRUE;0 W/ M  V' d" `9 ]) _, L

    2 m7 Y/ u( Q' l                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
    ' J8 j- }" H6 g+ b3 d        }4 k# `& V9 L  C9 p
            else& m' n2 l; i$ X( `5 Y
            {/* space left is enough to be a fragment on the free list then */4 e# y' ~1 H3 c: L! [# j
                    pNewHdr->nWords = nWords;
    - A3 P' |: O) t" Z" N% {                pNewHdr->free = TRUE;. P2 r. M7 p' r8 h3 z# R5 i5 y
    7 v0 _) I( W2 ^7 Q* E8 Q
                    pNextHdr = NEXT_HDR(pNewHdr);
    6 B/ Z/ x: n2 ~) ^. _                /* words 包括BlockHdr */) ~3 i3 F, f  X5 J/ `5 p+ y
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    ; P$ V& y# \$ C0 T                pNextHdr->prevHdr = pNewHdr;
    * a  D0 \. ?8 M$ y1 f                pNextHdr->free = TRUE;! Q" Q6 U. A5 [# P5 L4 N0 A

    & n; l1 m: \* |' X% l                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
    7 r9 {" s6 P2 _4 q  I, s8 o8 F
    . \  F- F: N, m* f                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;+ }6 I; X) C. K  P' Z) o! T% B
            }
    1 S$ J. L% K7 i$ {$ g% R( k2 K" h3 R) y8 C+ \0 E/ ?
            return (pNewHdr);
    , [! S0 H+ x0 F* S}/ U) o5 ~2 l9 ?" n0 w

    - `' J( u+ r/ C3 q8 Dstatic void memPartSemInit(PART_ID partId)
    3 `# g6 E# ]0 q6 y  o6 L; h{
    & |  f8 J6 Z# {- Y% v        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
    7 T. S: S( U& T. w& ^8 _, q* ?
    # h# Q, \- B+ X3 b% E        partId->semPartId = &semMemSysPartition;
    2 z) d; x7 E( e  M}  s% F9 C: b1 F+ |4 ^
    - g, K9 B6 R) {$ O7 c
    void* malloc(unsigned bytes). ^: v/ v! K  a3 M: ]  l+ ?
    {
    1 W1 }* y$ f9 c: M4 s; G1 x        return memPartAlloc(memSysPartId, bytes);
    $ B7 s. `) S. Z4 j1 a}7 t" L/ A4 B' C/ e$ k6 T( k

    " f6 O; J8 i( l7 \1 Qvoid free(void* p), y8 Y0 r$ o# p$ v6 r
    {
    ! H0 J3 p+ y. B0 q: i+ X        memPartFree(memSysPartId, (char*)p);' ~" m* f0 D/ N  i) \
    }
    % K  A1 W3 D# }9 A* @% k  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, 2026-7-19 15:33 , Processed in 0.461445 second(s), 51 queries .

    回顶部