数学建模社区-数学中国

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

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

! M1 w, Q) w. A! p4 I, J. h1 S2 M& ?
6 T, O6 H9 j4 S6 i" ` *\file
2 ^! N" h4 j% j *\brief               
: U# }0 n: y& J* p& d' y6 M) Z9 U *\details        $ H) ~6 W* m4 q% e! [
*1 t* _) ]% D& K+ z0 }8 d6 Q+ m5 m
*\author        Janson3 p3 [; F+ [; Q% g8 j
*\version       
7 ?: X# j, k# T+ H* g- J6 u *\date                04Jan12
6 z- w& a) l! P *. J! D6 R  C: o9 S5 ~
*\warning        % }: O9 e1 O& k# h' S
*$ i* f" ^  s; @+ y; ]9 K/ l" ]
*\history \arg        30Jan12, Janson, Create the file
: D2 K0 {- F7 x *        modify from VxWorks source
0 j  j9 z0 A7 L! l# T0 g, J" E: g  { *  Legal Declaration: it is for studying VxWorks only.
% S9 l# `! o/ m+ R */
1 B8 x: i# U9 L& ]0 E& c- P" A1 ~- t#include "includes.h"' t' @/ q6 w5 [& N; A. j! `

3 d3 [- a7 Q$ h( v9 U4 {: h/* The memParLib.h file is hear:
8 S6 t5 Y8 q0 E4 jhttps://code.google.com/p/vxwork ... rivate/memPartLib.h
) P- x) y1 F- ^4 a# p! |1 n*/
! b) |% y* t; b' |0 k
+ U* _) ~* t5 q) I/* optional check for bad blocks */* O7 T# D& d" |. S2 M

* H7 b2 ]% S3 i- T% F#define MEM_BLOCK_CHECK                        0x10
# ?, M: B. n2 ]6 Z# l3 }( Z9 k: W9 E
/* response to errors when allocating memory */
7 L; \# m! E; @, g, `
% }, e4 K" o- ~( K/ f#define MEM_ALLOC_ERROR_LOG_FLAG        0x20
( l- ^# X3 O0 B9 p0 v+ ?7 Y#define MEM_ALLOC_ERROR_SUSPEND_FLAG        0x40
7 ]/ T! \$ Y& f! X# \& @" v+ c: p2 r
/* response to errors when freeing memory */, d7 m9 n* J! g6 B$ `5 P) x
6 R: Q/ u; F5 C' T& R, F& y
#define MEM_BLOCK_ERROR_LOG_FLAG        0x806 ?$ z; T; v- `8 m( z
#define MEM_BLOCK_ERROR_SUSPEND_FLAG        0x1008 d- J3 U) r3 i. ]3 A

2 F0 O( H& M, J) K* r! Y& R# I#define NEXT_HDR(pHdr)  ((BLOCK_HDR *) ((char *) (pHdr) + (2 * (pHdr)->nWords)))1 }; K7 @: Q9 B4 N7 e/ S7 Y
#define PREV_HDR(pHdr)        ((pHdr)->prevHdr)
' y# y) D) A6 C& Z1 x. K% H
7 ?; P1 @3 ~9 N% k) M! q#define HDR_TO_BLOCK(pHdr)        ((char *) ((int) pHdr + sizeof (BLOCK_HDR)))
2 m9 c4 ], I" r2 c; G#define BLOCK_TO_HDR(pBlock)        ((BLOCK_HDR *) ((int) pBlock - \0 ]6 h5 x+ E  j8 H: \5 _& Q- {3 u
                                                sizeof(BLOCK_HDR)))% _0 s( @, ~2 J1 U2 q
. O; c) W# H7 v) N$ b* F
#define HDR_TO_NODE(pHdr)        (& ((FREE_BLOCK *) pHdr)->node)( D) q2 v% f: [/ W# ?0 R
#define NODE_TO_HDR(pNode)        ((BLOCK_HDR *) ((int) pNode - \
# K* H: O! A/ [# [6 o6 g6 |; u, q3 L                                                OFFSET (FREE_BLOCK, node)))
* }2 J1 a1 H' S2 i9 e' x2 e
+ {3 u- `9 W) h) Z; ?8 astatic BOOL memPartLibInstalled = FALSE;
8 k6 u# j* Z% m2 ^9 g' e" K0 |0 ]3 {' J2 _! X
static OBJ_CLASS memPartClass;  y9 H( J$ e6 }6 q4 H/ G
CLASS_ID memPartClassId = &memPartClass;
+ ?  Y! e5 K: [& h9 [. J: G# I( g, |9 i8 d; P/ Y! V; |
static PARTITION memSysPartition;
; ~: ?1 m, @/ O+ iPART_ID memSysPartId = &memSysPartition;6 l. c: `( a/ I2 B  e7 g
U32 memDefaultAlign = _ALLOC_ALIGN_SIZE;
. G! C- E2 w) \
& T6 @5 y" ]2 jstatic SEMAPHORE semMemSysPartition;: R1 ~& ~/ d) }9 I1 o
6 ~- |2 \0 c* `2 c( L2 U$ [! @
static void memPartSemInit(PART_ID partId);
9 R+ ?* r' M5 }
5 S& ?  B" D, q9 \5 T  H3 _/ F* mFUNCTION  memPartSemInitRtn        = (FUNCTION) memPartSemInit;
  |2 c, o% T0 \( u5 ]' ~, W7 x2 z0 G  _2 h% O+ H
unsigned memPartDefaultOption = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;
  K4 t8 m7 H# K9 T! H2 [& y8 h3 s* W) F, X% X, ^4 S3 C  h( }
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree);# P: h+ G. ~7 P. F% A' a; J
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId
5 ^" X! |, A- S$ i        , FAST BLOCK_HDR* pHdr! \$ w* K: ^# S* R
        , FAST unsigned nWords! T( i' M& ]* l$ k( N4 R$ [7 K" x* l
        , unsigned minWords$ h, P- ?9 H6 l- r7 {- g8 l& b
        , unsigned align);
( z" U0 |, Y/ ]8 M* a# c8 e  l' u
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize);
) y, z. D" g/ W$ U! p; Y; x
9 x' y( z( t6 }# eSTATUS memPartLibInit(char* pPool, unsigned poolSize)3 f' w1 [7 s8 \. ~2 D0 V/ Q+ _
{# n% i3 U% s3 u8 N% P: K+ i
        if((!memPartLibInstalled) && 6 `4 x, I5 [1 T0 B
                (OK == classInit(memPartClassId, sizeof(PARTITION), OFFSET(PARTITION, objCore)
" ^" C3 a4 S) M/ i                , (FUNCTION)memPartCreate, (FUNCTION)memPartInit, (FUNCTION)memPartDestroy)))5 \+ K0 f  n2 c3 t8 h: o3 S# D5 E6 I
        {
7 j8 ?! V3 `' ^                memPartInit(&memSysPartition, pPool, poolSize);7 ?9 G$ v+ N( C, |/ l9 p! B$ K
                memPartLibInstalled = TRUE;
1 J. D0 ?7 R% G0 C0 Z        }
6 R% B  ~, r  t) d; k6 Q( `' X- G* R
        return ((memPartLibInstalled)? OK : ERROR);9 q6 z# Y0 @. [
}
! }! Y  z% a4 o% e5 p  M0 r2 E
7 Z1 x) e; d1 p' QPART_ID memPartCreate(char* pPool, unsigned poolSize)6 B% J2 c# k2 i3 L
{; [$ t# \$ ~3 O2 S
        PART_ID pPart = (PART_ID)objAlloc(memPartClassId);0 @8 ~# b- ^* m1 k" Q
- ?, ^1 I- O; ^) z, D& U! K9 ?+ F6 |
        if(NULL != pPart)4 q' n: V* l) D5 ^% t' M; B
        {
& ~' p" ~* e5 ?8 a, Q0 p6 ?                memPartInit(pPart, pPool, poolSize);. @5 a% g9 [5 Z) P. _& j& s1 G
        }6 D* U1 O6 d% s

  n" [: S6 \5 H( @- S: W- F        return pPart;
1 w& ]2 t/ \4 L& f}; {5 T' i/ i' K* P& @

% G1 W5 L6 {+ J$ Kvoid memPartInit(PART_ID partId, char* pPool, unsigned poolSize)
. P& v7 w0 B* u1 ^& F* k% w3 ~{0 D* y; d# I6 e8 ~# s4 V
        memset((void*)partId, 0, sizeof(*partId));6 X4 L' F, D0 w6 {/ a

( b; q# }' f5 P4 E# ~        partId->options = memPartDefaultOption;
: `. R2 t/ I# z: y* a        partId->minBlockWords = sizeof (FREE_BLOCK) >> 1;        /* word not byte */
- n0 _/ ~$ L( U
, Q& o/ K1 ~( Q' d* n- P0 D* g        (* memPartSemInitRtn) (partId);
7 e, g5 c! W, A. _" A9 d* M       
0 G. k! c& F% u- D) d' w3 c        dllInit(&partId->freeList);- ~' Q7 H8 @) p" {9 b( A! `, O9 e* G
       
7 _9 I9 j/ b- s        objCoreInit(&partId->objCore, memPartClassId);6 d+ O  d' `7 X. o2 I- Z
       
, ?0 i( ^$ |3 u6 o5 N) y        memPartAddToPool(partId, pPool, poolSize);
0 x2 c; a; w& t% q  Y2 [}  v+ b4 A5 i# l  O. z  T6 _# t
1 z. W& x$ @& Z  e' P
STATUS memPartDestroy(PART_ID partId)
3 p8 I0 f( P: E6 L" Q  c" X{
- {* U. K0 S& ^: ?, u+ y2 v: R        return (ERROR);$ c8 d# p' x0 W' a; i  {
}9 H, M4 p1 Z0 }/ ^/ Z" J" G

; a$ q1 r6 A5 O' f& x3 }% ~void memAddToPool(FAST char *pPool, FAST unsigned poolSize)
, h" y  j& `- r5 P  y' s{* Y* R! D3 |! p( [. f% V
    (void)memPartAddToPool(&memSysPartition, pPool, poolSize);5 s8 ^  U8 R5 t+ A# x8 m
}
1 F7 ^5 o/ k; w- R, c: M* Q& C* C! r- V! t: ^* n

5 V  Y$ f1 \1 `* S( I3 k0 I0 U3 Dstatic STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize)6 O3 M4 I8 v! |& ~/ [- _
{
  N: Z' Y8 [* x- v        BLOCK_HDR* pHdrStart;3 e+ H; O, Y5 {8 `  E8 o# V2 X
        BLOCK_HDR* pHdrMid;, m- q/ E0 {* N: y4 _
        BLOCK_HDR* pHdrEnd;7 b0 H# I4 \) b9 c$ X5 j
        char* tmp;3 a1 b0 S3 K8 o, M
        int reducePool;% A& I7 p9 F4 \; b) z- Z

5 u6 \) g7 Z4 f# d* u1 e5 [        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
( B& v, b8 c4 b: d" c/ E2 ]        {# S5 E+ K  G2 e% X" R  r0 N
                return (ERROR);$ [7 o- ?# P( p( x0 {
        }1 o" ~+ y. u' `+ s
: U: Q# u/ z: E! v
        tmp = (char*) MEM_ROUND_UP(pPool);* x1 |' t/ u1 p4 E! _: M+ y
        reducePool = tmp - pPool;
( J3 j/ Y+ |! n8 `8 F
' Q. h, C/ O# n5 b/ L        /* adjust the lenght */8 k8 R0 B# \3 @, U! g
        if(poolSize >= reducePool)/ Q/ d% y$ m- H% f7 F! e
        {# d% l( @  L9 |& R2 G
                poolSize -= reducePool;# g6 j7 I# w7 V3 B4 z: [4 e! V1 y
        }* a: l1 g! t  h+ x
        else6 d& Q2 G! Y5 H' ?- w: `. N+ C
        {
7 v# c( _0 f! @- F- K4 T6 h  M                poolSize = 0;- N% x/ J  T; F1 W+ S" q+ z
        }1 ]6 `# D' e8 [: e$ H! l1 i2 H
        pPool = tmp;& ]5 M; Y) O0 L6 V0 h
        4 G( a6 }1 X+ @' v
        poolSize = MEM_ROUND_DOWN(poolSize);
) [  P6 }: }1 ^3 N  l        5 R. Q, \1 F& u! z$ C7 |
        /* at least one valid free block and three header blocks */
( F, F7 A$ c, _( U- g+ d5 c" U        if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)7 R3 l7 E# c8 l$ V# K' A; y# e& O4 T
        {5 b) P9 J7 C6 q4 Y% s
                return (ERROR);0 ^/ T9 v8 E* ~$ j; z6 |
        }
6 M9 u5 S" w/ X2 M/ `  X7 |/ P# p3 |; x* n% o! D/ E3 t6 f' ^# M
        /* initialize three blocks */4 j6 |7 _$ H9 Y- ~# N$ q
        pHdrStart = (BLOCK_HDR*)pPool;
. B$ D3 e" G8 n  A; R        pHdrStart->prevHdr = NULL;3 r' m9 B" z9 p0 h. t6 R
        pHdrStart->free = FALSE;                /* never in use */
1 h- s; ^/ M8 w0 h/ ^: R        pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;9 |7 |) C, u! _& d1 K) _4 u6 O* V
) f5 `+ t; v3 s, o0 c. [9 d2 D
        pHdrMid = NEXT_HDR(pHdrStart);) Z9 H0 X$ M+ {+ T7 L
        pHdrMid->prevHdr = pHdrStart;. T; q/ C3 ?" T8 {+ r2 K( i3 L/ V
        pHdrMid->free = TRUE;                        /* the main block */& a2 _5 {6 E/ Y* L! g" y) D. a+ |
        pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;
; F' @) B0 x( m1 y! i) {6 Z  Q7 a8 b$ g
        pHdrEnd = NEXT_HDR(pHdrMid);
3 t# B" E: }$ z% v        pHdrEnd->prevHdr = pHdrMid;& f# v) v8 A4 l' h$ }4 |; G
        pHdrEnd->free = FALSE;
0 l& e1 K! V, A8 S9 W* F        pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;& T; [4 x$ U& ~- r4 v

$ c6 D) d0 L! |        /* TODO take sem hear */9 W& d7 d! s' A, R% b
        semTake(partId->semPartId, WAIT_FOREVER);
. b# ]) R7 c# ]2 w! A       
' S! }. U$ w2 ]0 W  Q        dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));; h/ V! |: N: B! |$ p4 Q+ ?
        partId->totalWords += (poolSize >> 1);
; ^3 N( g& O/ p, i' @# v: G) Y0 J2 W: h; y6 H+ i
        /* TODO give sem hear */
4 R+ r3 y) B: ?* \* g/ {        semGive(partId->semPartId);
# A1 f) ^, X# l& c6 O
2 W/ s2 J3 `! K8 D6 l$ N0 ?8 B4 A4 ]& I+ H4 H
        return (OK);
