数学建模社区-数学中国

标题: malloc(内存分配)在嵌入式下的一种实现 [打印本页]

作者: wangzheng3056    时间: 2013-7-26 10:17
标题: malloc(内存分配)在嵌入式下的一种实现
想知道malloc是如何实现的吗?这里是一个简单版本,所有的功能都在这个文件实现了。如果你对malloc的原理有兴趣,可以通过这个代码窥视一二。实际上这个实现是著名的嵌入式操作系统vxworks5.5以前的内存分配版本。这里我已经把它实现的更简单易懂了。当然我还有移植到vc++下的版本,更方便调试。有需要请留言8 Q/ I9 K1 B: Q

! E+ V' x7 N' H. Y& `/ p( q; s
" t6 i; h( T$ ~- m% [" A7 e. Y5 m4 P  L  i7 }
*\file1 }$ E% b& w3 P5 ?9 ^
*\brief               
# [5 f2 e) X7 q$ ~# S *\details       
5 W' Y" P: \( K8 \" w) l4 F *7 e5 z7 d! N; N
*\author        Janson
9 F' M- o5 O! i4 { *\version       
( x8 V! k2 B* p( F- r *\date                04Jan12* `& ]; D6 P$ K" d
*7 z; W8 J3 [9 t7 C! t; R
*\warning       
9 z1 q) s- Q% _* N4 l4 I2 V8 r *
8 X+ X9 p1 L3 \  L *\history \arg        30Jan12, Janson, Create the file$ _: b2 M# V; a' ?  \
*        modify from VxWorks source1 ~6 x! }% z: ~. m& N3 R- j! Z; B
*  Legal Declaration: it is for studying VxWorks only.) f& t" s" l; s, ?7 x% T( ?  ~& |0 \
*/6 [: S. o5 Y3 t
#include "includes.h"
  Q; G9 _/ h# Y0 Z& v( f0 V# \9 o& I7 g
/* The memParLib.h file is hear:3 p' a$ ^' w- d  W% E
https://code.google.com/p/vxwork ... rivate/memPartLib.h
% W) z* E, j! h*/0 O  w5 u$ N0 u+ W( ]" C2 c
- x: w4 k# `; g; r# o
/* optional check for bad blocks */$ K9 V: x& w5 L8 {! ~
- G7 ^$ n9 Y6 t7 t
#define MEM_BLOCK_CHECK                        0x10
/ k6 V; U9 T" l( s" p" R2 h  Y" ^% p6 r
/* response to errors when allocating memory */
+ L+ g2 b1 j1 g& D9 ?* J% a. @) V7 W2 ~! }$ [2 q; v
#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
2 v! M; K0 `9 }: n- u5 d6 g5 ^8 j& D#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
6 V! R7 F" q- H& u; @
6 T8 |9 |+ X- _/ h+ g/* response to errors when freeing memory */  w7 o: y5 k) S0 E# y# |. R  V3 O6 L
4 H, E1 C6 v4 o# J0 \9 {4 r
#define MEM_BLOCK_ERROR_LOG_FLAG        0x80
9 s8 Q; G3 x4 r; T" n2 [+ z/ m#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x100. t7 n/ c. K7 c* n

: h$ n0 i' B- ]#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))( X% H  `9 ~3 a$ x9 [
#define PREV_HDR(pHdr)        ((pHdr)->prevHdr): t. N5 K- l) t
. o( }3 ~7 ^# G- D% v
#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))  W* v8 c' g4 d) {/ p
#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \4 n0 _( J" V9 e! f8 J7 j
                                                sizeof(BLOCK_HDR)))3 T( J' M- K+ s( G* i* n

' }' @+ e8 c- G* w7 n$ V#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)2 `7 t( I% H4 o2 f3 q
#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
6 t+ x& M- t& @- q9 [4 O) ~                                                OFFSET (FREE_BLOCK, node)))  H5 M% {" Y5 v6 Z2 v$ J* j

& }( m  ]" Y% Pstatic BOOL memPartLibInstalled = FALSE;
1 a, A, m6 H7 E/ K/ q8 H/ C( w# |2 U% H1 p5 t; G0 _0 L3 D2 N* n
static OBJ_CLASS memPartClass;
! j* ~* f* @- GCLASS_ID memPartClassId = &memPartClass;. E4 v" I: F$ o$ F: \5 V% o8 D
# t9 W1 ?2 V! P& L0 ?
static PARTITION memSysPartition;4 r. t# M6 e2 L3 Q
PART_ID memSysPartId = &memSysPartition;
/ x, Q4 v5 d' q5 @' \' Q& b8 wU32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
2 @$ q: N6 ]& E; k; J$ n$ W7 k3 }1 R; n  f  D
static SEMAPHORE semMemSysPartition;
1 n% {+ ?" Z  a) |- L' U5 I* T: Q: Y, X9 Z& @* u8 m( l
static void memPartSemInit(PART_ID partId);
2 P5 ~2 P+ L+ z  g4 |9 }: I
4 a6 D  ~9 Y; C8 ?. h0 CFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;( w# K( R  g7 U2 ~" ^8 L

5 U; t1 j8 A" L) f$ s6 y; Iunsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
% }) n% r" r9 d4 t( ~
: t; j" i0 S& F( jstatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);
8 h; x8 j* e2 G+ x% zstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId! O0 }  @6 n4 X' D3 s7 x" l
        , FAST BLOCK_HDR* pHdr' y) m" W3 k+ `4 M4 E
        , FAST unsigned nWords1 N+ o! F$ r/ e; O% n+ q
        , unsigned minWords9 o. _  @- T3 u: ]0 z; o7 o2 q
        , unsigned align);
