QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2879|回复: 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++下的版本,更方便调试。有需要请留言
    2 v" a- `0 W  H& S  r
    ; g+ a  a! X6 x. y9 P3 Z/ V, B$ R8 H% |& d5 I2 Q

    ; s2 v9 d' U) | *\file: a: P  ~) `4 r) g6 c
    *\brief                - b1 j& u; }2 G" r
    *\details       
    5 I6 u9 o& o' B, O* j: l' ` *
    6 ?) S8 x. h7 B/ M0 c- I, {% {0 g$ W *\author        Janson" t* {3 R  V$ v# E
    *\version       
    . M5 J0 m1 ^$ B" i. { *\date                04Jan12
    , q- G" ^% k3 d" r" w *
    2 v5 ^& `1 w. m: D1 R: d$ ^' z *\warning        0 ?% E9 u5 @$ w1 n# Z2 y9 D
    *
      F8 o9 C  `4 x; R3 w *\history \arg        30Jan12, Janson, Create the file& n% v# @  |( b( h0 s' F
    *        modify from VxWorks source  B2 N$ u/ J; a# |; J- m
    *  Legal Declaration: it is for studying VxWorks only.3 O- K: e! Y! T% |
    */
    ! K  {/ t, U) `/ W#include "includes.h"
    9 h2 s1 q5 Y5 `( `  i% m5 D5 U' f) t9 G, Y; z, V5 J1 Q9 C
    /* The memParLib.h file is hear:
      h9 g8 [; ]. n& C0 ]8 J  uhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
    / T# l1 y/ I# c*/
    # p% ~. D  n6 `2 U1 E8 E! J: W% c1 G* t' u* M
    /* optional check for bad blocks */
    7 L/ o% M2 v. _1 s- R+ p2 z; h
    6 i3 P( O' x0 ~#define MEM_BLOCK_CHECK                        0x10
    2 o; K3 z6 _8 J( a$ J; D; x' g3 r3 Y/ ?0 M. v2 F# Y
    /* response to errors when allocating memory */
    % S. F, h# @" x4 U8 t; d
    0 p5 M, R2 X/ \& B1 g#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
    5 M6 N0 K; k: t& N! M+ ^#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
    - }/ v4 O( C* }) [4 l4 d) o2 Z# H% F+ P/ y3 z5 J! U/ w
    /* response to errors when freeing memory */4 p' o* W8 n. t

    , c# P6 ~  f7 H7 P  U#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
    & K& l& {7 b8 y2 J! m' c2 p#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1002 C7 l6 a4 o$ h. W& @" w( E; D! ]
    4 R7 H- C1 R7 q- I7 U$ ^
    #define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))
      w4 U. J" j5 S3 U* n#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
    % r) Z8 w, ?# h2 O" Z0 c; i/ M1 H$ E7 j' h& \' X
    #define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR))): I# h. v' \" ?; j: ~6 Z) I: d
    #define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \
    5 z- y: }( L: e1 a+ e- U/ M! I                                                sizeof(BLOCK_HDR)))
    ( R+ s0 v  k: m1 f) O) ?) W. {! x8 u: m
    #define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)
    ' E) `4 F( S) h- \& e$ {$ O#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \, Q" o- F2 E' V8 s
                                                    OFFSET (FREE_BLOCK, node)))
    1 Q7 d& b* b" |8 D- M' ?
    % s0 Q6 o" e) w7 `4 wstatic BOOL memPartLibInstalled = FALSE;) t# P9 c( {! D! R4 F* q) z- R

    ' z) ^* ]: E$ H0 n! u1 F  N/ Z2 fstatic OBJ_CLASS memPartClass;
    ; L# l( z0 B( q$ ^; d, UCLASS_ID memPartClassId = &memPartClass;2 g/ ^2 x3 w& a7 B5 f5 l. J, ?
    * t0 r) `( j% {- v# H* [
    static PARTITION memSysPartition;
      ~8 e2 T( ^; G; B4 j* \PART_ID memSysPartId = &memSysPartition;' q* v4 v  {! [+ k  {5 b1 l
    U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
    ) V) n. r. _: [
    ! U% ]) g8 F# {) f6 D/ Pstatic SEMAPHORE semMemSysPartition;7 c+ ?. H$ I- w& U$ O" \* r
    : _+ D( B# h/ g: M* y$ }9 z
    static void memPartSemInit(PART_ID partId);3 i7 N8 W; o* T8 s
    " {3 x( G5 Z4 U1 |" F% F4 V- W) Z
    FUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;3 h9 p1 q% Q8 v

      w; Z6 h2 L# Gunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
    2 {: `4 U& d1 ?3 A* [
      D: i  ^9 I/ A, @* nstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);: ]% e0 E5 e6 o! L( U
    static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    : r6 V( F% N- Y        , FAST BLOCK_HDR* pHdr
    5 B+ {1 u% t  c4 t" V2 |- Y& [2 J: B        , FAST unsigned nWords
    4 a2 ^- G+ L6 Y) S% h9 R        , unsigned minWords  |1 i$ S( b# C# x" w! D
            , unsigned align);
    / ]% W' ~! _( U0 ?, s0 N9 `8 a/ @' p6 g
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);- a; D; m" C4 ?) f9 Q0 A, [

    3 ^) |( v) ~8 i9 QSTATUS memPartLibInit(char* pPool, unsigned poolSize)
    ' k' t# }  z5 c- y1 S0 T$ @, d{
    ) f9 O0 f/ `. v8 Z9 L        if((!memPartLibInstalled) && : C" X- ^" L& m
                    (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
    $ w4 [) F, [8 Z; p2 Z                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))5 }/ a( C. z# A9 [) k1 T. R
            {
    + K5 M% n8 I  E2 T3 R                memPartInit(&memSysPartition, pPool, poolSize);
    $ c. j( C3 a0 N% K( ^& w0 G3 S" H                memPartLibInstalled = TRUE;
    ) [" l, w& Q" h" D: g        }
    / w. f! Y: W- M+ I  F3 R$ ?- r; o% E' Q9 @$ q. r
            return ((memPartLibInstalled)? OK : ERROR);
    ! l3 k0 v! D9 f! a}- P  I- h6 ?( ^& S7 o8 o7 y
    9 f; m" c" K' q! W2 e
    PART_ID memPartCreate(char* pPool, unsigned poolSize)
    6 j6 a+ ~% D: [; ^5 ?{- h* t3 P. x/ Q" m) I+ Q
            PART_ID pPart = (PART_ID)objAlloc(memPartClassId);' F8 v6 u; [. t
    9 r- J- _5 t# F9 K* o
            if(NULL != pPart)% c6 F! F" `5 b# m" u; y- I5 x, m1 u
            {/ r) ^6 r. }' g  l6 {' R
                    memPartInit(pPart, pPool, poolSize);
    4 w* v, b. o4 r+ U# E7 S        }7 X* _! Z" `9 C8 V

    " j4 |: y2 F$ K        return pPart;1 v! u) k, Q" e$ W: q7 |% l  u+ R0 D
    }! m  h& ^, C4 `7 M- R# \# v: _

    1 d6 s/ m, I8 @$ y3 ]2 U8 a8 a* X: fvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
    . O8 u( U7 ~& w) L{
    + K! ^0 K" z5 G' f6 J- p* p$ j        memset((void*)partId, 0, sizeof(*partId));5 E% \( ?$ |4 A4 H
    : F$ F  w5 r* u! H7 i
            partId->options = memPartDefaultOption;9 F( P! e4 C- ]/ S
            partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */4 N* W# `. n! n  K/ z2 l5 P+ i3 R

    % v$ [! T# ^$ o4 t7 Y1 t4 P9 [( [' a& c        (* memPartSemInitRtn) (partId);9 D/ Y; i8 `2 S' Z6 h7 e! K
           
      |7 O% o5 r. @: O        dllInit(&partId->freeList);
    6 y8 H% @4 i3 R' U6 n& q       
    9 k4 P& d( @$ v! c5 g# L, L1 ]        objCoreInit(&partId->objCore, memPartClassId);4 F. s7 b# T2 O
            " g: P! N( i8 k+ w2 m
            memPartAddToPool(partId, pPool, poolSize);
    + ~. h5 h6 c/ a* A5 M}
    . I. ]/ {+ C5 Z; a8 y7 _' j, h0 w% A  ?7 Z" p- p8 i) L( D
    STATUS memPartDestroy(PART_ID partId)' U5 D4 V2 K. ^% T. ]- b. e
    {
    , v. k6 b4 o5 G        return (ERROR);
    / h* D  A( r) Z$ H8 b7 d8 g}
    0 j0 n9 e5 Y) D4 b- H
    8 W. Q1 W/ O4 L7 X6 M3 r2 ovoid memAddToPool(FAST char *pPool, FAST unsigned poolSize)
    ' T7 y7 S( k4 e4 k{
    " C7 E- i7 y( P; V. a7 y$ r    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);, m( u' x4 U* Q% O: W. v+ z7 i% b
    }0 S' B8 h6 F4 B9 X9 [! D3 d& y9 F6 L
    7 s5 `. G$ u- `  N, n
    6 S( Y0 e7 l! z. D. ~  l4 W
    static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)
    7 n( k1 ~! c: q# \3 ]8 v! {: v2 d0 X{
    # z( D; J4 @+ j, T% ?        BLOCK_HDR* pHdrStart;7 s& C0 O5 a) j  \$ S
            BLOCK_HDR* pHdrMid;' {* g/ x! A( E; W$ o
            BLOCK_HDR* pHdrEnd;
    ; S: T3 o4 E! T2 }. A        char* tmp;
    6 t9 j4 r$ }' I: y& K2 V        int reducePool;
    # B+ Z) w' \, d
    6 L, t' v# V! i& [1 D        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    : h( V! f, u' l  p6 J1 `        {6 D' [. b% l1 o: M  i% \
                    return (ERROR);7 n5 X2 {% {/ r; J- h/ A$ R6 j
            }7 `$ [2 \9 A4 [* j. y1 f0 a
    : H* N  M# p$ ~! U, e
            tmp = (char*) MEM_ROUND_UP(pPool);( R# P! ?3 k% E$ `/ t, {  r
            reducePool = tmp - pPool;8 {. n5 Q. b/ T; N( Q
    ( E+ ~# j- p/ T  B' ?: {$ h! r5 p
            /* adjust the lenght */+ N. k( [0 O$ r
            if(poolSize >= reducePool)
    6 M% c% i. g* ^: l; E        {' w% l8 j# b. S4 Z4 h
                    poolSize -= reducePool;
    & J& Q) D4 U- A& W" ]        }
    : M0 N- }# w% H; K$ Y' T* i/ `8 m        else  W, J* J4 n3 B( h+ @( Z2 r
            {
    6 F" c( @5 M  u6 c6 s0 i  J                poolSize = 0;
    % A0 s  D. f! L4 b        }" E4 e' T3 l+ E, i
            pPool = tmp;
    ! O" h7 P" O/ P# l* E        , w; z' f$ p  Z7 l4 j# c
            poolSize = MEM_ROUND_DOWN(poolSize);( [6 i% s7 b! k" y$ t! d& X
            / f. I9 b: u: ~
            /* at least one valid free block and three header blocks */
    $ i9 h5 n  D$ N$ n- O# V0 f  ?        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
    ) U# y4 M' {% P- M- ?, v+ Z        {
    4 V: U8 S1 k. {2 }                return (ERROR);
    ( }4 j: ^8 a- M6 F2 h/ g        }( I3 Z. K% i* }7 x

    + M" B6 s4 m/ K: O        /* initialize three blocks */, a( U8 J. L; x% o( p+ T
            pHdrStart = (BLOCK_HDR*)pPool;
    6 \" [/ J: Q, Y' c: a8 R  F        pHdrStart->prevHdr = NULL;1 a( x; U# d+ m+ d+ _
            pHdrStart->free = FALSE;                /* never in use */
    ; }6 W; \! |6 ]7 Q8 L$ h% Q! ~        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;4 c0 C) E  ]! y9 ~. i! ]! c3 `
    / F( c  Q  v/ q
            pHdrMid = NEXT_HDR(pHdrStart);
    0 v7 }8 f* c2 E- e# v8 U) z. l        pHdrMid->prevHdr = pHdrStart;, D% T) _3 b! C
            pHdrMid->free = TRUE;                        /* the main block */
    0 u. i: c! t4 t# Q        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
    . ~' y4 ]% w9 g* a1 y4 e6 w! z" ~' R; m; R
            pHdrEnd = NEXT_HDR(pHdrMid);% u0 t  u  ]8 ~7 M
            pHdrEnd->prevHdr = pHdrMid;/ T1 i( ?5 ]% V) h
            pHdrEnd->free = FALSE;: ^/ t4 t3 S# c$ Y6 @3 e
            pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
    7 j0 o! E& R, _* p0 L- R: P5 E$ \5 m4 L
            /* TODO take sem hear */
    0 T0 j+ ^! v1 U2 L- R& ?  f        semTake(partId->semPartId, WAIT_FOREVER);
    ) }+ g6 I! d2 K       
    4 C# k' e7 w* N; `; X* v3 C- }        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));# \+ Q8 x: A! P6 Z3 u" u
            partId->totalWords += (poolSize >> 1);( E% T6 ^& O0 A, C- c8 y

    6 V$ E- F) s' \# f  C        /* TODO give sem hear */- E, t8 E4 `/ [- I
            semGive(partId->semPartId);
    0 b, j" h+ f8 ~3 t; X) ]& P. f# q% {9 X3 M; J
    " s% A; E( S1 m; j
            return (OK);
    ( Z3 ^! N1 H& b, N/ s}" N2 g+ T% J; m+ e+ \. v

    6 m5 X2 J  ^6 z! b/ ]9 Kvoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
    , Q: s8 H/ v( K# y" F3 m: Z' l{
      V  ?1 h& o) m0 A2 w        FAST unsigned nWords;
    5 ~$ D6 r* r* z4 b        FAST unsigned nWordsExtra;# {$ Z( t1 ~1 s& w& {' r6 q
            FAST DL_NODE* pNode;6 V8 v, K" f* v' l4 u, I
            FAST BLOCK_HDR* pHdr;
    2 U1 t' j! E  \% d        BLOCK_HDR* pNewHdr;! b2 D% V$ G8 {5 s! G' Q
            BLOCK_HDR* origpHdr;
    : U3 x% Q" P! @, W4 g6 h) b( Q6 M7 E2 Z& p3 |3 y# i" u# ^5 p# k
            if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
    / j1 Z2 r8 h; f# }" a, \        {
    / m* c' H/ |% z3 o6 J3 T* d                return (NULL);! e! I* G3 v5 m- B  E
            }9 v6 q# r! s3 P$ M8 E& l% Q# q/ z
    8 B+ f% w' O+ v* W7 y
            nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;* Y' N, M* Y: y' J6 f0 r

    ! U6 I: @, q# p2 m6 S. s        if((nWords<<1) < nBytes): c' E  I4 {5 r
            {
    / Z# u- J) c; J3 I& i                /* TODO suspend the task */! w' {7 Z, G5 Z) ]0 K* [
                    return (NULL);  x/ ~( J3 ^% V" x
            }4 B% w6 X% |  f7 L3 W6 \& a
    * ]' S9 x! p+ S6 N8 k* l
            if(nWords < partId->minBlockWords)
    2 z' I- }# h+ Q; \9 S, m        {& k0 ]. u6 A8 h
                    nWords = partId->minBlockWords;
    : e8 X3 X; t& ^0 H        }
    ) [$ M) I8 m- q4 w
      ?8 e, H" v! y: x, c        /* TODO task the semaphore hear */
    . w/ U4 C, c$ g) g; @0 @& U        semTake(partId->semPartId, WAIT_FOREVER);# z4 W! C+ e2 N% J! s& i* \
            pNode = DLL_FIRST(&partId->freeList);$ l; Z/ n0 r! O' m5 K
            nWordsExtra = nWords + align/2; /* why? */
    0 R+ G% J5 v* W
    2 [9 h# {' h8 m8 D        for(;;)
    + W+ F$ x( l/ p( o5 _9 L7 G4 x        {
    & W( r+ ^; m. \# a9 w( U                while(NULL != pNode)
    8 o8 _) w! F5 U* m                {/ w/ j( [* {7 `1 Y
                            if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
    ' g7 }3 z/ v/ z0 U4 |; a0 o                                ((NODE_TO_HDR(pNode)->nWords == nWords) && ( E) m! i. V3 \) u. q
                                    (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))" `0 K/ M  ^1 m+ n) C
                            {
    % z- d3 t. E& Z3 Z                                break;
    $ _' `% n  o# y% T, b- D                        }
    / T$ x8 H) }$ X& C! f: Y: v1 {8 u, N9 n7 F' M% ~" k
                            pNode = DLL_NEXT(pNode);
    4 m5 a( D& |9 s. W5 a* {) u: R                }
    ! v7 D5 B3 d, P2 N; T& f/ u8 a9 z
    $ r* V# w9 J* o, G3 o% s. M( Z# K                if(NULL == pNode)
    / g& k9 n( z4 o3 ?5 {& }7 r                {7 ]6 n, ^( h& A# |7 w8 f
                            /*TODO give the semaphore */
    0 l- I) e7 h( c4 D5 N                        semGive(partId->semPartId);& q# g- ~8 G2 ]+ V9 k; g& q  Y8 y
                            return NULL;
    + H. i( W  B' A) x1 b$ g7 }                }' V/ ?2 Q: E9 r( v- a1 z3 q
      N" F( q5 r. l5 i6 d8 u2 I
                    pHdr = NODE_TO_HDR(pNode);
    : H4 u- }1 j. E                origpHdr = pHdr;
    : C+ Z+ u( o! O. M3 z4 N6 w8 B0 ^5 W0 j+ f9 y: S& M( J4 Z, b
                    pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);4 D6 u- j! C; Y5 A% C* j
                    if(NULL != pNewHdr)
    5 l/ F; t% n* @, u. O! L- O                {. x! k: F  J( Y+ \
                            pHdr = pNewHdr;  J3 J' |) r  ~) t0 A# t( L% ^
                            break;
    ) Y; G" W: ~0 \                }4 }4 T" K/ d7 R4 H3 E3 V
    6 [. G$ ^3 P6 C, P" L
                    pNode = DLL_NEXT(pNode);
    , B+ T4 P; @: y  G+ Y$ `. v7 g, r. [        }
    + v4 X7 h+ i; i% B' r1 S- E
    9 d% n& Z) q2 o2 ?        pHdr->free = FALSE;( f+ K9 A. S  z6 _4 h" Q9 r3 u6 O
            partId->allBlocksAlloc++;( `  z0 E0 d  P. Q5 Z4 h
            partId->allWordsAlloc += pHdr->nWords;3 l: `6 |7 p* _% x% }: ~. `
            partId->curBlocksAlloc++;
    9 Y: J/ e8 ]3 d* D+ C; ?        partId->curWordsAlloc += pHdr->nWords;) \7 g) S) h% c

    ! b* D! }7 B- f$ Q        /*TODO give the  semaphore hear */$ Y! V' l. b" Z  C% Z3 _$ |
            semGive(partId->semPartId);
    ; K% \' q/ S1 _, S2 f$ K' Q% K        return (HDR_TO_BLOCK(pHdr));3 z5 J5 c" D" N8 ]' ~) e; e7 t
           
    * i: V& ?' [. G1 ~3 G- H  R}
    : k4 P" R9 F2 j9 G# @8 l7 Z1 p+ Q
    void* memPartAlloc(FAST PART_ID partId, unsigned bytes)" m3 u/ @" f. G, `% B$ S7 F+ c
    {
    " c7 L$ B1 K- k* x        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);# I; N) w$ N' F0 N! s
    }2 _3 }- L9 ?) |! ^5 x
    7 }( T1 F$ U* f! _# i8 J4 Z
    STATUS memPartFree(PART_ID partId, char* pBlock)
    4 Z6 K) n6 A, D{
    8 ^4 b8 o% N) g0 J, X) o% M5 r        FAST BLOCK_HDR *pHdr;; R/ K1 }- J* I* u- ?6 a9 C1 V" y
        FAST unsigned   nWords;
    % w9 I0 s0 c5 K  \  U- |1 u    FAST BLOCK_HDR *pNextHdr;8 H$ k3 ]/ ^$ U9 R

    8 d: M7 @4 `. ?        if(!IS_CLASS(partId, memPartClassId))- W% |# D. k+ h3 u) p  {3 x  e  F
            {
    8 Y3 T" F+ {& q) O1 }3 b6 J: x$ e                return (ERROR);
    ! Y9 t, A" i% c! Q6 d( R3 N6 I+ A        }
    2 X- T# r8 h( _" \1 y; U" X5 b6 k! f
            if(NULL == pBlock)
    ' o& u, j9 w8 ?        {% D9 T+ z! m: i; Z) D/ c4 [& [0 p- L
                    return (OK);: p4 M8 X" B9 u5 L: w& o, [# j! i
            }$ W1 |9 }7 f9 q4 c: e( Q* L

      E2 o/ a. b8 {# e) ~9 c        pHdr =  BLOCK_TO_HDR(pBlock);8 S6 A: _9 z' F5 C* H9 l
    ; {; `5 {% |$ H# ~; q  i, B
            semTake(partId->semPartId, WAIT_FOREVER);
    7 E# F5 w9 o1 \0 d2 G: }7 P9 d+ Q7 v; ]- O8 B6 ~$ D4 u
            if((partId->options & MEM_BLOCK_CHECK)+ {5 ]& `  z! g( K3 }/ ^& z5 R
                    && !memPartBlockIsValid(partId, pHdr, FALSE))1 E5 q' a: b% k5 b% c+ K
            {6 R1 N, T7 y/ m8 [: I! I
                    semGive(partId->semPartId);5 d# \8 b, r0 l: Y) H
                    return (ERROR);: o/ r3 }  ~8 C  G  I9 _+ `
            }- C' @- j) R$ T' g& ~1 o

    & G( Z1 I6 n+ M/ z# i. o+ f5 j        nWords = pHdr->nWords;
    8 f/ r- r7 [: f+ _8 Q- Q& {' X        if(PREV_HDR(pHdr)->free)
    + v0 H* v, C! u* j1 u+ Y" ]  l, `        {/* the prev hdr is free and than coalesce with it */4 m1 K3 p7 A. T* K0 b" @, o
                    pHdr->free = FALSE;
    & J7 [  f+ e* k- v$ d                pHdr = PREV_HDR(pHdr);
    3 @! V4 K* `, U$ C& L  _                pHdr->nWords += nWords;& n9 f. ^6 n; R/ `$ L
            }
    4 F2 k1 X. t6 C6 E3 {7 @        else
    ( o" q/ E3 x8 z4 P8 A        {
    0 |+ s6 `, v# j  Q6 z                pHdr->free = TRUE;9 R! F$ e  I' E
                    dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));/ P$ P! t9 ?3 l/ h" ?, I! n+ c
            }9 U) l! `% e9 K; H& v& [
    & U- I! y" M. Y" v$ y9 m1 N% F
            /* check to coalesce with the next */' v# U' c6 n3 e% J
            pNextHdr = NEXT_HDR(pHdr);
    / [$ H0 V& Q, a        if(pNextHdr->free): \4 F, u7 p7 l( H. S
            {
    * H& @& C5 Z+ t# A. u                pHdr->nWords += pNextHdr->nWords;% j; e, n5 \9 N5 X% F
                    dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
    ! `$ J8 X% U+ ~% C' ?& R( {        }
    0 j  D: B# d% p" ]3 g
    ! u& k. o1 X. ~; j; |+ _% _0 ~        /* cannot use pNextHdr->prevHdr=pHdr hear */& Z  D6 j: C* o7 p4 A, I5 B! Z
            NEXT_HDR(pHdr)->prevHdr = pHdr;0 z7 B, L' e; Y3 m" L; L
    1 I+ w0 M1 E  d
            partId->curBlocksAlloc--;, y; M5 ]7 |4 |- C/ K: n0 C, h
            partId->curWordsAlloc -= nWords;
    - Q$ p# u% {( S
    6 q* Q! i- \4 {3 M, ~  |2 o        /* TODO give sem hear */
    0 w2 n/ f/ _' g& m6 D        semGive(partId->semPartId);. n0 y; v+ o7 g
           
    0 e' f* x: e7 k* B6 H  U, Y# R) K% w) t        return (OK);
    1 H6 J4 P( a$ f3 g: \" e* C% _! L}: l6 H* x4 {/ {7 R

    ) b! [' N& o0 kstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
    7 F( _8 f, ^; `9 ]) T3 f* E{* O1 Z3 [3 T6 }, K
            BOOL valid;! k% e: x1 u. e! L; M" F& l

    $ P4 ?  P- D' q2 \6 h3 ]! Z        TASK_LOCK();' W" Z& ~7 o3 |4 J6 E9 L' M( m
            semGive(partId->semPartId);1 g+ e: R+ ]' @, }0 P9 z, |
            2 X6 f' C2 G7 W4 T: X% d, ^
            valid = MEM_ALIGNED(pHdr). L7 Z% {8 G* \& A1 E. i
            && MEM_ALIGNED(pHdr->nWords*2)8 w& X! w$ J- ?
            && (pHdr->nWords < partId->totalWords) 6 U2 m  Y. O0 `
            && (pHdr->free == isFree)
    ! u6 x* |) t7 `$ P2 u8 J1 ^        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
    # B6 R$ ]2 o( u        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));  d! v, C5 c1 y/ B6 N# j
           
    ' j7 [; @) r8 a7 G" A) D! V' D        semTake(partId->semPartId, WAIT_FOREVER);
    " q4 q  m" [6 S+ O1 l% c2 T        TASK_UNLOCK();
    ( t, _. ]" e( h. V5 R
    ! C9 ?! k1 _6 _/ V' C$ Y& x% K! o        return valid;
    $ J( ?9 X7 K( X# I8 r/ o, j! {}
    ' b4 B! A6 P" `$ D& a9 R
    * P6 N& L% i4 v, B- v% ]! Qstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
    , C& M* f3 u. G        , FAST BLOCK_HDR* pHdr7 @2 S  K$ T! W
            , FAST unsigned nWords
    % X# j2 W; |. L- t+ p: s- B        , unsigned minWords& |1 ~9 r' o4 v7 V
            , unsigned align)- z' y% f& F8 Q# ]( T3 p5 ]
    {7 S: D! }: W3 r9 J# c
            FAST BLOCK_HDR *pNewHdr;
    / W+ D/ n( m+ b( J    FAST BLOCK_HDR *pNextHdr;- s! B# }# ~$ n( r
        FAST char *endOfBlock;* j' a' z. K5 E% v/ _- t
        FAST char *pNewBlock;+ o5 B; u! B5 p) [
        int blockSize;
      {- [- G5 F/ N8 B% T" k7 x) i2 f% T4 S( D
            endOfBlock = (char*)pHdr + (pHdr->nWords*2);$ A5 k  Z8 a6 b
    9 Y2 V! p9 s) Q7 D, ^# g2 q2 H
            pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));+ e. I2 f* }0 i9 u+ f- e/ B

    5 ^4 |8 x3 M  }$ k        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));! h, O1 a# ~$ S$ g) s6 T7 k8 m, R
    , o8 R( k4 i  {( G! P# h" _3 L9 q
            pNewHdr = BLOCK_TO_HDR(pNewBlock);" J5 l# y/ ~! ~# D0 s3 E" I

    3 ?7 h$ Q; ]" M+ |1 v) b        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;9 J+ W5 F' f+ K' D

    - H: Y5 y8 `, ~# h, v# g( p! Y        if(blockSize < minWords)9 z9 F, A! e( p3 k1 v
            {3 W+ \" n& k# B: D) _5 c
                    if(pNewHdr == pHdr)$ V- d0 P2 G' M3 o1 ]9 H/ N4 _
                    {; X! P+ [' q  @9 d( O& [
                            dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
    : T0 Z: _3 j& X4 q) D                }
    + B* }8 U9 n' _  X                else
    , J# a& q5 Q/ |, W3 z4 n* {                {
    / D' b) {) q7 X# R$ s, b0 k                        return NULL;
    & g. g3 q5 C7 s0 s4 @                }
    7 j/ a$ L- c4 T0 J/ p        }$ X) p! g# G% t# N; Z3 k+ s5 C
            else
    ) n! Y: |4 @" c# C. n        {        /* recaculate pHdr */
    " [2 a1 d% W/ O* u2 {4 [' L4 U7 Z                pNewHdr->prevHdr = pHdr;
    - b' M. `9 q1 m3 N3 Z9 ^                pHdr->nWords = blockSize;* Y# F+ @9 Q  W' m5 I/ Y% H
            }
    3 T8 l0 q/ h% U/ H: Q' B7 ~) f0 a
            if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
    ; A5 r0 C* D4 d- h  M6 V; N4 x' [        {1 I! u% o1 W. K# O, f3 J
                    pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;2 j' s7 E: P: ?) F6 L7 ^. P
                    pNewHdr->free = TRUE;
    . p  ~3 A7 h0 m: L
    + l7 ]0 y3 q( A' e) F8 O: }  U                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;, M: H1 R# \7 W- {. I+ q( n
            }
    0 n! J% @& }; i- C. J        else" M: r* J. i4 V9 P7 Y* M
            {/* space left is enough to be a fragment on the free list then */) {: M% i% m1 X4 X
                    pNewHdr->nWords = nWords;
    - }4 j5 v3 \& m, V/ t/ P                pNewHdr->free = TRUE;
    - Q2 O. V' Y: J* D+ u
    0 R1 |6 M4 W: r) w  d  q" Q                pNextHdr = NEXT_HDR(pNewHdr);1 |# H4 c. J/ h. a! B9 J5 I
                    /* words 包括BlockHdr */  {# ^# c5 Q. a: z9 M# o$ j+ I% C
                    pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
    0 r2 F* w# u0 K                pNextHdr->prevHdr = pNewHdr;
    3 w$ j9 F$ _4 n' n' ?# s                pNextHdr->free = TRUE;
    ! s. Z5 c! k; D* T+ a" {
    8 g  a0 a( a' O  b. M6 X! k- d                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));0 V; O/ K- S* ^) M

    , g' j3 s  m3 Z: V  y1 n- ?! Y                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;3 A, _1 _; W- x% W8 q. W4 N
            }. B4 R# c5 {; j2 J

    # q! D) [2 ~* e" Y3 l        return (pNewHdr);- Z6 R6 z6 ~& g' I3 \
    }
    , }5 y0 n) {6 n. ^7 Y' Q' q; S! C# `% X( I2 }
    static void memPartSemInit(PART_ID partId)9 ]8 x! N$ i, m4 X6 S3 m. x( ?
    {
    4 \% T) o' O6 q2 q  V5 Z& L        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);' v& d/ Q) `" ]3 y( {
    + t1 W7 J1 x9 D2 B  ~+ J
            partId->semPartId = &semMemSysPartition;1 @" r9 d( U' L& u
    }9 N: Y4 O8 t3 d
    / b& X( O" p& V( s" ~
    void* malloc(unsigned bytes)/ N: ^( {+ L, U9 N$ y- z7 a/ \( T
    {( w: H- O3 m0 D- N+ G0 Z
            return memPartAlloc(memSysPartId, bytes);
    ! v  @0 ?" T# x2 J  o}
    5 _" x5 {3 D6 [; r( H
    & f- ]. x% p& s2 y' z2 M. Fvoid free(void* p). x- @: q3 y4 @0 N7 q: A
    {8 z2 T% m! a+ c- T3 H( V. z
            memPartFree(memSysPartId, (char*)p);
    ; J/ U" G* b5 z4 g}& M$ e" M# Q/ h9 ^' 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-7-19 07:59 , Processed in 0.653388 second(s), 50 queries .

    回顶部