Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\misc\t_condvar2.cpp
18 #define __E32TEST_EXTENSION__
21 #include <e32base_private.h>
25 #include "../misc/prbs.h"
26 #include "../mmu/freeram.h"
28 const TInt KStackSize=0x1000;
30 RTest test(_L("T_CONDVAR2"));
32 const TInt KPacketSize = 1024;
33 const TInt KCrcSize = KPacketSize;
38 TUint iData[KPacketSize/4];
42 TDblQue<SMessage> Queue(0);
50 class CThread : public CActive
53 CThread(TInt aPriority);
56 virtual void DoCancel();
57 virtual void DisplayStats()=0;
60 static TInt ThreadFunc(TAny* aPtr);
62 virtual TInt StartThread()=0;
63 virtual TInt RunThread()=0;
78 class CProducerThread : public CThread
81 static void NewL(TInt aId);
82 CProducerThread(TInt aId);
83 virtual TInt StartThread();
84 virtual TInt RunThread();
85 virtual void DisplayStats();
88 class CConsumerThread : public CThread
91 static void NewL(TInt aId);
92 CConsumerThread(TInt aId);
93 virtual TInt StartThread();
94 virtual TInt RunThread();
95 virtual void DisplayStats();
98 class CRandomTimer : public CActive
102 CRandomTimer(TInt aPriority);
105 virtual void DoCancel();
116 class CStatsTimer : public CActive
120 CStatsTimer(TInt aPriority);
123 virtual void DoCancel();
132 const TInt KNumProducers=4;
133 CProducerThread* TheProducers[KNumProducers];
134 const TInt KNumConsumers=4;
135 CConsumerThread* TheConsumers[KNumConsumers];
136 CRandomTimer* TheRandomTimer;
138 CThread::CThread(TInt aPriority)
150 TInt StartAllThreads()
153 TInt r = CV.CreateLocal();
156 for (i=0; i<KNumConsumers; ++i)
158 r = TheConsumers[i]->Start();
162 for (i=0; i<KNumProducers; ++i)
164 r = TheProducers[i]->Start();
173 TExitType exitType = iThread.ExitType();
174 TInt exitReason = iThread.ExitReason();
175 const TDesC& exitCat = iThread.ExitCategory();
177 if (exitType==EExitKill)
179 if (exitReason!=KErrNone && exitReason!=KErrGeneral)
182 else if (exitType==EExitPanic)
184 if (exitCat!=_L("KERN-EXEC") || exitReason!=0 || CV.Handle()!=0)
191 TFullName n(iThread.FullName());
193 test.Printf(_L("Thread %S (P%1d) exited %d,%d,%S\n"),&n,iId,exitType,exitReason,&exitCat);
195 test.Printf(_L("Thread %S (C%1d) exited %d,%d,%S\n"),&n,iId,exitType,exitReason,&exitCat);
196 CActiveScheduler::Stop();
199 CLOSE_AND_WAIT(iThread);
200 if (exitType==EExitTerminate)
202 else if (exitType==EExitKill && exitReason==KErrNone)
204 else if (exitType==EExitKill && exitReason==KErrGeneral)
209 SharedHeap->Free(iTempAlloc);
216 r = StartAllThreads();
224 test.Printf(_L("Start thread error %d\n"),r);
225 CActiveScheduler::Stop();
229 void CThread::DoCancel()
231 iThread.LogonCancel(iStatus);
234 TInt CThread::Start()
242 if (r!=KErrAlreadyExists)
248 iThread.Logon(iStatus);
255 TInt CThread::ThreadFunc(TAny* aPtr)
257 return ((CThread*)aPtr)->RunThread();
260 CConsumerThread::CConsumerThread(TInt aId)
266 void CConsumerThread::NewL(TInt aId)
268 CConsumerThread* pT=new (ELeave) CConsumerThread(aId);
269 TheConsumers[aId] = pT;
270 CActiveScheduler::Add(pT);
271 User::LeaveIfError(pT->Start());
274 TInt CConsumerThread::StartThread()
276 TInt r=iThread.Create(KNullDesC(), &ThreadFunc, KStackSize, SharedHeap, this); // use unnamed thread
283 void CConsumerThread::DisplayStats()
285 test.Printf(_L("C%1d: I:%9d O:%9d S:%9d T:%9d C:%9d\n"), iId, iInnerCount, iOuterCount, iSuspendCount, iTerminateCount, iCvCloseCount);
288 TInt CConsumerThread::RunThread()
294 while (Queue.IsEmpty())
303 SMessage* m = Queue.First();
306 TBool seq_ok = (m->iSeq == CSeq++);
312 Mem::Crc(crc, m->iData, KCrcSize);
323 CProducerThread::CProducerThread(TInt aId)
329 void CProducerThread::NewL(TInt aId)
331 CProducerThread* pT=new (ELeave) CProducerThread(aId);
332 TheProducers[aId] = pT;
333 CActiveScheduler::Add(pT);
334 User::LeaveIfError(pT->Start());
337 TInt CProducerThread::StartThread()
339 TInt r=iThread.Create(KNullDesC(), &ThreadFunc, KStackSize, SharedHeap, this); // use unnamed thread
346 void CProducerThread::DisplayStats()
348 test.Printf(_L("P%1d: I:%9d O:%9d S:%9d T:%9d C:%9d\n"), iId, iInnerCount, iOuterCount, iSuspendCount, iTerminateCount, iCvCloseCount);
351 TInt CProducerThread::RunThread()
354 seed[0] = User::TickCount();
359 SMessage* m = new SMessage;
363 for (; i<KPacketSize/4; ++i)
364 m->iData[i] = Random(seed);
366 Mem::Crc(crc, m->iData, KCrcSize);
377 if (!(Random(seed)&1))
378 User::AfterHighRes(1000);
382 void CRandomTimer::NewL()
384 CRandomTimer* pR=new (ELeave) CRandomTimer(20);
385 User::LeaveIfError(pR->iTimer.CreateLocal());
386 CActiveScheduler::Add(pR);
391 CRandomTimer::CRandomTimer(TInt aPriority)
394 iSeed[0]=User::TickCount();
397 CRandomTimer::~CRandomTimer()
403 void CRandomTimer::RunL()
408 TUint x=Random(iSeed)&511;
409 TInt tn=(TInt)(Random(iSeed) % (KNumConsumers + KNumProducers));
410 CThread* pT = (tn>=KNumConsumers) ? (CThread*)TheProducers[tn-KNumConsumers] : (CThread*)TheConsumers[tn];
416 if (iSuspended->iThread.Handle())
417 iSuspended->iThread.Resume();
422 if (pT->iThread.Handle()==0)
434 pT->iThread.Terminate(0);
435 if (iSuspended == pT)
439 if (iSuspended && (x&1))
441 if (iSuspended->iThread.Handle())
442 iSuspended->iThread.Resume();
445 if (!iSuspended && !(x&15))
448 pT->iThread.Suspend();
453 tp = EPriorityMuchMore;
457 tp = EPriorityNormal;
461 tp = EPriorityMuchLess;
462 pT->iThread.SetPriority(tp);
468 void CRandomTimer::Start()
470 TUint x=Random(iSeed)&15;
472 iTimer.HighRes(iStatus, x*1000);
476 void CRandomTimer::DoCancel()
481 void CStatsTimer::NewL()
483 CStatsTimer* pT=new (ELeave) CStatsTimer(-10);
484 User::LeaveIfError(pT->iTimer.CreateLocal());
485 CActiveScheduler::Add(pT);
489 CStatsTimer::CStatsTimer(TInt aPriority)
492 iInitFreeRam = FreeRam();
495 CStatsTimer::~CStatsTimer()
501 void CStatsTimer::RunL()
504 for (i=0; i<KNumProducers; i++)
505 TheProducers[i]->DisplayStats();
506 for (i=0; i<KNumConsumers; i++)
507 TheConsumers[i]->DisplayStats();
508 test.Printf(_L("RndTm: %9d BO: %9d ZH: %9d\n"), TheRandomTimer->iCount, TheRandomTimer->iBackOff, TheRandomTimer->iZeroHandle);
509 TInt free_ram = FreeRam();
510 TInt delta_ram = iInitFreeRam - free_ram;
511 if (delta_ram > iMaxDelta)
512 iMaxDelta = delta_ram;
515 test.Printf(_L("Max RAM delta %dK Free RAM %08x\n"), iMaxDelta/1024, free_ram);
521 void CStatsTimer::Start()
523 iTimer.After(iStatus, 1000000);
527 void CStatsTimer::DoCancel()
532 _LIT(KSharedHeap, "SharedHeap");
537 User::LeaveIfError(Mutex.CreateLocal());
538 User::LeaveIfError(CV.CreateLocal());
539 User::LeaveIfNull(SharedHeap = UserHeap::ChunkHeap(&KSharedHeap, 0x1000, 0x01000000));
540 CActiveScheduler* pA=new (ELeave) CActiveScheduler;
541 CActiveScheduler::Install(pA);
543 for (id=0; id<KNumConsumers; ++id)
544 CConsumerThread::NewL(id);
545 for (id=0; id<KNumProducers; ++id)
546 CProducerThread::NewL(id);
547 CRandomTimer::NewL();
551 GLDEF_C TInt E32Main()
559 RThread().SetPriority(EPriorityAbsoluteHigh);
561 TRAPD(r,InitialiseL());
564 User::SetJustInTime(EFalse);
566 CActiveScheduler::Start();