; C' |  z+ n6 g. U/ c, Z  h# D4 [% z/ [, |( o
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);/ W1 a  |9 J* b
- q  C9 t. v* M' P) e; i
STATUS memPartLibInit(char* pPool, unsigned poolSize)
0 H, `+ @2 Q' N% }5 \{
* ?! j" g+ q% X/ R) R' C        if((!memPartLibInstalled) &&   }5 c2 B$ r; u6 [$ U% {
                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
" a- W+ `, d+ H% C+ f: Z# o( w7 P; g3 I                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))
* K2 N- G+ F4 e' c2 u% |        {
9 X/ @. L8 Y4 Z" ^                memPartInit(&memSysPartition, pPool, poolSize);! o. T6 e6 m5 v) }6 u' z0 ?
                memPartLibInstalled = TRUE;
- V6 n' h& g2 T" j# d( ?2 `        }
6 l, y+ E0 r+ z. ~; q: m9 o4 J' r/ C6 u) e8 \" J. D
        return ((memPartLibInstalled)? OK : ERROR);
/ z( ?* T* A/ o' Y$ k+ T* n}
2 H8 u2 w) Z# ~+ o- p/ P* T/ f2 o: k- T+ A% K+ x
PART_ID memPartCreate(char* pPool, unsigned poolSize)1 w" A1 X- d8 O) w
{0 H$ T9 Q: B& t. W, [: \+ D
        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);# i( ~9 }8 d$ M( U7 U

* }( X1 i) J0 ^) O( C        if(NULL != pPart)2 q$ R6 Q$ b8 H" b9 Q, n9 e( f- |
        {
2 j5 T" Z* o! O! N                memPartInit(pPart, pPool, poolSize);1 w7 N8 p- ~) G" Q
        }
% X% G5 m3 F/ g8 d9 H  r: \0 m
) {: H+ e& i0 V7 q        return pPart;8 @/ Y1 v% ^& ~  t
}
+ ~2 D9 ]( U, v+ M2 H& O/ ^8 u/ L5 `" O9 l' r4 @9 A
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
2 D0 a7 U8 f  c1 j. h{
  f( R+ \; u- B- M5 y4 x. A3 \        memset((void*)partId, 0, sizeof(*partId));
& P2 c" l6 i  }! }, [- C+ C2 A  ]8 o9 Q4 n
        partId->options = memPartDefaultOption;
: Q0 f, o. c1 b7 @- Z" ~        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
" A" C+ l: @) e6 V. ~* ?% x$ }# C& B, J
        (* memPartSemInitRtn) (partId);
6 F& \! n( h/ W; X3 u       
+ c7 y  n6 K  z* Q# M        dllInit(&partId->freeList);" |: f. E/ v' ^8 r# m/ [
        ; ^7 F& \/ D. O" B* J
        objCoreInit(&partId->objCore, memPartClassId);9 M/ p9 }7 e: X% e, z/ j1 S
        * q. j$ m/ l* j* ?
        memPartAddToPool(partId, pPool, poolSize);
' H. C" j7 n1 V' \1 |  l}1 ~& \$ R+ ?% I, d

6 P9 z& r0 l) f6 y, N% tSTATUS memPartDestroy(PART_ID partId)0 m! R; z7 I7 W% \, s' k: _4 y
{
: ?- s5 P: C; h* r$ ?0 a        return (ERROR);, [6 @+ h' H* F
}
1 S( {# o) q8 Q# W/ b5 H: c8 q' O2 S4 S
void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
# R) Y# P" b$ U5 p5 W{0 i1 j7 F" O% _8 q8 c0 o
    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);
! t. U- \% F' y5 y: u. {% E0 b( d/ M}# _/ T  c  c6 K# Y6 e: p. |3 T

. w+ b. @8 q+ v$ N4 y
* S: j/ P4 m4 w& w; Pstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)/ G0 E& v5 |, g  Z  v/ E% Q
{) N4 W8 F3 @' C6 }9 F, S
        BLOCK_HDR* pHdrStart;+ ~4 T+ J7 v1 h0 ]+ v6 @2 c
        BLOCK_HDR* pHdrMid;
2 O- [  Z0 a! Q2 L- ]/ I/ f! a$ K        BLOCK_HDR* pHdrEnd;
. Y- N, T: r& k; g4 J4 m        char* tmp;4 m# ~0 ~! [% X, V/ ]
        int reducePool;$ N  E' X9 C% m4 e

$ L6 }- |* T: _4 g        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
* ]- x1 y; ?( t. n4 N        {2 F# d0 N8 D6 H# S7 S
                return (ERROR);
' }% N8 y' g! u' Y        }
  W, R6 M; Q( P: |
! T- Y% a& E* k7 F$ I2 z3 c        tmp = (char*) MEM_ROUND_UP(pPool);
* X1 ~7 y0 y6 m- i8 _- V. L        reducePool = tmp - pPool;
7 K. r/ P; s) J2 N
# x, j  Q. C& |5 n        /* adjust the lenght */! s# ^( v  y+ x: ^
        if(poolSize >= reducePool)0 Q% ]  r  x( A
        {
& M( B1 r* i$ I# c; s$ ?) F                poolSize -= reducePool;0 |* j* K7 |% H3 ]! N
        }$ Z  _* P/ H% n0 e9 w: V; Y
        else1 J/ Z: I. H- y- X1 M) ~/ ?
        {8 Q% t8 R5 ~" m+ [6 z
                poolSize = 0;0 Q7 f) }/ `. F
        }" ?, [/ u( Y0 g# p
        pPool = tmp;' }$ I, h7 S6 G8 a
        5 C$ ?$ \3 q6 i/ @. |2 N
        poolSize = MEM_ROUND_DOWN(poolSize);8 O  w0 B* l) p% s: s3 P
        2 X* t) M  ~! ~4 l% g2 a- k
        /* at least one valid free block and three header blocks */