2 w8 _9 M/ S4 t1 m( a0 r}% L6 `: h$ x+ X- ^3 e# `6 O
0 D8 L; f& w8 b5 {, E
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
& Q6 M, q; G# m* r$ B: ?1 p3 H6 k{
0 D1 l# n( e# ?' ^% j6 N        FAST unsigned nWords;
, [" x  m3 O2 C+ w' J        FAST unsigned nWordsExtra;
+ s3 \2 S; N. p4 v  s9 V; u        FAST DL_NODE* pNode;( j' z; m$ ]  \4 v. }
        FAST BLOCK_HDR* pHdr;$ w6 i& ^0 q8 f) d3 D9 d
        BLOCK_HDR* pNewHdr;
' T% v) t# R( b* {# y& s! M. t        BLOCK_HDR* origpHdr;2 [$ c5 B4 a7 t1 O6 d0 q2 N: e" D7 i
' K, i9 l# _( R8 o
        if(!(IS_CLASS(partId, memPartClassId)))        /* only memPartClass can call this function */
# W0 g$ L% U6 D/ S        {
# k# w$ F8 X. p" y; v4 ?  s                return (NULL);
0 s& I; G8 A8 w3 K% b; c# Y0 r        }& D0 M2 t9 _$ C4 R4 Z

0 j4 @% f2 e: ^0 Q  E1 _        nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;
2 m5 K% B7 t9 u9 ?" \
2 W5 u  j/ X% c        if((nWords<<1) < nBytes)
8 O& B0 q0 F8 y$ S/ v        {1 i4 j' a1 Q6 b, |4 C
                /* TODO suspend the task */: O; Q; k, \( `0 q4 O" ]5 ~  l
                return (NULL);
9 w  K( A- _  Q: q1 o, K+ k        }2 D* f+ O( S. i8 F( g. l" c

" `& p/ }8 |; r& Q/ ?( k: x        if(nWords < partId->minBlockWords)+ w6 C7 y! K/ {3 W3 S  M
        {
: c; [& B& B) C3 _) y                nWords = partId->minBlockWords;+ n. q, L4 x. ?. I5 d
        }
% e" }/ P. e% j6 I- x6 X6 G; S0 C4 n/ G3 P  y/ e; }3 Z. R
        /* TODO task the semaphore hear */
$ E& T- P, k% d9 ^        semTake(partId->semPartId, WAIT_FOREVER);/ e; i: z2 N1 L0 l# C
        pNode = DLL_FIRST(&partId->freeList);
+ B- k4 H" p) g! r& s: k: y5 s5 R& b- v        nWordsExtra = nWords + align/2; /* why? */* d2 J% F: L0 E& }" k
2 l3 g2 Q% D1 R# y1 l  C
        for(;;)
' V) b- L  [$ }8 {        {: n- ^2 M: Y% g& P# O& v2 l5 t
                while(NULL != pNode)
5 y* t* c- F* ^6 R1 W, W9 I                {1 l' S" m. t4 O" n' h
                        if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
- y' H( `8 _0 ^& u6 C                                ((NODE_TO_HDR(pNode)->nWords == nWords) &&
5 _' W' U  [# ?( ?9 ^! y" w                                (ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))). W$ H( O5 u7 [7 D
                        {: R3 V5 u5 _+ o
                                break;
) @" M* a8 {1 _8 K( h  O                        }
) d( L2 [5 W! t) U- \7 ^( J: g- m* P" T2 R8 ]# w4 U( ^
                        pNode = DLL_NEXT(pNode);
% N4 `: o7 U2 ?- k8 I- s                }
' E1 W! n6 [; L* P& {/ o$ o
! Q9 |& a0 _9 D+ ~6 Y) Q                if(NULL == pNode)
( H6 P; ?$ V6 k1 k                {
! k5 Q( Q) X; p' n; V                        /*TODO give the semaphore *// g9 ~4 d8 n- U7 ]
                        semGive(partId->semPartId);
( D% P/ t2 J" E6 H* y; T                        return NULL;. I5 U" E- F+ w1 s+ l! {3 k: N
                }  I( C6 O! }2 w4 N4 e& m& B2 e* `% D

1 B7 u1 n: A6 V0 @                pHdr = NODE_TO_HDR(pNode);8 h1 B! Z& g# t5 c  S( e* P
                origpHdr = pHdr;
6 [2 `6 M+ ]. C5 |+ L+ j! o2 `1 t; B
                pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
. ^+ y" u1 [0 N& k, c3 H9 ^                if(NULL != pNewHdr): `' r- Y8 Z# c! C8 f7 d
                {
% J% @6 B" h  {# F& f* x$ E                        pHdr = pNewHdr;& D9 \6 H. Q4 n8 ]* T* s3 @
                        break;; t/ d. d4 ~4 X6 T# Z6 E9 o# X
                }
* H3 u% {  D& o, d  s; W0 p7 ]3 a0 Z& D
                pNode = DLL_NEXT(pNode);' C. F) O8 _4 h- p2 O
        }* d7 O6 c7 V( j7 }' f: V

, l* e1 ]# z# [% `9 I  H8 [        pHdr->free = FALSE;* Y2 E4 ]$ E6 P. w0 n
        partId->allBlocksAlloc++;
; J% ]9 U9 \' z3 y/ d" Z. Y        partId->allWordsAlloc += pHdr->nWords;
. X3 M1 S2 T# M8 k& `0 K        partId->curBlocksAlloc++;# ]' E  d" L( V3 O8 Q% m
        partId->curWordsAlloc += pHdr->nWords;( T2 T1 V* C3 k% U

* E" m3 c- Z+ U        /*TODO give the  semaphore hear */
' J; B7 j; \3 L. m1 Z        semGive(partId->semPartId);; d$ k. I& n  ?. l2 Q
        return (HDR_TO_BLOCK(pHdr));/ \# w7 z( ?: |
       
2 k4 J, }, y4 F" t/ L) c}
' s- |/ r7 K" I/ R; j3 I
8 a7 o) }/ o- j6 K4 _1 Kvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)+ U1 u# S/ a4 o3 I4 K
{
. u5 y8 E3 @! s' i) s! d5 O        return memPartAllignedAlloc(partId, bytes, memDefaultAlign);
9 i# q& t) b4 Q}$ J0 y$ j7 Y  }* c0 p" z, F( K0 ~" T; Q
- f* m6 ^* L1 A. A" K1 u9 H
STATUS memPartFree(PART_ID partId, char* pBlock)
- _8 D0 t# {3 x9 Y  e+ m( `{* ?4 d, d2 n, Z/ D- B6 I( l. J; t1 P
        FAST BLOCK_HDR *pHdr;! W  E7 T, U) a$ ]8 J: Q1 K2 S8 i6 D+ v* G
    FAST unsigned   nWords;7 P; D8 W9 O  Z: J
    FAST BLOCK_HDR *pNextHdr;! F- ]# w$ o$ u- Z, S8 J1 l4 r* q
