QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2862|回复: 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 F9 m7 Q: u4 l
    7 i1 E" x3 P# X. w- f

    2 Q7 w% A4 M1 X4 o3 E( E2 p$ R: P* B, }7 `; T
    *\file( F8 p1 W2 s% `& o. i1 O" l& M1 Q2 w
    *\brief               
    ! U8 p- Q$ f; s0 e9 I0 k+ i8 _ *\details        4 V8 l( G+ P" J& K( {6 G5 P4 [
    *6 Y9 E. ]6 k7 }# V/ U- t$ x! t
    *\author        Janson
    2 c6 X+ @* q9 o *\version        : m3 G2 A! u3 l" r
    *\date                04Jan12
    & _2 `9 k1 p/ q% u" R *7 m- E1 _. R5 m$ \2 E+ o" I% A
    *\warning        6 ]9 b0 D5 ]/ t0 U
    *
    , K; F0 \7 c4 k. G *\history \arg        30Jan12, Janson, Create the file! F4 F" |! k9 ^& |' O; M
    *        modify from VxWorks source
    ! n6 G. Q5 L9 W' p7 M5 K/ Q; e *  Legal Declaration: it is for studying VxWorks only.
    / ^( u' g$ ~+ G6 X6 t */  X/ C9 M# A5 Q' i; U2 B, H
    #include "includes.h"
    $ l# E" \: K  Z! O; a6 v+ B* L9 p) o" t0 L
    /* The memParLib.h file is hear:2 o4 A1 r+ |  Z! p
    https://code.google.com/p/vxwork ... rivate/memPartLib.h
    9 i5 {/ D  o  B# C*/
    9 C0 O; Q% K. C, b1 [$ V" [, s# Y& ]! z, ^: k
    /* optional check for bad blocks */
    1 t/ z6 E4 T# O) A0 g
    - k0 C8 L+ Q  W$ j) |2 R% s#define MEM_BLOCK_CHECK                        0x10
    - n+ C/ g6 }, u$ L. D7 I! w0 r, [# ~3 q1 Q2 Z+ Q, ]% U* s
    /* response to errors when allocating memory */! G  j- U! V( i8 u! O# Q+ a
    , h( r* s# ^4 s+ n2 J: e
    #define MEM_ALLOC_ERROR_LOG_FLAG        0x20- P: e9 q, C1 U7 C
    #define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    ' p. S) h2 |& l$ m( X2 D2 r; ?( D% |6 Z- Y9 {
    /* response to errors when freeing memory */
    8 z$ k0 h  h: ^1 d7 u
    - P, _0 d0 l5 _6 w; A#define MEM_BLOCK_ERROR_LOG_FLAG        0x80! ~' ~5 a6 D$ s4 _# F  H! L9 r- Z
    #define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100
    * |' Y6 @- z' g* [8 u6 d, k3 |1 n6 ~  ^0 H
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))- d; c& r: o. v0 @0 Y  `
    #define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
      P+ d$ v7 [) _8 z0 `$ ^$ d+ h6 k7 U
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))% v6 I) G. L2 X8 Q- j
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \' w, s5 o$ q9 ?% J
                                                    sizeof(BLOCK_HDR)))
    2 g3 _$ y0 B5 p1 z( U" V0 Z; t1 s
    ; b  j) @: T; m+ `#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    * j+ P- S" A  f, G& U#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
    1 x! o6 i; r3 g3 ^* U6 z                                                OFFSET (FREE_BLOCK, node)))
    ! j9 Z. _5 ]+ c: n9 g! J# T+ x( \; F1 V9 X2 {
    static BOOL memPartLibInstalled = FALSE;
    + g, u5 I( F( l9 K8 J! S( ]' C$ V0 v6 _
    static OBJ_CLASS memPartClass;& v) V. q* U: k: {% \; M3 H
    CLASS_ID memPartClassId = &memPartClass;
      `$ }% B. Q% z% @! Z: Z' T3 `$ ]
    ; ~1 D& S/ g0 n$ Astatic PARTITION memSysPartition;
    ' T: b" @" G4 E9 s) ]9 e3 M* v8 APART_ID memSysPartId = &memSysPartition;" a5 V* J' l4 }2 `! [
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;6 {+ k* ^; o' H% H3 r8 F" M

    3 v  d  ]' }/ @static SEMAPHORE semMemSysPartition;/ o! S3 P7 [* b) f8 K& a$ j8 P% t* m3 f
    ( O" n9 q( r( s
    static void memPartSemInit(PART_ID partId);
    8 h, B" V9 _) q7 b5 z4 I1 C5 o! R/ C- ^- H: {
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;; x* h' ^, c, [9 m. ?( a5 q, F
    6 F9 g, i' P4 \' k4 k2 A
    unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    & S, }2 C" p* N5 x4 f# Z8 D& ^) E* |( F- a* \4 N
    static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);5 ~% w. T" W8 c+ o; z
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId: J: d9 I. E+ S& a. N
            , FAST BLOCK_HDR* pHdr
    - y" H% ]' T7 [6 w* g        , FAST unsigned nWords
    ! M, N2 g* X! P* S8 _        , unsigned minWords
    & @5 L7 u& k( @" R% \# J) G6 h        , unsigned align);% _! b& o' w2 \! v

    ) ^; X  `: K" |: Z$ a/ istatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
    % K/ X6 a9 B3 x; @9 C) v- J' k% g  e0 E' q
    STATUS memPartLibInit(char* pPool, unsigned poolSize)5 E  V5 w2 Z0 \' \/ Y
    {* B* D; U, b! n8 ]* D5 k
            if((!memPartLibInstalled) && / a8 R% R! @" `$ m5 G! G* C( g% v
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    - |/ Q" ?" Z  d8 C% j0 z: x2 t                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
      J! h4 O6 t3 x        {
    ' @# E/ E& ~3 U' A. c4 s: c                memPartInit(&memSysPartition, pPool, poolSize);2 [/ W1 M. X" m% Z
                    memPartLibInstalled = TRUE;! ^9 |( {8 T4 X% Q$ f
            }  N- `# m# r  v. A" R0 Y8 i) f5 t0 s4 ?
    ) E) E5 [% `- g% ]. v1 V
            return ((memPartLibInstalled)? OK : ERROR);
    8 @* m. e0 M( E2 T2 }1 y}
    9 ~6 b9 O2 H" N2 R6 Y. h, E. ?' d7 u  A6 q
    PART_ID memPartCreate(char* pPool, unsigned poolSize)
    3 n0 {% E5 F# g* P{" u% t$ G6 g7 A: R; _; y- A$ \9 F
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);5 ]; k, S# d- }- C

    ; T; x+ ^0 v9 t$ Y6 R        if(NULL != pPart)5 i" `, A3 q1 z8 W: w9 O
            {
    * N1 {/ S* E7 Q. a                memPartInit(pPart, pPool, poolSize);2 m( _3 t7 X- z( d/ y
            }/ _: @, u& m6 H4 J3 T1 q

    ; J5 v# J# ?1 r* p( M$ Z        return pPart;
      X: k% g; j) g, L9 ^1 [  q& P% V* \; _}  o0 u) [8 P: s- p' Z/ D; Y
    - v# y1 B$ F( W% G% z' ^
    void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)& x% ]3 k8 E" s9 r# u3 ^! B) C( E
    {. F( z& s; N" Y* x
            memset((void*)partId, 0, sizeof(*partId));$ ]* J$ N8 N! C5 w8 A* q* @
    # g" d/ k1 \1 y; R& R0 c8 Q# H, F
            partId->options = memPartDefaultOption;
    1 W5 X$ [. p/ M4 N- [$ R* O  Q        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
    * V  L5 a1 Z* v  n) s, o& N* f' d6 Z; G# \8 D
            (* memPartSemInitRtn) (partId);
    5 ^! D0 n4 c; t: u       
    $ ?' L6 Y8 U7 M7 f        dllInit(&partId->freeList);2 N: S9 j- O8 @( k" q
            . a, V; @9 ]: ]9 `- o2 ?8 Y$ n0 }
            objCoreInit(&partId->objCore, memPartClassId);
    * Y) H, b5 k# @9 R        4 d+ A( n/ {* }, f# F/ L6 x: w. z
            memPartAddToPool(partId, pPool, poolSize);0 C3 e' ?" r+ {8 _
    }
    / j9 {7 X6 m7 @; D5 _" p
    ' P+ d6 p. w, S9 }+ G  KSTATUS memPartDestroy(PART_ID partId)
    ! x7 b/ \8 G( U6 \, s2 Y{5 ]% X/ Q1 @- i6 l. l; j
            return (ERROR);
    9 \) C# F, \+ ~}
    9 ~+ p4 p6 `8 n6 I  N! ^
    ( {; P9 i$ q& O0 v# Uvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)0 V; M( X" i/ \
    {
    & [9 E8 W* C, }, Q* ~: |    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);% h. G9 @% ^* ]% J& q' X
    }
    , T  q! g9 m* f9 X
    9 r6 s/ O+ A& h+ y2 n2 r8 [$ m9 X+ b6 c! r' Y4 @% J
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)( z+ w8 k- q$ q0 P" l2 Z( r
    {
    9 V8 F! p, s" {0 D9 I, \8 F& z- a        BLOCK_HDR* pHdrStart;
    + I5 R3 X# i: h) Q; D        BLOCK_HDR* pHdrMid;
    ; U$ U* {! f' {1 i        BLOCK_HDR* pHdrEnd;  \# i) v, ~0 R' d# R1 R
            char* tmp;
    ! r# p# s% A6 b- F        int reducePool;# c# U! S* M. j

    " ~+ T) v/ m" ~: R. z        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    ! r1 w# L" x& X* z" U( ~/ t  `        {
    ) @' A) G# M, z6 v                return (ERROR);8 r4 n+ s3 Q1 x5 {
            }
    - R2 B( e# f2 o/ H* [% \! m1 [& I- [6 _
            tmp = (char*) MEM_ROUND_UP(pPool);6 F- O/ i9 ?, h0 Y
            reducePool = tmp - pPool;
    & ^! J$ z. l0 `2 ]; z0 r6 D: n
    4 P. U- ?- \/ X6 r' o2 `6 v* f        /* adjust the lenght */
    6 \0 s5 J" N3 d5 [( d1 @        if(poolSize >= reducePool)
    / x7 A6 q; B/ d+ N8 }        {
    * w; V1 K) C1 |) n                poolSize -= reducePool;7 x5 }- ]5 k- e  j. H! v/ O
            }
    & w/ K; {: d6 C7 m1 B3 u        else% l, a$ T7 `) r7 E: a( F
            {
    / u* j9 O6 |' `! }/ t                poolSize = 0;
    6 ^% k1 O2 l9 R+ `+ a1 X        }
    : X2 i4 Q0 O" R7 t5 w% p- y  x        pPool = tmp;
    ! z2 C( Z: ]/ M: r       
    5 a5 h( C3 U& `) r+ _        poolSize = MEM_ROUND_DOWN(poolSize);! e) L0 ?  t9 j  i% U- t# |
           
    , }1 r& b% w: r9 ~' z5 s& R/ ]        /* at least one valid free block and three header blocks */* }7 Q) R5 ~$ y8 b. y. t/ Y5 Z
            if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    / Y; g- h+ t7 j0 m. Z' T: C        {( Y* n' a7 c6 b& Q$ f) \/ d
                    return (ERROR);
    5 N/ w# E+ J, u* P9 f        }$ u; Y3 r0 D% z0 ^/ r: N* `
    % [1 Y0 k, \- V5 k% M
            /* initialize three blocks */2 v4 Z8 Y/ ?7 m! L* X: B" w
            pHdrStart = (BLOCK_HDR*)pPool;# e! t( L+ B# k  C1 s6 U. |5 w7 p
            pHdrStart->prevHdr = NULL;+ g: H7 u0 O1 A
            pHdrStart->free = FALSE;                /* never in use */# A6 C" E6 X5 D2 g% `
            pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;  w7 {$ a7 Y# K* b$ L# _

    ! c# I/ K! C* b' p1 o- e        pHdrMid = NEXT_HDR(pHdrStart);
      M7 S  Z& A% B; M" v" M        pHdrMid->prevHdr = pHdrStart;$ f( `1 F' t/ t/ a0 B' i3 m
            pHdrMid->free = TRUE;                        /* the main block */
    * [# T$ Q/ p6 T        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;& j6 V$ ?' Z& r& Q: p' T+ t  F
      X, x* L: C" _3 h" L# d; d
            pHdrEnd = NEXT_HDR(pHdrMid);  q  A! n, b4 l( {
            pHdrEnd->prevHdr = pHdrMid;
    ) T. ]6 h8 }4 k        pHdrEnd->free = FALSE;& |; D) `/ x& M1 i
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;+ U; s- Z4 G2 n) a( |& j" B
    ! K. S* p* @0 V. s) V7 N' n) y
            /* TODO take sem hear */
    4 g5 A, N$ N  v" a* N+ I        semTake(partId->semPartId, WAIT_FOREVER);
    ( O3 d  ]: ^  I2 g* G; H- t       
    / j: k! y- w. f8 Z3 [- w0 I8 |$ B        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));5 D, P2 G) ^  a3 T' N, Y
            partId->totalWords += (poolSize >> 1);
    ! w% ]7 L" F0 B) O, _: i) W2 o' V- ?, K8 ~. N
            /* TODO give sem hear */2 Z# ]: w0 [* d8 o
            semGive(partId->semPartId);3 m/ ?! d4 U& T, `

    # z+ O+ z6 O" ~/ g( ~
    6 p3 d" v' c- O1 y1 h        return (OK);" a0 A8 c1 O4 C3 v/ b: K
    }+ u, E7 u! ^3 F/ ~& F' a
    4 r0 T! t7 `* w' P
    void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    7 b/ W" c4 O% i+ i5 \{
    ; p0 b* a+ G4 [9 A2 m        FAST unsigned nWords;; S8 D; ?, o; u* q& ]/ G
            FAST unsigned nWordsExtra;
    " j4 H3 v* ~2 X* A5 \! z; R1 O        FAST DL_NODE* pNode;$ {9 X# ^4 S; o0 a% c1 Q* S5 N
            FAST BLOCK_HDR* pHdr;2 A& N" m2 ^/ b7 o0 _5 ~! F3 z
            BLOCK_HDR* pNewHdr;  l% d" _; F4 @' o+ \2 v9 @
            BLOCK_HDR* origpHdr;2 U+ j6 }$ Q  j
    : t( S; C. g9 e5 O9 J; O9 l$ `% U
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    9 c+ U& _) r/ @/ J        {+ `2 _: L. G  I# {# ^4 X
                    return (NULL);4 x1 _' x* j3 v" p/ K$ _
            }
    ) c6 S/ K; p* j3 w
    - X% J. }. d% `+ i5 p; S0 t        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
    8 y1 G6 u2 _2 i9 h' _
    - q# N, o, C9 X# d5 c, h        if((nWords<<1) < nBytes)
    6 n8 Y4 I5 W7 g        {
      V3 G4 [7 \4 d$ p4 ?. c+ ?; n" }/ z                /* TODO suspend the task */
    + @3 K- |1 w5 F( W2 m                return (NULL);/ v# ]$ v" G( _9 ^& r' M% \& _
            }
    & g, u, ^5 ?, S$ m
    ' [/ ]2 ]  j9 M! ~6 Y3 G  P4 X" J        if(nWords < partId->minBlockWords)$ ~! P! g" O% d  A' ^& n( n
            {
    5 E$ j& t' O* a* ^7 |: R" S                nWords = partId->minBlockWords;5 J. ~6 |' \( \1 Z
            }. L  ~. g' ^9 ^; i$ @0 `

    & C# G7 A3 ]% S$ G# k/ s7 r        /* TODO task the semaphore hear */$ T; A* d7 z; Z2 S! A: D
            semTake(partId->semPartId, WAIT_FOREVER);) ~- O- n+ ~& t/ y5 g0 R/ Q' c3 E
            pNode = DLL_FIRST(&partId->freeList);
    ( a) h5 U0 E& V- h( |8 a: U        nWordsExtra = nWords + align/2; /* why? */
    , }9 g6 G# r2 Y1 @
    0 `" b/ W1 ?* s( q* k! `        for(;;)6 c$ l+ s- G9 r. {4 M3 H5 }
            {* e) [0 X0 F7 I9 _3 M
                    while(NULL != pNode). _* {9 V# Z8 O$ S- R8 l5 B8 O8 U4 p- Q
                    {
    8 D" s+ r: `8 u/ S3 M                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
      E7 x6 K; y' x2 b6 x6 E                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 1 t/ \: p  N3 S
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))* j- a8 B# j; J% g% J
                            {
    ! z8 z' w* C' d0 Z7 F                                break;
    # X& M5 e; I, L, b4 J0 i                        }
    " j1 K4 z$ b9 k
    $ g* X2 N# I/ ]; F                        pNode = DLL_NEXT(pNode);+ M' u7 d% D# ^. c) I6 ^4 t
                    }9 e+ Y$ k6 L2 R: T

    % H- ^! S! {- J$ m5 z( F# X6 @                if(NULL == pNode)
    , a, X. ~/ E7 I$ K                {& y7 B% n: X' z" _3 V: }7 h  q
                            /*TODO give the semaphore */+ U# e' u! e( O! C/ N6 u
                            semGive(partId->semPartId);' g1 S6 I3 D& F. Y$ \8 [) K9 G
                            return NULL;+ u! ]5 w3 Y: t6 R" y. ~  N& L
                    }& z! I0 I. [: x  v
    4 o8 W% C4 Y3 j
                    pHdr = NODE_TO_HDR(pNode);
    ( t4 X% O/ F' O! f2 i. K/ e                origpHdr = pHdr;7 {0 [  ]/ G/ _' M

    ( j; |0 B# i* y# P4 \) o9 q5 T) G                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);- I7 L6 _  ?- C/ W5 V; b/ [
                    if(NULL != pNewHdr)$ b) Q7 @, ?1 H% Q; `* i  m( v  K
                    {
    ! o2 Y0 B4 X# _1 J: W                        pHdr = pNewHdr;9 A+ `+ X5 A( D" b7 i# L# ^
                            break;& ]1 T* M7 I: Z* |1 Y
                    }/ T" o) j6 v, `! Z- z2 V$ Z! M; s
    % S5 G9 a0 r1 s; i% S+ _( j
                    pNode = DLL_NEXT(pNode);
    ! q# m- M* W; B. q( a2 ]        }
    $ b6 v$ t' F1 z# I; Q3 i% b% N; M
    9 @, j$ _4 P  J! h( d        pHdr->free = FALSE;1 F5 V; f9 f7 O2 N! V
            partId->allBlocksAlloc++;' n( F1 x6 l" c& `+ g9 \$ A
            partId->allWordsAlloc += pHdr->nWords;
    1 m8 N! H- q4 F' Q* n4 k        partId->curBlocksAlloc++;
    0 B- t/ ~5 i( \& H5 _6 ^        partId->curWordsAlloc += pHdr->nWords;
    . e: g/ V1 Y% f8 {+ l5 p( E; ]8 V3 s3 U% N% N, _7 w9 r5 x6 u! X7 S
            /*TODO give the  semaphore hear */. w6 ?# J, V( y
            semGive(partId->semPartId);
    ) g! s2 T* X% |& d; j/ D" z$ C        return (HDR_TO_BLOCK(pHdr));' k) {, M* ]/ G* I. x9 x/ J" W9 z* V
           
    3 ^2 x/ v! w% O* h7 |( j" K}$ P! C, i' M8 Z* W8 Q* E* G2 ]

    6 m2 m" X$ ~; ?void* memPartAlloc(FAST PART_ID partId, unsigned bytes)
    / D- ^; L/ R. C{, F2 R" t+ t" O1 y
            return memPartAllignedAlloc(partId, bytes, memDefaultAlign);" V4 g  z1 x7 E8 l0 J
    }
    7 l( Z6 X, ?2 I% U* q
    1 c9 j% u$ q+ I/ Q6 X' ZSTATUS memPartFree(PART_ID partId, char* pBlock)1 b& I* L2 g) A  X3 g% e: K
    {
    2 f1 x% X0 m% L  w        FAST BLOCK_HDR *pHdr;, F1 f; f: l' U* D+ a. _
        FAST unsigned   nWords;
    : [; p# j% R6 {2 w8 G3 u( s    FAST BLOCK_HDR *pNextHdr;) w2 m# X6 O* ]8 {; R, ~
    - T% L8 {6 L5 k
            if(!IS_CLASS(partId, memPartClassId))8 [+ _' S2 E( z4 o- s- s
            {( x0 k" }4 A' N$ i  W* Q1 y/ _
                    return (ERROR);# B% C  U  m5 K9 L! `4 r
            }# W/ {, S  X) ?

    8 @5 Q: e/ L) C" @; @9 t$ T        if(NULL == pBlock)/ P: L9 d1 |: T1 {# e4 P3 M5 n5 z
            {& e. k* g' `3 y. b8 G' F6 \2 Q
                    return (OK);* j# a; h- Y0 i. @3 f
            }
    % w& X! q  z; F2 q2 P& v+ j
    ! Q! i1 b) Q; B: J' ]& A/ N        pHdr =  BLOCK_TO_HDR(pBlock);
    . ?5 ^! ~+ T7 r) X
    - b. a9 M! O/ x$ P9 ^        semTake(partId->semPartId, WAIT_FOREVER);: g  _5 p" B2 ~
    # A' ]+ S9 \( p
            if((partId->options & MEM_BLOCK_CHECK)
    ( V5 c; }: ]3 Y                && !memPartBlockIsValid(partId, pHdr, FALSE))
    2 F9 M* s8 b. N        {
    + D( D% A' i4 j- @, w2 P* k, H" l                semGive(partId->semPartId);
    : f& i" i5 \3 p. F& T) V$ Q                return (ERROR);$ }9 ?8 g3 _) W9 X; H
            }
    7 \) {: q! E6 i
    5 Z* A4 p9 i2 r' F9 _4 U7 H        nWords = pHdr->nWords;
    + @' s/ s* S: e* I: M        if(PREV_HDR(pHdr)->free)
    / G9 Q' m# v" M0 c6 F: k# a: D        {/* the prev hdr is free and than coalesce with it */
    , Q/ x! f* ^/ |0 q                pHdr->free = FALSE;
    $ @7 ~8 i# i. A* m/ q                pHdr = PREV_HDR(pHdr);" P, ?9 }* k" {1 @
                    pHdr->nWords += nWords;
    8 P( D/ ^' _; G  d        }7 f$ y" n3 z5 A+ I
            else$ r2 b! D% s2 z7 m$ k; R7 F0 ?
            {, c* ]! ?4 q; R. `
                    pHdr->free = TRUE;% x2 s& l& E2 \8 ^+ @
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));% ~7 b8 f5 n! o1 u& V7 G& l) [
            }/ p$ b$ l* ]( K0 l8 Y
    ' {8 y) ~* V% O0 Q/ O3 r( r3 i0 A* v- u
            /* check to coalesce with the next */
    % {3 Z% W, W7 B( h7 [        pNextHdr = NEXT_HDR(pHdr);
    ) s' e# ~6 Z" S! z        if(pNextHdr->free)
    ' B+ W7 Q- C2 E6 c" |( K4 r        {
    6 ?1 T7 P0 x/ d; a- j" `0 U: O                pHdr->nWords += pNextHdr->nWords;- y, u  O5 x, `  F4 l, b* z4 s4 h
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    + J# ?* Y: x+ d* ~! q        }" L: k- G0 O- l; ?1 R

    ' G6 [0 P8 d& u        /* cannot use pNextHdr->prevHdr=pHdr hear */
    # h3 X" Z( t$ J+ _8 V9 F; g        NEXT_HDR(pHdr)->prevHdr = pHdr;, {) v; N" @/ g  u
    9 P$ f" ?' U5 E& N  G
            partId->curBlocksAlloc--;
    + Q+ ]: I0 }$ v  U        partId->curWordsAlloc -= nWords;
    $ f. U2 }, [( m5 N
    3 ^: [$ ^+ C4 t! f1 L! S        /* TODO give sem hear */- C# C: Z5 D% G, b0 _
            semGive(partId->semPartId);% z; ^0 y. K# ~9 v4 F! w
           
    ! z" R" \# ~1 G8 Y        return (OK);
    # y3 A# }' {3 B6 e& f}0 ^+ |. k  E# r* f3 u% a5 c

    2 X( C: ?. g1 rstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)* W: e. }2 v1 ~+ \8 r2 }
    {
    / I0 X% ^& z& ^/ h; b. T6 Y        BOOL valid;
    9 i# m7 |  y" u
    2 C! |* b& O* ?# R, f9 v, s        TASK_LOCK();3 Q! {) j8 l+ G* k+ n: {- e' E5 m
            semGive(partId->semPartId);0 I! _6 H2 b3 P! \8 \( Z& s
            , s: E+ U1 w0 t/ t- Z) v
            valid = MEM_ALIGNED(pHdr)2 r: y  b2 L1 o* R+ r* w8 h3 e
            && MEM_ALIGNED(pHdr->nWords*2)" [7 `* ]& _, ?; z- F2 t2 H) H
            && (pHdr->nWords < partId->totalWords) % l6 r5 y  v8 T5 e9 ?+ V
            && (pHdr->free == isFree)- W5 n8 e2 h* `' P3 Q
            && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))! t5 G; _1 k' ?% J8 d
            && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
    8 |5 l* U. C$ c5 f       
    6 }$ H; B5 c3 ]: f        semTake(partId->semPartId, WAIT_FOREVER);
      I: O) S% P+ |- U3 k        TASK_UNLOCK();
    5 P. w! F, S& j; I3 v8 s: B. f' S0 G/ k  y8 ^) a- u
            return valid;
    8 O! k, p6 O* d, T& `; z- p, J) q% r}% ^! W+ j9 E5 b. u, I
    - {: @) L$ i; k, ]' O
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId% |% w+ ^0 ~; _( }6 m) h7 D+ g( L
            , FAST BLOCK_HDR* pHdr
    $ N/ M- t7 g& n2 c        , FAST unsigned nWords5 u) p3 O$ I+ F$ i4 Z# I' W8 G- o
            , unsigned minWords
    5 y& F9 e' x$ i' r, a        , unsigned align)
    4 U1 ^+ M' {8 }4 e& g{7 t( P8 e0 A2 r1 w+ a5 b' e. ]
            FAST BLOCK_HDR *pNewHdr;( g! ^" F; K1 P  t
        FAST BLOCK_HDR *pNextHdr;) C/ X$ Z7 Z( J
        FAST char *endOfBlock;# f/ c& [2 z0 T# x
        FAST char *pNewBlock;2 M/ U# |+ @% |" L
        int blockSize;; w, }% v8 F9 C2 M/ J% l

    ) E" l5 s+ _  O5 y/ R: L( R        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
    ( i6 T2 V5 \4 g' s) H
    9 h- {! b4 N7 S8 I        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));1 U) Q7 |& ]8 d" P
    / f8 J; F8 U$ o9 b  R
            pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));& T, ~& `) ]; ]/ e! \" o
    ' U3 W" X4 f$ q% I& z
            pNewHdr = BLOCK_TO_HDR(pNewBlock);0 x$ [+ @( \/ N/ s' v1 M1 w/ K1 B
    1 G  V4 O/ V+ B; Q* Q$ Z. y: w1 R
            blockSize = ((char*)pNewHdr - (char*)pHdr)/2;2 `+ P% z4 I. c; E

    $ y( ^/ M, ]6 m2 y9 b& C! O        if(blockSize < minWords)# ]5 `5 O+ [- W/ W
            {
    ! Y1 j/ O' ^; T* V% c                if(pNewHdr == pHdr)) g% D  ]" W1 m! ^, X- ]2 y6 @
                    {
    / v. `1 t9 ]5 d% v* j                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    5 f% A0 c8 h9 v8 w: [+ H" A                }; z' A- X0 ^! G9 v$ `4 p7 H
                    else
    7 e0 |  f: u6 ]' y# l) s& R                {
    + g0 c6 C  ~# z                        return NULL;
    1 e4 z0 r% I, U9 Z% q2 S8 |                }  r! r  S6 G3 H% m# ]! ]; c
            }
    ) L; q+ B. a$ z/ ?. P        else
    ! H* L" N; l9 w, D& H        {        /* recaculate pHdr */1 K- a1 O" [2 _: U. n
                    pNewHdr->prevHdr = pHdr;0 `( ~0 I( w* P5 x5 N" S3 A
                    pHdr->nWords = blockSize;
    " ~$ _% D- y) E9 ?9 ^  k1 _. E        }
    ( V$ I8 E& Q- w: N8 j5 p3 D* H) ?) T! _
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    / U% ~/ d% q0 v2 u& q7 H9 u        {) y( ~: p" M5 L: {
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;  |& [$ w: P, Q2 y, K. g3 K
                    pNewHdr->free = TRUE;9 b6 t  F( F: r2 P, v7 Z! ~
    7 r5 `3 j/ |+ \6 j! L: a
                    NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;6 P, `1 v" J0 l8 l& \$ A
            }
    1 F" S( F7 G4 e/ y& X6 q        else
      a+ d3 F* i% b( c& A        {/* space left is enough to be a fragment on the free list then */
    9 w: X9 c& f1 ~0 ~, I' v                pNewHdr->nWords = nWords;( B/ i2 U( I/ }' c7 s( I! W
                    pNewHdr->free = TRUE;$ \* i4 H2 c$ H, B6 ~

    * e4 K% z" h! v                pNextHdr = NEXT_HDR(pNewHdr);
    1 G8 q. ]5 s! O2 `+ L" k+ Z                /* words 包括BlockHdr */
    0 U+ _5 P9 X8 Y                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;5 W8 X. }* m) d8 S* H
                    pNextHdr->prevHdr = pNewHdr;2 h! l2 V% }+ X& J. x
                    pNextHdr->free = TRUE;
      m, q$ ]( U  Q; `1 F3 Y
    + O8 r( L$ I* l  Z/ o                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));6 y! U* Z" \1 I6 o

    * _# B5 }3 c- d- P0 K7 V                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;, T8 \) E, L7 i7 A" Z
            }
    : D! {7 }) U5 o. {' f- i3 A2 C
    ) O- ~; n4 A# j        return (pNewHdr);5 s' |. H) X3 G
    }. O& D* }& ?' w+ T8 ?
    ; H7 z1 q0 j3 F! B
    static void memPartSemInit(PART_ID partId)
    / Y! x8 d* F: S9 Z3 a{! {* o6 u1 @' X" A1 C0 V6 J
            semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);# o3 w5 ]7 d4 B2 j

    3 P5 U& H# y) S9 f9 L& w        partId->semPartId = &semMemSysPartition;
    0 T, n% U, }6 r3 y}% Y( |+ E9 e: g0 F

    6 Q' D8 O6 }3 q0 Q- nvoid* malloc(unsigned bytes)( Q. t6 h" k& H' W
    {
    # Y, ~% y0 L8 q3 X        return memPartAlloc(memSysPartId, bytes);
    / c, n5 H2 l6 O, Q4 B, `}
    7 Y" x, K* d- r0 m% ^! [; F* C! l4 _: {2 W* i7 R" o
    void free(void* p)
    , ?* s) W, o- R- t{" C! I4 N& |5 ~; G
            memPartFree(memSysPartId, (char*)p);7 E: K$ t9 }/ j  A1 e
    }
    . ]( w) r' Y' B' [
    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-6-3 18:27 , Processed in 0.424159 second(s), 51 queries .

    回顶部