' U6 v% e8 P3 [- s( A- B& l        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)
4 ?, @7 R6 ^4 M: F+ p6 o        {
  n8 D+ n% I6 E3 H1 z: l                return (ERROR);
+ @' s: P5 M; G2 W5 K! I- Y        }2 i' O$ F. c- H
( `0 J5 X, h9 d( m' d& j
        /* initialize three blocks */
6 g' ^, m. I- o; f5 S        pHdrStart = (BLOCK_HDR*)pPool;8 R6 W, i1 g  O7 i0 \
        pHdrStart->prevHdr = NULL;, f% k+ u" V/ }4 @. ?, d6 v9 Z, c0 X
        pHdrStart->free = FALSE;                /* never in use */
: q2 l6 K4 \' l        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;$ p7 X$ `/ F* h4 a
. }# E! U/ }, c* K
        pHdrMid = NEXT_HDR(pHdrStart);
6 j, V! E5 W5 C. ~2 T' |        pHdrMid->prevHdr = pHdrStart;" S  U* P, @) u$ k% i' V
        pHdrMid->free = TRUE;                        /* the main block */; o/ ]' a4 c; S( q
        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
; K7 M; S  B9 o) f5 Z) W! _8 _6 Z$ O6 V# j! H- e
        pHdrEnd = NEXT_HDR(pHdrMid);( c; C8 S- z0 S4 ?% ?; t, E
        pHdrEnd->prevHdr = pHdrMid;: S& R8 a' t; U+ n9 T
        pHdrEnd->free = FALSE;
1 P  l, l( u+ M. t6 _! j        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;
- w6 F) G6 v8 }+ X, |
2 ~4 J2 B7 L  @  z& C5 D+ g        /* TODO take sem hear */
+ c; @& I7 [4 K        semTake(partId->semPartId, WAIT_FOREVER);
" K" V" e+ G; ]! @( I        6 K) U, G/ H. ]/ o. e
        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));: b7 I0 G9 D: i# Y& {
        partId->totalWords += (poolSize >> 1);$ d4 ~. n+ Z! R# i& r# V: m