# b9 U9 o% V; d1 A$ A
        if(!IS_CLASS(partId, memPartClassId))( A) h$ }* [- R& I2 R9 G
        {
; Y7 J' Q- V; Y; d# w; l7 y                return (ERROR);* r. B7 s+ D) [5 T
        }; `8 @, P6 ~1 G7 `7 ^& U
" Y7 G& L6 T& E: ?
        if(NULL == pBlock)
) Y( ]) P) h8 G        {, s  a) {- c" V5 I5 l8 a
                return (OK);
; I4 E& ]# p) ^& y        }" G! W, y7 }3 Q
3 }2 b; x8 y) H8 y0 K4 R0 c
        pHdr =  BLOCK_TO_HDR(pBlock);! w% X9 k& ^. D' D! P& x

0 f* v1 `3 Y9 I8 G; g1 ~        semTake(partId->semPartId, WAIT_FOREVER);1 Z# Z" E/ C, ]0 Q" h" Y

8 ^8 q4 ^2 J5 G! }: h        if((partId->options & MEM_BLOCK_CHECK)3 A& x$ W3 `  ]
                && !memPartBlockIsValid(partId, pHdr, FALSE))
; e& E3 U0 d  u3 X& W: k        {' f# C% d- ~/ c$ q$ o
                semGive(partId->semPartId);8 Z/ j5 r1 ~: a  v, @
                return (ERROR);8 B1 W6 l& r, \) e" f
        }
