. Q: q# S) a4 W2 L7 N- { return pPart; & H5 b L8 K1 {" T& x* _} ) A+ [, H# e" Z$ r3 j* N( d: _( y1 j- t6 C) B& F
void memPartInit(PART_ID partId, char* pPool, unsigned poolSize)' U5 h* N& i# Y; ^% I
{ $ w! u" f/ Y Q, k6 M) P memset((void*)partId, 0, sizeof(*partId));" p& N+ V }; D3 ]! c8 O
) U! C. I' G3 v7 ~3 {1 y partId->options = memPartDefaultOption; 4 r3 q9 B7 i# D partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* word not byte */& z8 v `" ^9 |( `( S+ f
b- N8 E( M* s+ a
(* memPartSemInitRtn) (partId);2 C1 J5 j4 G! u0 f- Q9 e
3 }" C% b H' a: a: ]9 L" n dllInit(&partId->freeList);; P. F* T$ [, `/ ?$ ~ D
5 S2 m4 {+ @8 d$ ~, g8 @ objCoreInit(&partId->objCore, memPartClassId);5 P5 A) |1 g0 x, k0 k
% S( b6 O N( `0 w
memPartAddToPool(partId, pPool, poolSize); 4 L9 R4 m* z3 [ \}+ ^' H: m, q8 N9 U) i' e
! I z1 \% A/ j5 G' I: F# E; Q
STATUS memPartDestroy(PART_ID partId) - d4 |7 d" x# D$ Y0 d. }0 S{$ C* i1 p+ u5 G$ a
return (ERROR);8 y3 i' J) |9 `
}0 j* ^! K: d% `
! d7 v! }) N9 [! }3 Gvoid memAddToPool(FAST char *pPool, FAST unsigned poolSize) 9 |/ w* M- L9 z7 I% E7 N{6 B2 z2 u. a# p7 S
(void)memPartAddToPool(&memSysPartition, pPool, poolSize); + Z# ]& D' P' ]1 C. ?9 K& w} 6 C5 t ]% i9 N1 R5 A' |+ _, o; C6 B" }: ?; a$ l
' h& ~6 t1 g$ E
static STATUS memPartAddToPool(PART_ID partId, char* pPool, unsigned poolSize) ' j0 W! `' E* u& Y1 p. k) [) W{+ W2 y; x* X, F {
BLOCK_HDR* pHdrStart;9 Q* C: I8 I- H$ L6 J$ `6 O
BLOCK_HDR* pHdrMid; 2 o. n5 s6 ]! ~ BLOCK_HDR* pHdrEnd;# s, a- r$ J/ M; J
char* tmp;- F' W1 o" p: ^1 u$ p
int reducePool; ( R$ }% [6 H1 x$ ]0 g 9 q' A1 t; A8 h% |* ` if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */# ?$ y, f! w: H1 Q
{ 6 N# k R9 q1 ]$ l- y: } return (ERROR);( D3 r a5 T8 M- _# v0 {( E, ?
} 3 J1 P- i" c; v: q, \ 1 Y, y" L, q6 b9 |& x9 \ tmp = (char*) MEM_ROUND_UP(pPool); & H1 O- S+ ^7 e6 _ reducePool = tmp - pPool;$ ]8 ~& ~9 A, t: \2 j$ n5 x
% ?& F$ T( J0 G: O! B
/* adjust the lenght */ ) @; Z0 r9 v. o. I4 {$ {% J/ U if(poolSize >= reducePool) 7 q% J/ y- W( w7 N { {8 k, t1 K8 j) k" S; n4 k! {. R
poolSize -= reducePool;4 n2 {, v- j- ~$ ~' C
}7 r' Y/ `; Z# |) c, @3 T) d# Y
else% {) k: s. ]5 K" h: o
{" H" @8 G& E% A% t- N
poolSize = 0;3 l; \6 I* [; j( v: j# q. z
}) I! N4 [$ g _( C7 |* c
pPool = tmp;9 J! @1 Q- J0 Q' N4 C# B
2 J$ q9 l' t! y! z5 K4 r
poolSize = MEM_ROUND_DOWN(poolSize); $ A6 d1 ~0 {' I( I& z 2 |+ U) G1 l2 k' b* @( k /* at least one valid free block and three header blocks */# F2 \! E- d, t+ x, V
if((sizeof(BLOCK_HDR)*3 + (partId->minBlockWords*2)) > poolSize)0 p4 W3 K6 L7 i) F" a5 W2 e/ j, Z
{& k2 L5 A: k3 Z
return (ERROR);- h" W: V/ Q1 |8 [$ E( G5 t8 I
} * G* B1 O' J' ~. z- s5 h M; j" r9 D5 u A# o9 O" L
/* initialize three blocks */# y4 U; w }. w# s
pHdrStart = (BLOCK_HDR*)pPool;/ T9 A; t: x8 q; E5 h: w
pHdrStart->prevHdr = NULL;9 N3 a" b* ?6 I+ e; e/ l8 K
pHdrStart->free = FALSE; /* never in use */ + D' v1 C6 ~, e9 e' ]! L pHdrStart->nWords = sizeof(BLOCK_HDR) >> 1;* ^; q# I4 X3 m" L8 |0 E. B
* R) A( J" v) s( ~8 p pHdrMid = NEXT_HDR(pHdrStart); # q# t8 a: i; i. j6 b pHdrMid->prevHdr = pHdrStart;; C; ~# Q$ W* O/ n0 |: ^
pHdrMid->free = TRUE; /* the main block */ - i1 G! I) y6 p) S! c pHdrMid->nWords = (poolSize - 2*sizeof(BLOCK_HDR)) >> 1;. o$ L! X: o* ?, t3 _5 M
. f' D1 F+ e, f N" [3 o pHdrEnd = NEXT_HDR(pHdrMid);9 }8 B, w6 L5 m
pHdrEnd->prevHdr = pHdrMid;. [5 S7 a5 ^1 ^& f1 A6 n" ^' ?$ P# c
pHdrEnd->free = FALSE;. U* a0 _0 l( ~, A" U
pHdrEnd->nWords = sizeof (BLOCK_HDR) >> 1;0 n* E3 F u0 W9 }5 k! P
7 s7 L8 R( z+ S; x1 v( b
/* TODO take sem hear */2 e) q5 \2 p( o. ^& Y/ @1 M
semTake(partId->semPartId, WAIT_FOREVER); 8 e& H; l4 J% C1 }' U 1 A; T4 ^- M5 \+ e
dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdrMid));" V/ Q( U8 q1 R* a6 K: |
partId->totalWords += (poolSize >> 1); # F2 _. `) o2 c; A `& ^7 F, Z6 j( Q% z
/* TODO give sem hear */ B/ o% T: b; ~0 g# w f Q: b- }: L semGive(partId->semPartId); ) V; [& p; y+ r 5 X( v- x( D6 J9 E8 Q- M - m g* z7 `' a/ ?' W. ?1 @$ D return (OK);% Q% B& a' W- x3 g, f l
} / g6 g- f# ]* C. I% u, [ 2 s+ z7 a- A6 {3 a+ K% S5 Avoid* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)* X* {0 o. n, m. E
{ 0 D! A( s" R; Z5 L3 n9 j FAST unsigned nWords; 3 S7 B. |$ j% U3 S! c* o( V FAST unsigned nWordsExtra;/ X4 q) L$ p9 _& i* V( x3 J9 a U0 P9 I
FAST DL_NODE* pNode;' }: O: O/ r: h4 }4 k2 A; k
FAST BLOCK_HDR* pHdr;" ^ T: O0 p5 f& ~/ g
BLOCK_HDR* pNewHdr;# `+ K$ m# L5 O; O; x6 A
BLOCK_HDR* origpHdr; 6 \7 M N. F% p" w( B ; p- _6 p9 H/ m7 A2 d1 G if(!(IS_CLASS(partId, memPartClassId))) /* only memPartClass can call this function */ 6 V e; i9 Q7 O; Y7 t; o/ v {& Y3 z5 s5 p) p; s& m+ m; s9 O
return (NULL);' |3 x/ U; Q% ^- w9 l. ^- A" Z0 w( T
} ( v9 Z" r9 `9 `, ?3 a " k+ [+ r1 k4 q! {. `* P2 m nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;! q! O6 s+ e( k+ h0 J
, x8 U9 ?" Z: i; {. |2 F+ [, { if((nWords<<1) < nBytes)" t; m" o I5 k8 d8 w
{5 I$ r! T# L u, d9 ^
/* TODO suspend the task */5 @# e" W. d) t. ]. @, K) b0 V: p
return (NULL);, o" c( `* `- s
} % x" ?5 J3 X: j' H1 w8 K8 Z , \2 |' ^+ J B* H- S# x, Q if(nWords < partId->minBlockWords) * J' ]5 p! O% e* r: V8 k* [6 z) _ { @6 x7 k/ ?+ f8 y2 q5 B nWords = partId->minBlockWords; 8 b) t: j e; j$ \ }# Y2 S# O7 ?9 V' H+ i& ^2 l, ]
2 v& H8 F* }- o( Q, E
/* TODO task the semaphore hear */ " X' Y! O; p# R% H- W( o semTake(partId->semPartId, WAIT_FOREVER); 0 b1 Q/ ^) m" U pNode = DLL_FIRST(&partId->freeList);4 L8 c* S: g% i4 n+ U. r; m& w
nWordsExtra = nWords + align/2; /* why? */7 [/ x: o9 Y0 O3 P) @/ M" `& G" W* q
/ \' t7 C5 C% ?5 v, L4 X. d
for(;;)/ C$ {1 d- @. [7 _6 e
{' i/ B& l' h9 S/ L X
while(NULL != pNode)5 B0 {9 G; l0 A% A; \1 [' _
{ " u {) v& v& d+ Y if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) || ) y$ G7 V; Y) o7 R2 I ((NODE_TO_HDR(pNode)->nWords == nWords) && 5 A" n c! ~" I+ F0 R
(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align)))) - S8 i0 W2 C% T N, g* r: C {6 Z5 B) b$ e1 c( \4 L
break; : y3 M$ ~+ I/ C: D }# r$ i6 m+ P) ^4 r. w/ ?
6 V% }6 h' P3 U( @5 C+ z
pNode = DLL_NEXT(pNode); " r$ u8 h Q1 b/ e; I& [2 r3 q } . T# \ {0 o# W0 _6 U. t+ h; A' j# d0 U( m; E1 g" H
if(NULL == pNode) u" N7 d6 H# ]- [7 R/ C
{ 8 D Y7 N$ a8 T+ W /*TODO give the semaphore */: E, g6 W U7 b0 E' @
semGive(partId->semPartId); ! d. g" R. h R0 E% I2 F return NULL;, s5 Y2 s' s- o# t* Z
}! `4 `% S4 c0 K! H$ |
# o9 Q: v# C( Z) F/ u pHdr = NODE_TO_HDR(pNode);8 W) _2 R) L" V: z5 w
origpHdr = pHdr;/ i! e( w" a2 c" R2 \& d
$ J1 p7 K. Y: E# o* V
pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);' ~& {+ P: d# x
if(NULL != pNewHdr)9 W5 R- P( }2 |" t0 o- g* v3 A4 [6 x
{0 N1 ^7 [6 K3 X: d, Y1 k/ X$ H( C
pHdr = pNewHdr;2 G6 B4 x( o9 t8 a+ Y- C3 t, f
break; $ O0 S" d! @& B" e }& {8 j1 n; u% u6 a. `( ]1 R
9 E' e- q% u/ w- B: B- x! a pNode = DLL_NEXT(pNode); 9 v, B* A" ~) r8 t9 x }+ I! l' I/ g' u
5 z/ j1 v% R4 M+ Y. k: }
pHdr->free = FALSE;0 n5 ~' n) g$ o+ O4 C% X
partId->allBlocksAlloc++; . ]) `* y% e1 o% O: ~$ l# o partId->allWordsAlloc += pHdr->nWords; Y' u- C" W" ?7 x
partId->curBlocksAlloc++; & Y& l) U) R f2 b2 n2 i6 N partId->curWordsAlloc += pHdr->nWords;3 y4 w, S8 N! M3 L& {
* ~# i* S5 o' y9 I" Q; | /*TODO give the semaphore hear */( A: S4 a# K6 a# f
semGive(partId->semPartId);% i m& g @7 `0 a1 p i) U: S7 v
return (HDR_TO_BLOCK(pHdr));% A7 ^- d2 j% A& r3 l
9 z$ f9 |* O9 z" \9 Uvoid* memPartAlloc(FAST PART_ID partId, unsigned bytes)- K, \5 q, W4 Q: }5 N: ^
{ U4 C5 I1 \! i
return memPartAllignedAlloc(partId, bytes, memDefaultAlign); , u: x b" f3 M} 6 y8 h) H- H4 [9 b& j. t2 p: e$ g! J. c' Z J8 J( d. k, T* F
STATUS memPartFree(PART_ID partId, char* pBlock)- C/ C0 c# D/ l8 o( }6 K8 J% u" R
{ . d' a9 d2 P: o j" ^4 i FAST BLOCK_HDR *pHdr; * b, y- \ l0 U! ?* f. v FAST unsigned nWords;+ ?" H4 h2 M, u1 i
FAST BLOCK_HDR *pNextHdr; & a+ d. @. B8 N+ y; W' o4 `8 d h8 J! E. I: s( o% Z
if(!IS_CLASS(partId, memPartClassId))9 d0 |: c0 l" ~1 n
{! ^# f( D7 l$ [4 V- H& Z) P
return (ERROR); 5 @0 h0 M( s4 y% h4 x& l- n* L }. l# S. O4 i6 H
' d$ [. r! D, Z+ Y2 h$ C3 @( ?
if(NULL == pBlock)/ v L" `7 ^% L
{1 Q( u4 I( G" J
return (OK); 8 p+ C$ d5 v3 b5 H& z9 `; G# J } 7 x$ K' v& \! |* d% Q. }; n- b: g# {: N7 ]0 k8 k
pHdr = BLOCK_TO_HDR(pBlock); " @3 V# a( c+ A, D* c, z$ j$ ]" j0 t# T+ [
semTake(partId->semPartId, WAIT_FOREVER); ' R2 u2 R9 b& r: _$ f g* U , g* R# r! J9 N% i. r4 ~( l& r4 ^ if((partId->options & MEM_BLOCK_CHECK)2 {* T1 f$ }; O* i$ P* W0 D1 ^: P M
&& !memPartBlockIsValid(partId, pHdr, FALSE))* ~+ ]7 ?/ D% b% D) @- V
{: V& g' w! |2 S! Z( m$ Z: o
semGive(partId->semPartId); - f t$ e) \7 _: R return (ERROR);- [$ G- x4 I9 c/ T+ }
} e# U' p! L2 R2 g! l
4 o4 e q6 `1 W$ G2 F2 Z- e# ^ nWords = pHdr->nWords;* r/ L1 x5 P) O2 E. N! G( S) @5 O/ ^
if(PREV_HDR(pHdr)->free) - d- }8 r6 t5 V9 a% R) [* {) F) a {/* the prev hdr is free and than coalesce with it */, q7 z0 l& r* D0 |7 S
pHdr->free = FALSE;) l' z* [4 I! P2 [% T' Z8 r
pHdr = PREV_HDR(pHdr); + A* `( y, _( h4 P# _# V1 a pHdr->nWords += nWords; d S, O- i" q3 c l' E+ ^ } $ A0 t2 o# i. Z1 X( b R else6 q; L3 O& y0 `3 G
{ \$ D# h- ?) ]) v8 I* k2 V: m, [ pHdr->free = TRUE; . ^+ T2 c3 g) L) f dllInsert(&partId->freeList, (DL_NODE*)NULL, HDR_TO_NODE(pHdr)); q5 n! y8 _' T5 w) V6 s* v
} ( P7 y8 u" G4 `' m" [0 y0 B/ c: D$ p! d5 }& [% ~
/* check to coalesce with the next */$ L4 Q& @- ?/ ~) U$ s/ W
pNextHdr = NEXT_HDR(pHdr); ) R: p! B9 \$ n: A if(pNextHdr->free) $ Q; Z2 q7 f: e$ K {1 E) \8 o1 ]' O' y$ {
pHdr->nWords += pNextHdr->nWords; ' q0 J* p% \, y j, d# K dllRemove(&partId->freeList, HDR_TO_NODE(pNextHdr)); . |' q+ A: e6 n5 _ }# E( J: ~ r) E. t( a; N0 d
4 F* X. T8 a% Z7 D" {3 d /* cannot use pNextHdr->prevHdr=pHdr hear */ . r% U0 E2 R7 k& L* _2 O2 ^5 { NEXT_HDR(pHdr)->prevHdr = pHdr; 6 P/ q8 P8 N2 I1 a1 `4 Z$ t% {3 z0 Z% T
partId->curBlocksAlloc--;! W. S" k3 R/ u' u; r% }+ O8 ~
partId->curWordsAlloc -= nWords; 8 v/ T8 Y4 B2 {. S/ \6 E5 L, L* ~9 v! r& C
/* TODO give sem hear */ 9 Y; N$ f) Q9 B d; [" m semGive(partId->semPartId); $ g$ n/ ?0 J9 F! v4 z 2 M/ J/ v/ w3 y
return (OK); 7 Z. R7 D9 o1 S2 A, s}9 `, R, K0 n: t: j
& E' R" I! l) B. k
static BOOL memPartBlockIsValid(PART_ID partId, FAST BLOCK_HDR* pHdr, BOOL isFree) w, }, ]& U- C* Y7 ^3 p" e+ _0 E
{$ H. Z$ a2 q! z A4 F
BOOL valid;6 _; E' a" N- |4 R% U" @! [
. k5 F" T$ y u: Q TASK_LOCK();7 M' l/ T( A2 I) H2 b9 g7 S: P0 B
semGive(partId->semPartId); 4 K: o) u1 H8 F" W3 b/ p6 q 6 M8 e6 \4 i3 t, _
valid = MEM_ALIGNED(pHdr) 9 s$ t7 }: n# @ && MEM_ALIGNED(pHdr->nWords*2): }; f% B6 w# \4 [/ z
&& (pHdr->nWords < partId->totalWords) : d3 W" w8 j/ r' |" E ]$ [ && (pHdr->free == isFree) 6 Y; C6 i& [' e && (pHdr == PREV_HDR(NEXT_HDR(pHdr)))1 }% q. U; I) N. i
&& (pHdr == NEXT_HDR(PREV_HDR(pHdr))); 0 d3 Y! }+ k( r p d& G& l/ X Y8 N0 e8 Y& i semTake(partId->semPartId, WAIT_FOREVER);& h) `/ ]9 _9 n% C) b2 Q. p
TASK_UNLOCK();0 _5 e9 _+ Q( _7 Z7 L
: G4 j% |* L7 R- d
return valid; ) a6 D( z' F! `6 g# `% l}% ^" ]: i5 _- p, t3 f" h ~
+ M# w8 g8 Q6 y- Mstatic BLOCK_HDR* memAlignedBlockSplit(PART_ID partId0 s8 v& v/ S% \5 l6 S
, FAST BLOCK_HDR* pHdr ' j" |* M4 v4 [ C& g0 X , FAST unsigned nWords* K, `! o% C+ k- d
, unsigned minWords , C& ~4 R, x% O( r9 R8 H4 k+ ~0 B , unsigned align) ! K! g# [0 p% x- Z{ 7 p( c; C* {5 ~8 U( a& j, Z3 } FAST BLOCK_HDR *pNewHdr; % `/ ~! d0 U1 r) V( t6 l7 k" S. t1 [- G FAST BLOCK_HDR *pNextHdr;7 [- F& |( ^# C& K
FAST char *endOfBlock; 5 ]! X' S& |% l% T2 e0 k FAST char *pNewBlock; 8 C5 `! |4 U4 q$ ?# x int blockSize; / B. L/ J) u; E0 f7 v: R/ ?7 L( A# [& U% z2 \; _
endOfBlock = (char*)pHdr + (pHdr->nWords*2); : z! ~4 w5 r; @ V: X % ]" V h4 q/ ]& L9 m pNewBlock = (char*)((unsigned)endOfBlock - ((nWords - sizeof(BLOCK_HDR)/2)*2));0 Q& _1 x% F/ S" d/ w+ h) T
% N) s6 t- t; X& L- J2 N4 a
pNewBlock = (char*)((unsigned)pNewBlock & (~(align-1))); 3 k* n2 |+ a& j+ r8 h 9 Y) v/ y) x1 ~; B: k: ^ pNewHdr = BLOCK_TO_HDR(pNewBlock); 9 r7 @0 G" s) _3 `* M1 x : u. b+ u' ~( B8 b( X blockSize = ((char*)pNewHdr - (char*)pHdr)/2; ; x2 G) N4 H+ w6 H8 M4 {' @3 m2 T( ?
if(blockSize < minWords) $ Y1 _% G) a9 n. ?. w2 G { 8 E' o$ v7 R$ W$ F$ N* a if(pNewHdr == pHdr)/ |7 v. z: l1 n# ^% ~
{ # m, @9 p- U- d1 G/ G. }' ? dllRemove(&partId->freeList, HDR_TO_NODE(pHdr));+ O" V9 n) j/ W* g2 k9 s) X f
} + A' r T' w4 S else * ^$ u& j' T: f {6 g. u; a) p5 ?& u8 V
return NULL;; e p# a' J- \7 h* H: Y! C
}! @% R$ ~& S1 G% c
}$ z" R3 S/ |, J; J% Y
else ) w' o1 N" F, h { /* recaculate pHdr */3 b" n0 l/ y! T
pNewHdr->prevHdr = pHdr;: {* @6 r6 l7 L9 C
pHdr->nWords = blockSize; 1 h" x6 p2 j. g9 U! r7 k% S }) [8 [" d$ a/ ~3 V
, v7 O( }) `% d0 | if(((U32)endOfBlock - (U32)pNewHdr - (nWords*2)) < (minWords*2))8 F, A/ O" `. d. u- P" S
{ - O; H {: r- g7 }, T2 N pNewHdr->nWords = (endOfBlock - pNewBlock + sizeof(BLOCK_HDR))/2;" u) R2 M# k+ M
pNewHdr->free = TRUE;4 v: K" H |1 k. P
V D- W; h2 E c NEXT_HDR(pNewHdr)->prevHdr = pNewHdr; ! x' e x1 l4 T. U4 m' Q } - T: ~% C. Q- [, Y) k- h* M% } else ) Q7 n0 x, @! \7 ^* x {/* space left is enough to be a fragment on the free list then */3 o1 [0 W7 y* r; _7 t) \9 [, L
pNewHdr->nWords = nWords; " j. b/ q& v) e; Q1 K/ C' u0 _ pNewHdr->free = TRUE;, ^1 z* s; S2 W- m& ^: b7 T1 D
c! X; _) ~0 u Z' r3 s% W, I8 S; _/ V pNextHdr = NEXT_HDR(pNewHdr);" n+ O J" k- z6 z) U/ E
/* words 包括BlockHdr */ 5 o9 f- L/ a" N8 a( \" t pNextHdr->nWords = ((U32)endOfBlock - (U32)pNextHdr) / 2;& b6 s% _5 ]4 E
pNextHdr->prevHdr = pNewHdr;+ z$ R c+ ^/ Q) ?
pNextHdr->free = TRUE; 3 a1 O* h1 [3 N% @& G: z & R0 t8 \# h# l5 y dllAdd(&partId->freeList, HDR_TO_NODE(pNextHdr)); 3 M6 S! s( d$ l! s* B# q& f( z/ [' V2 A$ M$ g
NEXT_HDR(pNextHdr)->prevHdr = pNewHdr;' N) B" x& u; q5 S# _3 D, j8 Z8 @9 ^
} ; U5 Y( x6 m h* m8 g( V0 N6 ]) e `8 }! q4 P6 F& z
return (pNewHdr); ; X) B$ A& }/ V9 n, o; F4 y; O; m} . s2 y" P0 [8 c% Y& ~9 i 3 i. M* Q! c8 Q; Ostatic void memPartSemInit(PART_ID partId) * W8 J9 x( x0 v! [{ ; W [( |4 S- ` z5 F1 i7 K semBInit(&semMemSysPartition, SEM_Q_FIFO, SEM_FULL); C+ P2 R, [; h' c- f
D Q7 c K) ^9 y partId->semPartId = &semMemSysPartition; ) v5 o" ~* B9 m" u}0 i$ V$ d; M. ]