$ W+ _' ]- w: h, L# X
        /* TODO give sem hear */& r# `* R7 U3 D9 v
        semGive(partId->semPartId);0 \0 h$ R2 j# c
- c5 L- l  j' P7 u$ ~

+ e5 }' _* {9 M9 v" c4 J2 @        return (OK);1 R& B. |  w/ i, {5 w1 v) R5 m
}
7 |1 Y& ]- f) y. `5 r+ w  L7 {6 [8 F, I, Z0 ^. V" H
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
" c5 \; X2 H! e{0 P+ M7 F2 ]% r9 a, F; i! ]4 r
        FAST unsigned nWords;
: G9 K  G' i* r+ V' L        FAST unsigned nWordsExtra;  d/ r+ n- k! I6 \% C7 o7 k
        FAST DL_NODE* pNode;
$ v' A" W, x! I. Q$ ^% y" U: M        FAST BLOCK_HDR* pHdr;+ G0 J6 p% X6 w( n* C$ u/ e
        BLOCK_HDR* pNewHdr;
7 s! |1 m, m/ u- `        BLOCK_HDR* origpHdr;$ i( v' Z6 M% S7 J6 A( ]

: r" V$ o5 Z. S- R* b        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */1 E4 f* g# B! D( V% R$ F8 |
        {
  B+ K# ?8 h# j% F) A3 X4 Y                return (NULL);/ {+ b4 \2 [* s+ ~
        }
. E7 [3 P( a4 r' i
, h8 n. g" Q2 P  s) f        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
5 ~2 `9 ]3 R$ l, i
2 K0 U: _- Q3 M2 a        if((nWords<<1) < nBytes)4 z6 F, u. G# h9 \& L. E( L
        {
! L/ ^# z& d' o& S2 t" b                /* TODO suspend the task */
. s9 \3 a: ~! D: f                return (NULL);
/ W5 D$ c; o; T8 O3 w8 ^, g        }
4 W0 a  S& h+ W9 v8 i. n. ~  Y  o! n  p. M% V& k
        if(nWords < partId->minBlockWords)' u5 g+ [' N) V5 u* ^
        {) c: J6 u" o( U! k- P4 b7 V
                nWords = partId->minBlockWords;
$ g# Z3 N4 [! D1 p: t/ [5 g9 e        }
. ?1 w$ m% g9 K- K5 q0 v- `
/ Z2 H: |" ~7 M        /* TODO task the semaphore hear */1 \: P; N5 C: g# y2 i( e
        semTake(partId->semPartId, WAIT_FOREVER);
  z) O/ ?: e; t2 K% X" ?, D4 K3 q        pNode = DLL_FIRST(&partId->freeList);& H% Q7 @3 a1 L% M
        nWordsExtra = nWords + align/2; /* why? */7 V: A7 X$ u# Z3 E0 R  J
9 a. Q6 L( ^6 W3 T  n/ D
        for(;;)' I/ x( r7 |% `& S& A' H7 I0 j
        {$ f0 x9 {3 o% }! s
                while(NULL != pNode)1 O9 u' k0 d, l8 I" x1 L9 X' \* a
                {9 |6 k4 i* o+ S/ @6 t+ v, D! a0 ?+ b
                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
, }- ^8 p0 L# y) c8 q- F" i                                ((NODE_TO_HDR(pNode)->nWords == nWords) && 0 q$ o9 z4 Q# |) w2 p2 j* Z& |$ w
                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))" g5 W3 O/ x$ u5 l2 {- ?" I
                        {% N: t* G* y6 G  L9 \) }; {3 h# m4 x
                                break;
3 r% Y! u" m6 g& r4 g/ P" ^4 d5 {                        }' _$ a& e3 I" e3 V

4 i; M- j& I, R& Q                        pNode = DLL_NEXT(pNode);' `: ^1 ]8 D4 q  b3 X+ y8 q/ _' H
                }1 p! ~- T3 n' g. S
; d' u% {" D, D$ h4 o" U
                if(NULL == pNode)
7 v6 v8 O% q8 u+ l) K2 L4 j                {% x1 `' B6 ?: O; V/ a
                        /*TODO give the semaphore */
8 j9 H' z& f% Q  e                        semGive(partId->semPartId);* `7 j/ A7 ?. e" Y
                        return NULL;4 f& l: N# O* {% K, ~- i6 ?1 G/ B2 s
                }% f( F" w3 l: A; s% j
2 A3 h3 G. l$ e$ s4 d, X: Z3 {
                pHdr = NODE_TO_HDR(pNode);
; l; t3 [6 _/ E! ^3 S- t. }' l                origpHdr = pHdr;# _/ X) l" n+ t# _! L1 n! {
- W+ S8 j- H9 D7 }2 S
                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
/ d8 M% P$ |+ v3 k& D9 R6 m  U                if(NULL != pNewHdr)8 c3 u6 E3 G  E& J
                {9 O- N: z) |7 d3 M# n
                        pHdr = pNewHdr;) w9 T0 E6 F0 n: h2 e
                        break;