* }& F! r! g& g7 Q9 Z
. f$ N7 A/ c2 T& Y" j        nWords = pHdr->nWords;
1 o. j* m# F: }- J2 j% C        if(PREV_HDR(pHdr)->free)
! S9 S/ r. r2 V9 }1 t        {/* the prev hdr is free and than coalesce with it */, k$ i- L! s9 ]/ n
                pHdr->free = FALSE;
9 `8 E+ q  L5 D; k                pHdr = PREV_HDR(pHdr);
+ ^' W- O0 W) {                pHdr->nWords += nWords;- c4 ~( d6 v4 n6 e
        }
6 R: t: B9 D: l* L* h8 K" o        else0 w4 \2 }9 F0 f
        {# M) P8 ~4 e. x/ z) X* w
                pHdr->free = TRUE;
1 p! X3 s7 d8 q+ @/ b                dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr));2 V6 q4 b5 S4 y5 W* }
        }& X/ f- Z% G. [8 x$ b8 h" R

5 y2 |# |9 a. M& c        /* check to coalesce with the next */2 ~$ P& t% ~/ [% E
        pNextHdr = NEXT_HDR(pHdr);; F- x! ~, q( `- c3 Q
        if(pNextHdr->free)
! F0 ?3 o9 w7 k4 B$ X4 L9 r        {
) s! H  L) X8 @: l+ u/ b                pHdr->nWords += pNextHdr->nWords;2 j" e2 ]; ]/ s
                dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr));
