Update contrib.
1 // Copyright (c) 2006-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\smp_demo\smp_demo.cpp
15 // Demonstration for SMP
26 RTest test(_L("SMP_DEMO"));
28 #define DEBUG_PRINT(__args) test.Printf __args ;
30 TBool TestThreadsExit = EFalse;
34 //#define LOCK_TYPE RMutex
35 //#define LOCK_TYPE_CREATE_PARAM
36 #define LOCK_TYPE RFastLock
37 #define LOCK_TYPE_CREATE_PARAM
38 //#define LOCK_TYPE RSemaphore
39 //#define LOCK_TYPE_CREATE_PARAM 0
42 #define MAX_CHAPTERS 28
44 TUint8 TestGuess[MAX_THREADS];
45 TInt TestGuessReady[MAX_THREADS];
46 LOCK_TYPE TestGuessLock[MAX_THREADS];
48 TInt TestGuessChanged[MAX_THREADS];
49 LOCK_TYPE TestChangedLock[MAX_THREADS];
50 TUint8 TestNext[MAX_THREADS];
52 TUint TestGuessMisses[MAX_THREADS];
53 TUint TestGuessCorrect[MAX_THREADS];
54 TUint TestGuessIncorrect[MAX_THREADS];
55 TUint TestGuessCollision[MAX_THREADS];
56 TInt TestCpuCount = 0;
58 TBool TestUseMathRandom = ETrue;
59 TBool TestSingleCpu = EFalse;
60 TBool TestDualCpu = EFalse;
61 TBool TestNoPrint = EFalse;
62 TBool TestSingleThread = EFalse;
63 TBool TestUseAffinity = ETrue;
65 TInt LoadChapter(TInt chapterIndex, HBufC8 **aChapterPtrPtr)
69 if (KErrNone != fs.Connect())
71 DEBUG_PRINT(_L("LoadChapter : Can't connect to the FS\n"));
76 filename.Format(_L("z:\\Test\\war_and_peace_ch%d.txt"), chapterIndex);
78 TInt ret = file.Open(fs,filename,EFileRead);
82 ret = file.Size(fileSize);
85 HBufC8 *theBuf = HBufC8::New(fileSize + 10);
88 TPtr8 des2=theBuf->Des();
89 ret = file.Read((TInt)0, des2,fileSize);
92 *aChapterPtrPtr = theBuf;
96 DEBUG_PRINT((_L("LoadChapter : Read Failed for %S of %d\n"), &filename, fileSize));
101 DEBUG_PRINT((_L("LoadChapter : Buffer Alloc Failed for %S\n"), &filename));
106 DEBUG_PRINT((_L("LoadChapter : Size Failed for %S\n"), &filename));
112 DEBUG_PRINT((_L("LoadChapter : Open Failed for %S\n"), &filename));
118 TInt SetCpuAffinity(TInt aThreadId)
124 if (TestCpuCount == 4)
125 cpu = (TUint32)(aThreadId % 3) + 1;
126 else if (TestCpuCount == 2)
131 TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)cpu, 0);
139 LOCAL_C TInt DemoThread(TAny* aUseTb)
141 TInt threadId = (TInt)aUseTb;
143 SetCpuAffinity(threadId);
146 TestGuessChanged[threadId] = EFalse;
147 TestGuessReady[threadId] = EFalse;
148 TestGuessMisses[threadId] = 0;
149 TestGuessCorrect[threadId] = 0;
150 TestGuessIncorrect[threadId] = 0;
151 TestGuessCollision[threadId] = 0;
154 TUint8 nextChar = TestNext[threadId];
155 TBool correct = EFalse;
157 while (!TestThreadsExit)
161 if (TestUseMathRandom)
162 guess = (TUint8)Math::Random();
166 if (TestGuessChanged[threadId])
168 TestChangedLock[threadId].Wait();
169 nextChar = TestNext[threadId];
170 TestGuessChanged[threadId] = EFalse;
171 TestChangedLock[threadId].Signal();
173 correct = (nextChar == guess);
177 if (TestGuessReady[threadId] == EFalse)
179 TestGuessLock[threadId].Wait();
180 TestGuess[threadId] = guess;
181 TestGuessReady[threadId] = ETrue;
182 TestGuessLock[threadId].Signal();
183 TestGuessCorrect[threadId] ++;
187 TestGuessMisses[threadId] ++;
192 TestGuessIncorrect[threadId] ++;
194 if (TestCpuCount == 1)
204 TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
212 User::CommandLine(args);
217 TPtrC token=lex.NextToken();
218 if(token.Length()!=0)
220 if (token == _L("unbound"))
222 TestUseMathRandom = EFalse;
224 if (token == _L("single"))
226 TestSingleCpu = ETrue;
228 if (token == _L("dual"))
232 if (token == _L("silent"))
236 if (token == _L("onethread"))
238 TestSingleCpu = ETrue;
239 TestSingleThread = ETrue;
241 if (token == _L("help"))
243 test.Printf(_L("smp_demo: unbound | single | onethread | silent | dual | noaffinity | help \n"));
246 if (token == _L("noaffinity"))
248 TestUseAffinity = EFalse;
262 test.Start(_L("SMP Demonstration guessing War and Peace...."));
264 if (ParseArgs() != KErrNone)
271 TUint start = User::TickCount();
273 HAL::Get(HAL::ESystemTickPeriod, tickPeriod);
279 else if (TestDualCpu)
285 TestCpuCount = NumberOfCpus();
288 DEBUG_PRINT((_L("CPU Count %d\n"), TestCpuCount));
290 TRequestStatus theStatus[MAX_THREADS];
291 RThread theThreads[MAX_THREADS];
292 TBool threadInUse[MAX_THREADS];
295 TInt maxChapters = MAX_CHAPTERS;
297 if (TestUseMathRandom)
302 TInt maxIndex = TestCpuCount - 1;
308 else if ((maxIndex == 1) && (TestUseMathRandom))
318 UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)cpu, 0);
321 if (TestSingleThread)
326 maxChapters = MAX_CHAPTERS;
328 TRequestStatus keyStatus;
329 CConsoleBase* console=test.Console();
331 console->Read(keyStatus);
333 for (chapterIndex = 0; chapterIndex < maxChapters; chapterIndex ++)
335 HBufC8 *chapterPtr = NULL;
336 ret = LoadChapter(chapterIndex + 1, &chapterPtr);
337 if ((ret != KErrNone) || (chapterPtr == NULL))
339 DEBUG_PRINT((_L("E32Main: LoadChapter failed %d\n"), ret));
343 TPtr8 theDes = chapterPtr->Des();
344 TUint8 *pData = (TUint8 *)theDes.Ptr();
345 TInt dataLength = chapterPtr->Length();
348 while (dataLength > 0)
350 if (TestUseMathRandom)
351 guess = (TUint8)Math::Random();
361 test.Printf(_L("%c"), (TUint8)guess);
364 if (keyStatus != KRequestPending)
366 if (console->KeyCode() == EKeyEscape)
368 TestThreadsExit = ETrue;
371 console->Read(keyStatus);
376 test.Printf(_L("\n\n"));
383 console->ReadCancel();
384 test.Printf(_L("Finished after %d chapters!\n"),chapterIndex);
388 for (index = 0; index < maxIndex; index ++)
390 TestGuessLock[index].CreateLocal(LOCK_TYPE_CREATE_PARAM);
391 TestChangedLock[index].CreateLocal(LOCK_TYPE_CREATE_PARAM);
392 ret = theThreads[index].Create(KTestBlank,DemoThread,KDefaultStackSize,NULL,(TAny*) index);
395 theThreads[index].Logon(theStatus[index]);
396 if (theStatus[index] != KRequestPending)
398 DEBUG_PRINT((_L("E32Main: !KRequestPending %d\n"), theStatus[index].Int() ));
400 theThreads[index].Resume();
401 threadInUse[index] = ETrue;
402 DEBUG_PRINT((_L("E32Main: starting thread %d %d\n"), index, index % TestCpuCount));
406 DEBUG_PRINT((_L("E32Main: Create thread failed %d\n"), ret));
414 TRequestStatus keyStatus;
415 CConsoleBase* console=test.Console();
417 console->Read(keyStatus);
419 for (chapterIndex = 0; chapterIndex < maxChapters; chapterIndex ++)
421 HBufC8 *chapterPtr = NULL;
422 ret = LoadChapter(chapterIndex + 1, &chapterPtr);
423 if ((ret != KErrNone) || (chapterPtr == NULL))
425 DEBUG_PRINT((_L("E32Main: LoadChapter failed %d\n"), ret));
429 TPtr8 theDes = chapterPtr->Des();
430 TUint8 *pData = (TUint8 *)theDes.Ptr();
431 TInt dataLength = chapterPtr->Length();
432 for (index2 = 0; index2 < maxIndex; index2 ++)
434 TestChangedLock[index2].Wait();
435 TestGuessChanged[index2] = ETrue;
436 TestNext[index2] = (TUint8)*pData;
437 TestChangedLock[index2].Signal();
439 // where the real code goes!!
441 TBool wasReady = EFalse;
442 while (dataLength > 0)
444 for (index = 0; index < maxIndex; index ++)
447 if (TestGuessReady[index])
450 TestGuessLock[index].Wait();
451 guess = (TUint8)TestGuess[index];
452 TestGuessReady[index] = EFalse;
453 TestGuessLock[index].Signal();
461 for (index2 = 0; index2 < maxIndex; index2 ++)
463 TestChangedLock[index2].Wait();
464 TestNext[index2] = (TUint8)*pData;
465 TestGuessChanged[index2] = ETrue;
466 TestChangedLock[index2].Signal();
470 test.Printf(_L("%c"), (TUint8)guess);
475 TestGuessCollision[index] ++;
478 if (TestCpuCount == 1)
483 if (keyStatus != KRequestPending)
485 if (console->KeyCode() == EKeyEscape)
487 TestThreadsExit = ETrue;
490 console->Read(keyStatus);
495 test.Printf(_L("\n\n"));
503 console->ReadCancel();
505 test.Printf(_L("Finished after %d chapters!\n"),chapterIndex);
506 for (index = 0; index < maxIndex; index ++)
508 test.Printf(_L("Thread %d stalls %u correct %u incorrect %u collision %u\n"), index, TestGuessMisses[index],TestGuessCorrect[index],TestGuessIncorrect[index], TestGuessCollision[index]);
512 TestThreadsExit = ETrue;
514 TBool anyUsed = ETrue;
520 for (index = 0; index < maxIndex; index++)
522 if (threadInUse[index])
524 if (theThreads[index].ExitType() != EExitPending)
526 threadInUse[index] = EFalse;
527 TestGuessLock[index].Close();
528 TestChangedLock[index].Close();
538 TUint time = TUint((TUint64)(User::TickCount()-start)*(TUint64)tickPeriod/(TUint64)1000000);
539 test.Printf(_L("Complete in %u seconds\n"), time);