6 y, ^8 J7 ~* P" t                }
& W& H" N( H9 T4 \8 N0 Y, s2 T7 b% l$ E' D& e1 p1 A
                pNode = DLL_NEXT(pNode);: e- T7 a" R0 V  j, |: x8 K* D/ [
        }
/ x; Y) v$ r* V& H8 e
# N$ ~7 r3 R: ]6 i5 B; Q# L4 E2 N        pHdr->free = FALSE;3 K. @% ]' v2 c( h
        partId->allBlocksAlloc++;  s4 {$ h! M  I% z# P- B
        partId->allWordsAlloc += pHdr->nWords;
  ?' |. M8 L( }9 l' {$ _        partId->curBlocksAlloc++;; n# A9 }' o" f
        partId->curWordsAlloc += pHdr->nWords;0 A, e( n4 S7 T/ Y

& h$ Q8 L$ E; e* z, o9 w5 J$ Y        /*TODO give the  semaphore hear */0 L9 B2 Z( i" U+ l
        semGive(partId->semPartId);' x5 O' e9 |" s6 V7 `
        return (HDR_TO_BLOCK(pHdr));
/ R2 v) o4 l) v7 |$ G, P        , U' l: u; c1 l2 k$ j7 J$ U' i8 E
}! i* l2 F* K8 t% r5 e

2 s0 e1 v% t! N+ tvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes); X: a. _6 I; e) u  G, B4 g" ^
{
, t7 H: }; C& z5 d) U3 _        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);4 y- d8 W; _- g! H/ A
}
! r% z; v4 k' }) ]; R8 o/ ^% [. V) B/ ^: _# E9 g$ q9 D  S
STATUS memPartFree(PART_ID partId, char* pBlock)
& T* J" H9 z( G  n: {% }  j( M: z{/ t. j- }4 ]- h6 a
        FAST BLOCK_HDR *pHdr;- x+ C# c8 E7 E( L; r4 n/ k
    FAST unsigned   nWords;4 G4 Y! _* a! Q2 y5 l
    FAST BLOCK_HDR *pNextHdr;; K0 N! j3 h$ e