. J2 u* q6 F: l$ B        }
+ [# m1 r9 G+ I% f; ^, Z: O5 B: o. W& h9 g8 U
        /* cannot use pNextHdr->prevHdr=pHdr hear */
' R6 d9 z& S, f        NEXT_HDR(pHdr)->prevHdr = pHdr;
% m( s0 G1 g' i; X* C2 X' X7 {/ ^! n% ~' n
        partId->curBlocksAlloc--;
& P+ @: L3 g6 i1 r% ^# X+ M5 W        partId->curWordsAlloc -= nWords;
/ t3 f' e7 e) o* T, y4 A9 w8 v
! j% \- [/ @3 B' k5 u        /* TODO give sem hear */
, w. y9 c3 P( f        semGive(partId->semPartId);
% K. K; j( r) m+ b( @        : Z$ L1 q( Z) y+ i
        return (OK);" b( E# G  r+ m8 {0 k6 ?6 ?" b+ X
}
# V9 R% y* U$ Z; u) H! U9 b9 f! _- ]1 C' R; U  K
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree)
; K. ^' ^. b3 x4 b: b1 Q( T9 k: D{3 W8 F" y& L( g, r  C' C7 U7 {" J
        BOOL valid;
  F1 |) b# X$ S/ F* |: w9 @! A
1 R- }6 x* \# q7 K        TASK_LOCK();
' w/ O8 B( Y$ z! d0 h8 C( ]        semGive(partId->semPartId);
# W% Y9 s6 F, c$ C% b3 ^2 X, |' c1 p        - j3 d' p: Y1 W3 N3 z, L4 K. P
        valid = MEM_ALIGNED(pHdr)9 q1 |, i1 x/ n, d
        && MEM_ALIGNED(pHdr->nWords*2)
" ~& I9 n8 J8 O# \6 ]+ L        && (pHdr->nWords < partId->totalWords)
: t* ~" |/ [/ ?, S        && (pHdr->free == isFree)
( c# m7 E8 ^* o) s, F2 g  }        && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))+ f" N3 f3 ^! q" B! K: _
        && (pHdr == NEXT_HDR(PREV_HDR(pHdr)));
  c1 \/ o0 B0 X        9 c+ M- V7 H2 h
        semTake(partId->semPartId, WAIT_FOREVER);
8 g8 l8 Z2 A0 Y        TASK_UNLOCK();
2 P3 [5 q7 y" r. }. J
$ o, f+ s& t' O        return valid;5 t) o3 s  u: h3 x
}. W4 j3 X. O: G: s0 x( |* {
* B. K( n1 k+ `, @  h5 u
static BLOCK_HDR* memAlignedBlockSplit(PART_ID partId/ }! g( P, ?( \# b' V
        , FAST BLOCK_HDR* pHdr
3 y0 s: l$ {4 L. @/ s' q        , FAST unsigned nWords, N( n4 d4 \5 _1 ^
        , unsigned minWords
' H5 B0 H0 }- w2 ]# r# m. }        , unsigned align)" z' x# a4 Z& j: v/ s8 ~
{5 k2 p+ z  X3 C. b
        FAST BLOCK_HDR *pNewHdr;
4 D+ h# N# P+ s4 v1 v. `5 K. m  E/ A    FAST BLOCK_HDR *pNextHdr;
% z6 h5 f- u) |8 M  c4 ~    FAST char *endOfBlock;5 n$ t, g" F. W
    FAST char *pNewBlock;
' \, Y! Z3 N$ ?5 Q* r+ D& X6 c! w    int blockSize;
1 ?( B  u7 @3 ~) c" J! G, U: ^. J6 F: U; F1 q
        endOfBlock = (char*)pHdr + (pHdr->nWords*2);) [% A1 n/ Q0 Y8 J" Z

: |( G4 m8 i3 x        pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));) [0 K. V# j2 B  Y
0 N3 d" q3 Y7 P; F- O
        pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1)));0 L3 s/ D& h3 h- [# ]7 E0 B2 t

0 d4 t2 u' d# `; ~8 H        pNewHdr = BLOCK_TO_HDR(pNewBlock);* ?: w" ~- Z9 V. A( E1 G0 g& s: t
1 c# J. ]+ @9 `- _
        blockSize = ((char*)pNewHdr - (char*)pHdr)/2;
, Z; q- w& Z, w( j" Z7 E& Z% S1 z, Q2 J& D2 H4 o( M
        if(blockSize < minWords)
; A6 e, ], @7 o. ~/ k        {6 ]+ R) X. U7 v. ]# [5 x/ e+ Z
                if(pNewHdr == pHdr)
7 G: s/ O: J4 I0 r0 B                {
5 h% z+ J6 q4 W" C2 b# p; ~5 Y                        dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));
# P' s! H; _# X4 A/ C                }
7 Y  D  @0 M% I  i+ W) p! a6 i4 T) |5 X                else1 F; {% b# B3 [
                {
& _" C" [9 T3 j5 g; c3 N' _                        return NULL;
: D. |; y( e. n* s$ e                }' y$ `( S" w/ s' ^- N% c  ^
        }
1 D$ N) P6 ?& V. [        else
0 \5 f' I9 L+ G9 C0 f) k1 {8 {! R        {        /* recaculate pHdr */
9 s% j% b" w% O; ?& p: p( b                pNewHdr->prevHdr = pHdr;
4 y2 J' i. y6 p) @/ K$ ~                pHdr->nWords = blockSize;
+ w2 O! Y8 d/ N, O" C        }
3 K" |" R4 _6 g5 O! {& S$ q' G, s- x% Z2 `/ |3 R% c/ I% K
        if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))
( x6 d4 @5 C3 c5 @: ^        {9 z* G7 M$ q$ Z% O5 u! ^; a* o
                pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;
0 N! R& w2 A- m6 k( L                pNewHdr->free = TRUE;
: q: h: O) [! e6 U/ h( h9 m" {6 w  A# @$ G( e
                NEXT_HDR(pNewHdr)->prevHdr = pNewHdr;
- g. X7 t/ V! h, r8 h        }
) w) i; k- ?( i        else$ H0 Y6 w) W# L8 w' J
        {/* space left is enough to be a fragment on the free list then */: d) W$ e8 K; w3 k, m
                pNewHdr->nWords = nWords;
2 G& q) U9 c& R  K) L% Q0 L                pNewHdr->free = TRUE;
, @. ^0 s2 N  d& j- t8 O) r
  k( B& w( u2 ?0 j                pNextHdr = NEXT_HDR(pNewHdr);! T6 G$ T! T. V+ ]5 ]+ t$ `
                /* words 包括BlockHdr */
! c) D7 P- h/ L, W                pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;
8 k  \, f7 t% V( o( S& l                pNextHdr->prevHdr = pNewHdr;" s8 r/ p+ r' f- N! R6 K& Q: w
                pNextHdr->free = TRUE;
) S  v* F' Z* N! P) ]# U- `+ o; s! k- M* }0 f# i; t. S; z# X
                dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr));
