|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\misc\t_svr6.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #define __E32TEST_EXTENSION__ |
|
19 #include <e32base.h> |
|
20 #include <e32base_private.h> |
|
21 #include <e32test.h> |
|
22 #include <e32svr.h> |
|
23 #include "u32std.h" |
|
24 #include "../misc/prbs.h" |
|
25 #include "../mmu/freeram.h" |
|
26 |
|
27 const TInt KStackSize=0x1000; |
|
28 const TInt KHeapMaxSize=0x100000; |
|
29 const TInt KMajorVersionNumber=1; |
|
30 const TInt KMinorVersionNumber=0; |
|
31 const TInt KBuildVersionNumber=1; |
|
32 const TInt KNumMessageSlots=10; |
|
33 |
|
34 _LIT(KServerName,"StressSvr"); |
|
35 |
|
36 LOCAL_D RTest test(_L("T_SVR6")); |
|
37 |
|
38 class CMySession : public CSession2 |
|
39 { |
|
40 public: |
|
41 CMySession(); |
|
42 virtual void ServiceL(const RMessage2& aMessage); //pure virtual fns. |
|
43 void Process(const RMessage2& aMessage); |
|
44 public: |
|
45 TInt iOutstanding; |
|
46 TUint iSeed[2]; |
|
47 }; |
|
48 |
|
49 class CMyServer : public CServer2 |
|
50 { |
|
51 public: |
|
52 enum {ETest}; |
|
53 public: |
|
54 CMyServer(TInt aPriority); |
|
55 static CMyServer* New(TInt aPriority); |
|
56 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2&) const;//Overloading |
|
57 }; |
|
58 |
|
59 class CMyActiveScheduler : public CActiveScheduler |
|
60 { |
|
61 public: |
|
62 virtual void Error(TInt anError) const; //Overloading pure virtual function |
|
63 }; |
|
64 |
|
65 class RStressSvr : public RSessionBase |
|
66 { |
|
67 public: |
|
68 TInt Connect(); |
|
69 TInt Test(); |
|
70 void Test(TRequestStatus& aStatus); |
|
71 TVersion Version(); |
|
72 }; |
|
73 |
|
74 class CThread : public CActive |
|
75 { |
|
76 public: |
|
77 CThread(TInt aPriority); |
|
78 ~CThread(); |
|
79 virtual void RunL(); |
|
80 virtual void DoCancel(); |
|
81 virtual void DisplayStats()=0; |
|
82 virtual TBool PanicBadHandleAllowed(); |
|
83 virtual void RegisterAllowedPanic(); |
|
84 virtual void Cleanup(); |
|
85 virtual TInt ProcessStartError(TInt anError); |
|
86 TInt Start(); |
|
87 public: |
|
88 virtual TInt StartThread()=0; |
|
89 public: |
|
90 RThread iThread; |
|
91 TInt iExitCount; |
|
92 TInt iServerTerminatedCount; |
|
93 TInt iTerminateCount; |
|
94 }; |
|
95 |
|
96 class CServerThread : public CThread |
|
97 { |
|
98 public: |
|
99 static void NewL(); |
|
100 CServerThread(); |
|
101 virtual TInt StartThread(); |
|
102 virtual void DisplayStats(); |
|
103 public: |
|
104 TInt iMessagesReceived; |
|
105 }; |
|
106 |
|
107 class CClientThread : public CThread |
|
108 { |
|
109 public: |
|
110 static void NewL(TInt anId, TInt aPrimaryId); |
|
111 CClientThread(TInt anId); |
|
112 virtual TInt StartThread(); |
|
113 virtual void DisplayStats(); |
|
114 virtual TBool PanicBadHandleAllowed(); |
|
115 virtual void RegisterAllowedPanic(); |
|
116 virtual void Cleanup(); |
|
117 virtual TInt ProcessStartError(TInt anError); |
|
118 public: |
|
119 TInt iId; |
|
120 TInt iCloses; |
|
121 CClientThread* iPrimary; |
|
122 RStressSvr iSession; |
|
123 TBool iConnected; |
|
124 TBool iWaitingToRestart; |
|
125 }; |
|
126 |
|
127 class CRandomTimer : public CActive |
|
128 { |
|
129 public: |
|
130 static void NewL(); |
|
131 CRandomTimer(TInt aPriority); |
|
132 ~CRandomTimer(); |
|
133 virtual void RunL(); |
|
134 virtual void DoCancel(); |
|
135 void Start(); |
|
136 public: |
|
137 RTimer iTimer; |
|
138 TUint iSeed[2]; |
|
139 TInt iCount; |
|
140 }; |
|
141 |
|
142 class CStatsTimer : public CActive |
|
143 { |
|
144 public: |
|
145 static void NewL(); |
|
146 CStatsTimer(TInt aPriority); |
|
147 ~CStatsTimer(); |
|
148 virtual void RunL(); |
|
149 virtual void DoCancel(); |
|
150 void Start(); |
|
151 public: |
|
152 RTimer iTimer; |
|
153 TInt iInitFreeRam; |
|
154 TInt iMaxDelta; |
|
155 TInt iCount; |
|
156 }; |
|
157 |
|
158 const TInt KNumPrimaryClients=3; |
|
159 const TInt KNumSecondariesPerPrimary=3; |
|
160 const TInt KNumClients=KNumPrimaryClients*KNumSecondariesPerPrimary; |
|
161 LOCAL_D CServerThread* TheServer; |
|
162 LOCAL_D CClientThread* TheClients[KNumClients]; |
|
163 LOCAL_D CRandomTimer* TheRandomTimer; |
|
164 |
|
165 CMySession::CMySession() |
|
166 // |
|
167 // Constructor |
|
168 // |
|
169 { |
|
170 iSeed[0]=User::TickCount(); |
|
171 } |
|
172 |
|
173 CMyServer* CMyServer::New(TInt aPriority) |
|
174 // |
|
175 // Create a new CMyServer. |
|
176 // |
|
177 { |
|
178 |
|
179 return new CMyServer(aPriority); |
|
180 } |
|
181 |
|
182 CMyServer::CMyServer(TInt aPriority) |
|
183 // |
|
184 // Constructor. |
|
185 // |
|
186 : CServer2(aPriority, ESharableSessions) |
|
187 {} |
|
188 |
|
189 CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const |
|
190 // |
|
191 // Create a new client for this server. |
|
192 // |
|
193 { |
|
194 |
|
195 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
196 if (!User::QueryVersionSupported(v,aVersion)) |
|
197 User::Leave(KErrNotSupported); |
|
198 return new(ELeave) CMySession; |
|
199 } |
|
200 |
|
201 void CMySession::ServiceL(const RMessage2& aMessage) |
|
202 // |
|
203 // Handle messages for this server. |
|
204 // |
|
205 { |
|
206 |
|
207 ++TheServer->iMessagesReceived; |
|
208 switch (aMessage.Function()) |
|
209 { |
|
210 case CMyServer::ETest: |
|
211 if (iOutstanding==KNumMessageSlots-1) |
|
212 Process(aMessage); |
|
213 else |
|
214 ++iOutstanding; |
|
215 break; |
|
216 default: |
|
217 aMessage.Complete(KErrNotSupported); |
|
218 break; |
|
219 } |
|
220 } |
|
221 |
|
222 void CMySession::Process(const RMessage2& aMessage) |
|
223 { |
|
224 TUint x=Random(iSeed)&16383; |
|
225 if (x==0) |
|
226 User::Exit(0); // exit the server |
|
227 else if (x<8) |
|
228 aMessage.Terminate(0); // terminate the client |
|
229 else |
|
230 aMessage.Complete(KErrNone); |
|
231 } |
|
232 |
|
233 void CMyActiveScheduler::Error(TInt anError) const |
|
234 // |
|
235 // Called if any Run() method leaves. |
|
236 // |
|
237 { |
|
238 |
|
239 User::Panic(_L("Server Error"),anError); |
|
240 } |
|
241 |
|
242 TInt RStressSvr::Connect() |
|
243 // |
|
244 // Connect to the server |
|
245 // |
|
246 { |
|
247 |
|
248 TInt r=CreateSession(KServerName,Version(),KNumMessageSlots); |
|
249 if (r==KErrNone) |
|
250 r=ShareAuto(); |
|
251 return r; |
|
252 } |
|
253 |
|
254 TInt RStressSvr::Test() |
|
255 // |
|
256 // Send a message and wait for completion. |
|
257 // |
|
258 { |
|
259 |
|
260 return SendReceive(CMyServer::ETest); |
|
261 } |
|
262 |
|
263 void RStressSvr::Test(TRequestStatus& aStatus) |
|
264 // |
|
265 // Send a message asynchronously |
|
266 // |
|
267 { |
|
268 |
|
269 SendReceive(CMyServer::ETest,aStatus); |
|
270 } |
|
271 |
|
272 TVersion RStressSvr::Version() |
|
273 // |
|
274 // Return the current version. |
|
275 // |
|
276 { |
|
277 |
|
278 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
279 return(v); |
|
280 } |
|
281 |
|
282 LOCAL_C TInt ServerThread(TAny*) |
|
283 { |
|
284 |
|
285 CMyActiveScheduler* pR=new CMyActiveScheduler; |
|
286 if (!pR) |
|
287 return KErrNoMemory; |
|
288 CActiveScheduler::Install(pR); |
|
289 CMyServer* pS=CMyServer::New(0); |
|
290 if (!pS) |
|
291 return KErrNoMemory; |
|
292 TInt r=pS->Start(KServerName); |
|
293 if (r!=KErrNone) |
|
294 return r; |
|
295 |
|
296 CActiveScheduler::Start(); |
|
297 |
|
298 delete pS; |
|
299 delete pR; |
|
300 return KErrNone; |
|
301 } |
|
302 |
|
303 LOCAL_C TInt ClientThread(TAny* aPtr) |
|
304 { |
|
305 CClientThread* pT=(CClientThread*)aPtr; |
|
306 CClientThread* pP=pT->iPrimary; |
|
307 TBool primary=(pP==pT); |
|
308 RStressSvr& d=pP->iSession; |
|
309 TUint seed[2]; |
|
310 seed[0]=User::TickCount(); |
|
311 seed[1]=0; |
|
312 TInt r=KErrNone; |
|
313 TInt i; |
|
314 if (primary) |
|
315 { |
|
316 FOREVER |
|
317 { |
|
318 FOREVER |
|
319 { |
|
320 r=d.Connect(); |
|
321 if (r!=KErrNotFound) |
|
322 break; |
|
323 User::After(50000); |
|
324 } |
|
325 if (r!=KErrNone) |
|
326 return r; |
|
327 pT->iConnected=ETrue; |
|
328 TRequestStatus s[KNumMessageSlots]; |
|
329 for (i=0; i<KNumMessageSlots-1; i++) |
|
330 d.Test(s[i]); |
|
331 TInt n=Random(seed)&16383; |
|
332 for (i=0; i<n && r==KErrNone; i++) |
|
333 r=d.Test(); |
|
334 pT->iConnected=EFalse; |
|
335 d.Close(); |
|
336 ++pT->iCloses; |
|
337 } |
|
338 } |
|
339 else |
|
340 { |
|
341 TRequestStatus s[KNumMessageSlots]; |
|
342 for (i=0; i<KNumMessageSlots-1; i++) |
|
343 d.Test(s[i]); |
|
344 FOREVER |
|
345 { |
|
346 if (pP->iConnected) |
|
347 { |
|
348 RStressSvr dd; |
|
349 dd.SetHandle(pP->iSession.Handle()); |
|
350 TInt n=Random(seed)&16383; |
|
351 for (i=0; i<n && r==KErrNone; i++) |
|
352 r=dd.Test(); |
|
353 } |
|
354 TInt ms=(Random(seed)&7)+1; |
|
355 User::AfterHighRes(ms*1000); |
|
356 } |
|
357 } |
|
358 } |
|
359 |
|
360 CThread::CThread(TInt aPriority) |
|
361 : CActive(aPriority) |
|
362 { |
|
363 } |
|
364 |
|
365 CThread::~CThread() |
|
366 { |
|
367 Cancel(); |
|
368 iThread.Kill(0); |
|
369 iThread.Close(); |
|
370 } |
|
371 |
|
372 _LIT(KLitKernExec,"KERN-EXEC"); |
|
373 void CThread::RunL() |
|
374 { |
|
375 TExitType exitType=iThread.ExitType(); |
|
376 TInt exitReason=iThread.ExitReason(); |
|
377 TBuf<32> exitCat=iThread.ExitCategory(); |
|
378 TBool bad=EFalse; |
|
379 if (exitType==EExitKill) |
|
380 { |
|
381 if (exitReason!=KErrNone && exitReason!=KErrServerTerminated) |
|
382 bad=ETrue; |
|
383 } |
|
384 else if (exitType==EExitPanic) |
|
385 { |
|
386 if (!PanicBadHandleAllowed() || exitCat!=KLitKernExec || exitReason!=EBadHandle) |
|
387 bad=ETrue; |
|
388 else |
|
389 RegisterAllowedPanic(); |
|
390 } |
|
391 if (bad) |
|
392 { |
|
393 TFullName n(iThread.FullName()); |
|
394 test.Printf(_L("Thread %S exited %d,%d,%S\n"),&n,exitType,exitReason,&exitCat); |
|
395 CActiveScheduler::Stop(); |
|
396 return; |
|
397 } |
|
398 Cleanup(); |
|
399 iThread.Close(); |
|
400 if (exitType==EExitTerminate) |
|
401 ++iTerminateCount; |
|
402 else if (exitType==EExitKill && exitReason==KErrNone) |
|
403 ++iExitCount; |
|
404 else if (exitReason==KErrServerTerminated) |
|
405 ++iServerTerminatedCount; |
|
406 TInt r=Start(); |
|
407 if (r!=KErrNone) |
|
408 { |
|
409 test.Printf(_L("Start thread error %d\n"),r); |
|
410 CActiveScheduler::Stop(); |
|
411 } |
|
412 } |
|
413 |
|
414 void CThread::DoCancel() |
|
415 { |
|
416 iThread.LogonCancel(iStatus); |
|
417 } |
|
418 |
|
419 const TInt KThreadStartAttempts=3; |
|
420 TInt CThread::Start() |
|
421 { |
|
422 TInt r=KErrNone; |
|
423 TInt n=KThreadStartAttempts; |
|
424 while(n--) |
|
425 { |
|
426 r=StartThread(); |
|
427 if (r==KErrNone) |
|
428 break; |
|
429 if (r!=KErrAlreadyExists) |
|
430 break; |
|
431 User::After(100000); |
|
432 } |
|
433 if (r==KErrNone) |
|
434 { |
|
435 iThread.Logon(iStatus); |
|
436 SetActive(); |
|
437 } |
|
438 return ProcessStartError(r); |
|
439 } |
|
440 |
|
441 TBool CThread::PanicBadHandleAllowed() |
|
442 { |
|
443 return EFalse; |
|
444 } |
|
445 |
|
446 void CThread::RegisterAllowedPanic() |
|
447 { |
|
448 } |
|
449 |
|
450 void CThread::Cleanup() |
|
451 { |
|
452 } |
|
453 |
|
454 TInt CThread::ProcessStartError(TInt anError) |
|
455 { |
|
456 return anError; |
|
457 } |
|
458 |
|
459 CServerThread::CServerThread() |
|
460 : CThread(0) |
|
461 { |
|
462 } |
|
463 |
|
464 TInt CServerThread::StartThread() |
|
465 { |
|
466 TUint seed[2]; |
|
467 seed[1]=0; |
|
468 seed[0]=User::TickCount(); |
|
469 TInt heapMin=TInt(Random(seed)&0x0f)+1; |
|
470 heapMin<<=12; |
|
471 TInt r=iThread.Create(KNullDesC(),ServerThread,KStackSize,heapMin,KHeapMaxSize,this); // use unnamed thread |
|
472 if (r!=KErrNone) |
|
473 return r; |
|
474 iThread.Resume(); |
|
475 return KErrNone; |
|
476 } |
|
477 |
|
478 void CServerThread::NewL() |
|
479 { |
|
480 CServerThread* pT=new (ELeave) CServerThread; |
|
481 TheServer=pT; |
|
482 CActiveScheduler::Add(pT); |
|
483 User::LeaveIfError(pT->Start()); |
|
484 } |
|
485 |
|
486 void CServerThread::DisplayStats() |
|
487 { |
|
488 test.Printf(_L("Svr : X:%9d ST:%9d T:%9d RX:%9d\n"),iExitCount,iServerTerminatedCount,iTerminateCount,iMessagesReceived); |
|
489 } |
|
490 |
|
491 CClientThread::CClientThread(TInt anId) |
|
492 : CThread(0), iId(anId) |
|
493 { |
|
494 } |
|
495 |
|
496 TInt CClientThread::StartThread() |
|
497 { |
|
498 TInt r=iThread.Create(KNullDesC(),ClientThread,KStackSize,NULL,this); // use unnamed threads |
|
499 if (r!=KErrNone) |
|
500 return r; |
|
501 iSession.SetHandle(0); |
|
502 iThread.Resume(); |
|
503 return KErrNone; |
|
504 } |
|
505 |
|
506 void CClientThread::NewL(TInt anId, TInt aPrimaryId) |
|
507 { |
|
508 CClientThread* pT=new (ELeave) CClientThread(anId); |
|
509 TheClients[anId]=pT; |
|
510 pT->iPrimary=TheClients[aPrimaryId]; |
|
511 CActiveScheduler::Add(pT); |
|
512 User::LeaveIfError(pT->Start()); |
|
513 } |
|
514 |
|
515 void CClientThread::DisplayStats() |
|
516 { |
|
517 test.Printf(_L("Cli %1d: X:%9d ST:%9d T:%9d CL:%9d\n"),iId,iExitCount,iServerTerminatedCount,iTerminateCount,iCloses); |
|
518 } |
|
519 |
|
520 TBool CClientThread::PanicBadHandleAllowed() |
|
521 { |
|
522 return (iPrimary!=this); |
|
523 } |
|
524 |
|
525 void CClientThread::RegisterAllowedPanic() |
|
526 { |
|
527 ++iCloses; |
|
528 } |
|
529 |
|
530 void CClientThread::Cleanup() |
|
531 { |
|
532 TInt r=KErrNone; |
|
533 if (iPrimary==this) |
|
534 { |
|
535 if (!IsLocalHandle(iSession.Handle())) // don't close if not shared yet |
|
536 iSession.Close(); |
|
537 CClientThread* pS1=TheClients[iId+1]; |
|
538 CClientThread* pS2=TheClients[iId+2]; |
|
539 if (pS1->iWaitingToRestart) |
|
540 r=pS1->Start(); |
|
541 if (r==KErrNone && pS2->iWaitingToRestart) |
|
542 r=pS2->Start(); |
|
543 if (r!=KErrNone) |
|
544 { |
|
545 test.Printf(_L("Start thread error %d\n"),r); |
|
546 CActiveScheduler::Stop(); |
|
547 } |
|
548 } |
|
549 } |
|
550 |
|
551 TInt CClientThread::ProcessStartError(TInt anError) |
|
552 { |
|
553 if (anError==KErrAlreadyExists && iPrimary!=this && !iWaitingToRestart) |
|
554 { |
|
555 iWaitingToRestart=ETrue; |
|
556 return KErrNone; |
|
557 } |
|
558 iWaitingToRestart=EFalse; |
|
559 return anError; |
|
560 } |
|
561 |
|
562 void CRandomTimer::NewL() |
|
563 { |
|
564 CRandomTimer* pR=new (ELeave) CRandomTimer(20); |
|
565 User::LeaveIfError(pR->iTimer.CreateLocal()); |
|
566 CActiveScheduler::Add(pR); |
|
567 TheRandomTimer=pR; |
|
568 pR->Start(); |
|
569 } |
|
570 |
|
571 CRandomTimer::CRandomTimer(TInt aPriority) |
|
572 : CActive(aPriority) |
|
573 { |
|
574 iSeed[0]=User::TickCount(); |
|
575 } |
|
576 |
|
577 CRandomTimer::~CRandomTimer() |
|
578 { |
|
579 Cancel(); |
|
580 iTimer.Close(); |
|
581 } |
|
582 |
|
583 void CRandomTimer::RunL() |
|
584 { |
|
585 ++iCount; |
|
586 TUint x=Random(iSeed)&15; |
|
587 CThread* pT=NULL; |
|
588 if (x==0) |
|
589 pT=TheServer; |
|
590 else if (x<10) |
|
591 { |
|
592 pT=TheClients[x-1]; |
|
593 if (((CClientThread*)pT)->iWaitingToRestart) |
|
594 pT=NULL; |
|
595 } |
|
596 if (pT) |
|
597 pT->iThread.Kill(0); |
|
598 Start(); |
|
599 } |
|
600 |
|
601 void CRandomTimer::Start() |
|
602 { |
|
603 TUint x=Random(iSeed)&63; |
|
604 x+=64; |
|
605 iTimer.HighRes(iStatus, x*1000); |
|
606 SetActive(); |
|
607 } |
|
608 |
|
609 void CRandomTimer::DoCancel() |
|
610 { |
|
611 iTimer.Cancel(); |
|
612 } |
|
613 |
|
614 void CStatsTimer::NewL() |
|
615 { |
|
616 CStatsTimer* pT=new (ELeave) CStatsTimer(-10); |
|
617 User::LeaveIfError(pT->iTimer.CreateLocal()); |
|
618 CActiveScheduler::Add(pT); |
|
619 pT->Start(); |
|
620 } |
|
621 |
|
622 CStatsTimer::CStatsTimer(TInt aPriority) |
|
623 : CActive(aPriority) |
|
624 { |
|
625 iInitFreeRam = FreeRam(); |
|
626 } |
|
627 |
|
628 CStatsTimer::~CStatsTimer() |
|
629 { |
|
630 Cancel(); |
|
631 iTimer.Close(); |
|
632 } |
|
633 |
|
634 void CStatsTimer::RunL() |
|
635 { |
|
636 TheServer->DisplayStats(); |
|
637 TInt i; |
|
638 for (i=0; i<KNumClients; i++) |
|
639 TheClients[i]->DisplayStats(); |
|
640 test.Printf(_L("RndTm: %9d\n"),TheRandomTimer->iCount); |
|
641 TInt free_ram = FreeRam(); |
|
642 TInt delta_ram = iInitFreeRam - free_ram; |
|
643 if (delta_ram > iMaxDelta) |
|
644 iMaxDelta = delta_ram; |
|
645 if (++iCount==10) |
|
646 { |
|
647 test.Printf(_L("Max RAM delta %dK Free RAM %08x\n"), iMaxDelta/1024, free_ram); |
|
648 iCount=0; |
|
649 } |
|
650 Start(); |
|
651 } |
|
652 |
|
653 void CStatsTimer::Start() |
|
654 { |
|
655 iTimer.After(iStatus, 1000000); |
|
656 SetActive(); |
|
657 } |
|
658 |
|
659 void CStatsTimer::DoCancel() |
|
660 { |
|
661 iTimer.Cancel(); |
|
662 } |
|
663 |
|
664 void InitialiseL() |
|
665 { |
|
666 CActiveScheduler* pA=new (ELeave) CActiveScheduler; |
|
667 CActiveScheduler::Install(pA); |
|
668 CServerThread::NewL(); |
|
669 TInt p; |
|
670 TInt s; |
|
671 TInt id=0; |
|
672 for (p=0; p<KNumClients; p+=KNumSecondariesPerPrimary) |
|
673 { |
|
674 for (s=0; s<KNumSecondariesPerPrimary; s++) |
|
675 { |
|
676 CClientThread::NewL(id,p); |
|
677 id++; |
|
678 } |
|
679 } |
|
680 CRandomTimer::NewL(); |
|
681 CStatsTimer::NewL(); |
|
682 } |
|
683 |
|
684 GLDEF_C TInt E32Main() |
|
685 // |
|
686 // Test timers. |
|
687 // |
|
688 { |
|
689 |
|
690 test.Title(); |
|
691 |
|
692 User::SetCritical(User::ESystemCritical); |
|
693 RThread().SetPriority(EPriorityMore); |
|
694 User::SetJustInTime(EFalse); // prevent the debugger picking up expected thread panics. |
|
695 |
|
696 TRAPD(r,InitialiseL()); |
|
697 test(r==KErrNone); |
|
698 |
|
699 CActiveScheduler::Start(); |
|
700 |
|
701 test(0); |
|
702 |
|
703 return(0); |
|
704 } |
|
705 |
|
706 // Override heap creation for this process |
|
707 // This function runs at the beginning of every thread |
|
708 // Initial heap is shared but subsequent heaps are single threaded |
|
709 TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo) |
|
710 { |
|
711 TInt r = KErrNone; |
|
712 if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0) |
|
713 { |
|
714 // new heap required |
|
715 RHeap* pH = NULL; |
|
716 r = CreateThreadHeap(aInfo, pH, 0, aNotFirst); |
|
717 } |
|
718 else if (aInfo.iAllocator) |
|
719 { |
|
720 // sharing a heap |
|
721 RAllocator* pA = aInfo.iAllocator; |
|
722 pA->Open(); |
|
723 User::SwitchAllocator(pA); |
|
724 } |
|
725 return r; |
|
726 } |
|
727 |