9 ^& a  W4 a/ |! d        if(!IS_CLASS(partId, memPartClassId))
9 a+ a  d% l4 y5 g/ g# k        {
0 W# P6 ?- D: c5 W                return (ERROR);
, Y6 `/ [3 A  F        }
4 Q8 a( e$ E9 f* I: J( \; H
6 J' @9 V" i' T7 l4 f        if(NULL == pBlock)& }' b* A( x9 d. W$ @# h6 M5 [7 ^
        {
" @! H5 X. {+ B; }" S                return (OK);5 c( b9 h; X- [
        }) ~% T2 I# ?# [9 S- k* u9 [
7 Y/ l# S  D1 `+ h# ]$ L1 G' O+ Z% ~
        pHdr =  BLOCK_TO_HDR(pBlock);
$ z8 O% ?6 v( ^. O3 u- W; C" W6 B( g
2 @: K4 R* e- C# l        semTake(partId->semPartId, WAIT_FOREVER);
: d* R% r" ^1 Y$ ~! p# R3 v9 h' B- c) e# U- A' B2 m8 ?
        if((partId->options & MEM_BLOCK_CHECK)$ I& o' H$ i2 e  E
                && !memPartBlockIsValid(partId, pHdr, FALSE))1 R* B4 a; [7 f+ O, G
        {) c" S1 w* t0 \8 q5 b; `1 }6 i, z* h
                semGive(partId->semPartId);0 w2 ]1 x% i% Y4 ^; J
                return (ERROR);
! _5 B* ^" b, ~$ x7 \+ F, }        }/ H* H% ^3 c2 E6 x% U2 t
+ _1 C1 T3 R6 U4 r0 i
        nWords = pHdr->nWords;
( Y. }9 E  ~# ^* c: \, C! k. h        if(PREV_HDR(pHdr)->free)% m+ L8 N6 G, v) y* d6 W! y+ M3 z
        {/* the prev hdr is free and than coalesce with it */
! P) X  V! H* l                pHdr->free = FALSE;
/ T. z$ b$ v9 j% R6 q! s* s* |                pHdr = PREV_HDR(pHdr);
! `4 p7 H! u. ?$ p                pHdr->nWords += nWords;
5 k' D6 ^: E9 E% M% k' p        }
1 h9 R* J& T* G        else4 E, @  I: V* ]3 b8 u
        {8 C1 N' h7 ~% V/ W3 B3 M
                pHdr->free = TRUE;
9 o$ |* {! i$ @- j* F+ |2 d  |                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));9 c2 x% l, k. F* c4 D1 f+ i
        }8 O! D3 `3 c+ y, v9 R6 t; @0 B

4 T8 h" G+ Y# [1 W- k7 P        /* check to coalesce with the next */
9 Q0 h# c. I' z- I1 i% @1 Q5 `8 |% |8 }9 Z        pNextHdr = NEXT_HDR(pHdr);- O, _5 D, X# Z* O5 l$ L) ~
        if(pNextHdr->free)
; I  W& y! f9 {. c        {
  H/ n  K1 Q/ G. S" T- `' t* ]                pHdr->nWords += pNextHdr->nWords;; e$ p1 v  a3 O
                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
5 d! O6 J- r$ [8 {! R) q        }/ ~* r' R' p. O! i
# k0 W3 E% m; Q7 U! Q" `* w
        /* cannot use pNextHdr->prevHdr=pHdr hear */& M% y( {) @/ G( ^
        NEXT_HDR(pHdr)->prevHdr = pHdr;
. H1 E# b& Q% G  C* f
# d/ d; L2 w; N* t4 m        partId->curBlocksAlloc--;
' I2 }) v: {4 P  h2 C        partId->curWordsAlloc -= nWords;2 @+ O$ ]2 [/ B+ Q

! L. S8 m! {. T& y( I. U' {- a        /* TODO give sem hear */( r& j' G6 d" C
        semGive(partId->semPartId);5 W8 T& i: ~& g0 V
        # v( ~; u  {' n0 o8 D$ Y3 p; q
        return (OK);
- I+ G' Z$ k' ^}
& V; ~6 U4 E1 P$ H" ]' R* R' T/ _
* x5 R- d  w# k2 Y, a6 t+ Ustatic BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
# F9 B3 I+ W+ K) t- u4 n3 z4 P& `" M  D{- x! b$ q) r8 H
        BOOL valid;' ]8 O5 P: y! p2 p3 I% y
7 y/ U% E" E( q1 k
        TASK_LOCK();6 P! w& X1 n7 t9 N$ @
        semGive(partId->semPartId);  r) U" ]+ c7 K! F5 x8 G
        8 D' \# V3 P9 }
        valid = MEM_ALIGNED(pHdr)
0 s* h+ C) H+ [* ^$ B* D% N        && MEM_ALIGNED(pHdr->nWords*2)- [, G7 z0 Q5 I! J
        && (pHdr->nWords < partId->totalWords) + a0 {1 y" I# Z+ S: S" P. S
        && (pHdr->free == isFree); f4 W, }+ K% O6 ^
        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))
3 d, n5 y% h/ E4 b. I        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
) C$ s; k8 V* A8 L$ v       
2 r: ?: [- z) B, e! t9 d        semTake(partId->semPartId, WAIT_FOREVER);
* V: u% T2 m! X9 a) C+ ^' ^& v        TASK_UNLOCK();. N/ i; o' g5 l/ w( b4 L

0 x' K' q8 Q3 ]        return valid;
6 M* h- y: d1 |  y" B5 z}
, m6 r8 x* _  G  n" W1 q) J/ ?9 g6 v
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
" Z( I" d, J* ]. I+ j# P2 B3 W        , FAST BLOCK_HDR* pHdr
; F+ T& J! B4 u9 {' i& _        , FAST unsigned nWords
& q' ]8 L8 e: T% J# X        , unsigned minWords
) N- ?5 F9 y" T        , unsigned align)* E, y, J. |  e; ~) o' c
{
& j; y  H" B5 x        FAST BLOCK_HDR *pNewHdr;3 }( T6 t1 `# h3 m
    FAST BLOCK_HDR *pNextHdr;' ^; a- y6 v) T6 _' q0 y
    FAST char *endOfBlock;5 x' Y& z  P/ y0 Z
    FAST char *pNewBlock;
9 ?6 r2 f  u$ u0 e+ L* _, q  u* c# K    int blockSize;/ Y' `* x' h# [2 C6 H3 `' d
; a4 P, B; O1 k+ A0 T4 D
        endOfBlock = (char*)pHdr + (pHdr->nWords*2);
" h/ p; B: r- B9 N8 [) f! {" B$ k; k6 U* R) Q7 a+ C# n
        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));