0 P0 c. r+ k$ S# ^0 K$ L8 P$ Z; e) ^4 O  U6 G
                NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;
/ Y" h( @! R7 O- }4 R        }# l0 \# `/ Y- D" {  a3 B) U0 Y, p- Z
1 l; m  p' Y# ^+ o: u
        return (pNewHdr);5 B* E, \* e7 A( P2 T- ^( H
}
" N/ R6 X7 h! t
2 Y1 H4 B- I9 K6 ^. {( n" Z1 Vstatic void memPartSemInit(PART_ID partId)7 R4 f- S% D$ v& ]! A+ e+ k: X! i
{
1 M0 w/ y. z+ Y8 M        semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL);
% S! n8 c* _" g. L+ c$ G% w. l3 R: Q
# ~. l% U- _. a% |# E7 I        partId->semPartId = &semMemSysPartition;' }( K" e' {. l! [+ D9 M
}' O- l9 K! g, S) ~1 ?
; p' |* u( x3 w- U# E1 m( N) n
void* malloc(unsigned bytes); w: X  \; r% W1 O" u) ]8 ~# d/ |, k
{/ h* ^4 T% ^5 R* k" f) V
        return memPartAlloc(memSysPartId, bytes);
- F2 Y; z, B) W0 {: V}( V# G! [- x( c* k( w& M

  _2 `% q, U  {& g& g" [void free(void* p)" Y3 F' B" B/ n3 `
{" m1 x/ h' b4 D; u* n/ z
        memPartFree(memSysPartId, (char*)p);
+ v5 R/ Z7 P, O4 K. k! {! h! a}  w0 k+ f0 @3 d! a8 e





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