* _, H+ C! {+ d/ J, O9 P+ K3 M
0 E* o/ Z0 y' [' n. F4 ]: K# S        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));
0 D! @  M2 @/ n. ~
% @# Q( |: _* Z4 v  a        pNewHdr = BLOCK_TO_HDR(pNewBlock);2 Z. W8 G3 T6 t3 D, q: Y

/ o: w; m% D8 b. O  e# g8 b        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
6 M& d' l2 a2 b8 i
( o2 m$ b' N6 h; ^        if(blockSize < minWords)% S9 w( _7 M5 g( F9 L
        {- y( ?9 z+ w) Q3 x
                if(pNewHdr == pHdr)
% t- j+ D. M7 m% X. K2 h* v                {7 L4 q! _* o8 \- }' s
                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));. X! ~; h: @7 W) Z4 o( D- G
                }2 Q, E& \1 H  p
                else
; b; i1 @2 J2 @4 C- E                {
( J8 C1 h2 f- J2 d3 a% o* z1 V4 S                        return NULL;
# ~; L% u* d4 r: F' H( |                }+ n0 g- b2 b/ J) O, H# X
        }" k3 P) c8 C6 t5 ^
        else
0 @. X0 V( a0 W' C8 T; a  p        {        /* recaculate pHdr */
$ }& P5 Z& ~* J7 v' @3 ?$ B8 W* \                pNewHdr->prevHdr = pHdr;5 r( i6 o- J# U: P$ A* X. g
                pHdr->nWords = blockSize;
  p3 i1 w) z  n0 w9 q( M/ w- ^        }
' B5 J/ N' m. V$ Y3 G
# k% V" Z4 t1 V, a: P        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
( d  |' m. C! ^/ y* x        {
0 `! S) S( z: ?  H                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
! L. x; ?! O' Q- Q; _0 y6 R2 d' O                pNewHdr->free = TRUE;- x% V1 s2 ]. r8 M! D7 L  Y3 b, ?4 d

) l5 l2 g: A2 r                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
! G2 N# d8 j% O$ N        }) I/ M& q4 |  e3 M
        else
0 t4 e/ z- C  K        {/* space left is enough to be a fragment on the free list then */
: a* Q. w' ?& p) |$ N                pNewHdr->nWords = nWords;
( L  K, P  \. A                pNewHdr->free = TRUE;- P3 M- U1 K+ {, D- g5 E

4 v3 ]* ]1 S# f) P                pNextHdr = NEXT_HDR(pNewHdr);6 Z4 Z9 y/ j# m& r3 T
                /* words 包括BlockHdr */
- e# R, P  ]) |* V- ]* H: `  W8 b                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;7 c7 D, p5 O$ S) `
                pNextHdr->prevHdr = pNewHdr;% I6 _# c% f  F& J! P1 N2 m6 d7 X
                pNextHdr->free = TRUE;3 F2 A5 y$ m8 `0 L
# u6 q9 M9 I5 f; _- S" q. k
                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));- E% p# h) ^- c" X0 H  L; L1 ?/ @1 z: K

1 X( u( n. {$ F' D, n1 d( d( K0 h                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
% o! G# M4 W- w, W: D0 I/ _% K        }- a* A1 Q6 s0 D7 s
6 i& ]: c6 }0 f4 u, v
        return (pNewHdr);* p+ a+ @2 @& w% F9 T: o$ |" f
}
2 w2 w! ~# `2 G' f% I' u2 i
+ v% b& g! f4 Q- ]1 d/ bstatic void memPartSemInit(PART_ID partId)
& j- A0 b/ m' z5 m" [" U& b{
, |+ L* a; o- G( Q8 O# r. {        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
5 J& f  f( w' O9 k, v. O' M6 @. B) c; ]" J; ^' e
        partId->semPartId = &semMemSysPartition;. b8 B! y- Q: e. ^$ Y2 \6 b
}
7 f6 ^  @( g0 L& W2 {& Y  t: x+ H. P2 m  E' l6 @, d+ V$ {# ?  b
void* malloc(unsigned bytes). @" r: ?2 E" \- ]& Q! v6 Y! h
{/ @0 {( S0 B5 K# x
        return memPartAlloc(memSysPartId, bytes);) I6 N3 c, d& D
}2 ^+ x1 Z+ e7 Z  ^0 |- s
3 A' U  n( L- |9 _" \8 E# Z1 |, {3 l; B
void free(void* p)( G# v' b, Y3 k) q/ F! X' v
{' |5 e  b! l" w7 O% ~$ F
        memPartFree(memSysPartId, (char*)p);) V' p& {* _7 d* ^" ^
}5 P( U* @$ Q) ]( e  ~8 ~





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5