Update contrib.
1 // Copyright (c) 2002-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\smpsoak\t_smpsoak.cpp
18 #include "t_smpsoak.h"
20 void ParseCommandLine ();
23 static TInt gPageSize;
25 static TUint gTimeout = 120;
27 //class for smpsoak thread and it creates memory, device, timer and spin threads.
35 void CreateChildProcess(TInt aIndex);
36 void ResumeChildProcess();
37 void TerminateChildProcess();
40 static TInt SMPStressMemoryThread(TAny*);
41 static TInt SMPStressDeviceThread(TAny*);
42 static TInt SMPStressTimerThread(TAny*);
43 static TInt SMPStressSpinThread(TAny*);
45 void DoCreateThread(TAny*);
46 void SetThreadPriority();
48 //Utils for memory thread
49 void CreateChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
50 void CommitChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
51 void WriteReadChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
53 //Memebers for threads
54 TInt DoSMPStressMemoryThread();
55 TInt DoSMPStressDeviceThread();
56 TInt DoSMPStressTimerThread();
57 TInt DoSMPStressSpinThread();
59 TThreadData iThreadData;
64 // Thread Data for each thread- low priority
65 static TThread KThreadTableLow[];
66 // Thread Data for each thread- high priority
67 static TThread KThreadTableHigh[];
68 //Process Data for each process
69 static const TProcess KProcessTable[];
70 //Memory table for memory thread
71 static const TMemory KMemoryTable[];
72 //Device table for device thread
73 static const TDesC* KDeviceTable[];
76 TThread CSMPSoakThread::KThreadTableLow[] =
78 { _L("Memory Thread"), CSMPSoakThread::SMPStressMemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 250, 1, (TAny *)&KMemoryTable, NULL, NULL}},
79 { _L("Device Thread"), CSMPSoakThread::SMPStressDeviceThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 300, 1, &KDeviceTable, NULL, NULL}},
80 { _L("Spin Thread 0"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityAbsoluteVeryLow, EPriorityNormal, EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 200, 0, NULL, NULL, NULL}},
81 { _L("Spin Thread 1"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityAbsoluteVeryLow, EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 300, 0, NULL, NULL, NULL}},
82 { _L("Spin Thread 2"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal, EPriorityAbsoluteVeryLow, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 400, 0, NULL, NULL, NULL}},
83 { _L("Spin Thread 3"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal, EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow}, EPriorityList, KCpuAffinityAny, 500, 0, NULL, NULL, NULL}},
84 { _L("Timer Thread"), CSMPSoakThread::SMPStressTimerThread, {{EPriorityNormal, 0, 0, 0}, EPriorityList, KCpuAffinityAny, 1000, 4, NULL}},
86 TThread CSMPSoakThread::KThreadTableHigh[] =
88 { _L("Memory Thread"), CSMPSoakThread::SMPStressMemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 250, 1, (TAny *)&KMemoryTable, NULL, NULL}},
89 { _L("Device Thread"), CSMPSoakThread::SMPStressDeviceThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 300, 1, &KDeviceTable, NULL, NULL}},
90 { _L("Spin Thread 0"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityAbsoluteVeryLow, EPriorityNormal, EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 200, 0, NULL, NULL, NULL}},
91 { _L("Spin Thread 1"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityAbsoluteVeryLow, EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 300, 0, NULL, NULL, NULL}},
92 { _L("Spin Thread 2"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal, EPriorityAbsoluteVeryLow, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 400, 0, NULL, NULL, NULL}},
93 { _L("Spin Thread 3"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal, EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow}, EPriorityList, KCpuAffinityAny, 500, 0, NULL, NULL, NULL}},
94 { _L("Timer Thread"), CSMPSoakThread::SMPStressTimerThread, {{EPriorityNormal, 0, 0, 0}, EPriorityList, KCpuAffinityAny, 1000, 4, NULL}},
96 const TProcess CSMPSoakThread::KProcessTable[] =
98 { _L("t_smpsoakprocess.exe"), _L("-W"), KCpuAffinityAny},
99 { _L("t_smpsoakprocess.exe"), _L("-R"), KCpuAffinityAny},
100 { _L("t_smpsoakprocess.exe"), _L("-F"), KCpuAffinityAny},
101 { _L("t_smpsoakprocess.exe"), _L("-T"), KCpuAffinityAny},
102 { _L("t_smpsoakprocess.exe"), _L("-O"), KCpuAffinityAny},
104 const TMemory CSMPSoakThread::KMemoryTable[] =
106 {_L(""), EChunkNormalThread, 0, 10, 100 },
107 {_L("Global Chunk 1"), EChunkNormalThread, 0, 20, 200 },
108 {_L(""), EChunkDisconnectedThread, 3, 30, 300 },
109 {_L("Global Chunk 2"), EChunkDisconnectedThread, 4, 40, 400 },
110 {_L(""), EChunkDoubleEndedThread, 5, 50, 500 },
111 {_L("Global Chunk 3"), EChunkDoubleEndedThread, 6, 60, 600 },
112 {_L(""), EChunkNormalProcess, 0, 10, 100 },
113 {_L("Global Chunk 4"), EChunkNormalProcess, 0, 20, 200 },
114 {_L(""), EChunkDisconnectedProcess, 3, 30, 300 },
115 {_L("Global Chunk 5"), EChunkDisconnectedProcess, 4, 40, 400 },
116 {_L(""), EChunkDoubleEndedProcess, 5, 50, 500 },
117 {_L("Global Chunk 6"), EChunkDoubleEndedProcess, 6, 60, 600 },
118 {_L(""), EChunkNone, 0, 0, 0 },
120 const TDesC* CSMPSoakThread::KDeviceTable[] =
122 &KDevices, &KDevLdd1, &KDevLdd1Name, &KDevLdd2, &KDevLdd2Name, &KDevLdd3, &KDevLdd3Name,
123 &KDevLdd4, &KDevLdd4Name, &KDevLdd5, &KDevLdd5Name, NULL
127 CSMPSoakThread::CSMPSoakThread()
131 CSMPSoakThread::~CSMPSoakThread()
134 //All child process creation
135 void CSMPSoakThread::CreateChildProcess(TInt aIndex)
138 gCmdLine.Format(KCmdLineBackground,(KProcessTable[aIndex].operation).Ptr());
140 gCmdLine.Format(KCmdLinePeriod,gPeriod,(KProcessTable[aIndex].operation).Ptr());
142 gCmdLine.Format(KCmdLineProcess,(KProcessTable[aIndex].operation).Ptr());
144 TInt r = iProcess.Create(KProcessTable[aIndex].processFileName,gCmdLine);
146 iProcess.SetPriority(EPriorityLow);
147 gSMPStressDrv.ChangeThreadAffinity(&iThread, KProcessTable[aIndex].cpuAffinity);
148 PRINT ((_L("SetProcessPriority CPU %d Priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iProcess.Priority()));
150 //Terminate process when user press "Esc key"
151 void CSMPSoakThread::ResumeChildProcess()
155 //Terminate process when user press "Esc key"
156 void CSMPSoakThread::TerminateChildProcess()
158 iProcess.Kill(KErrNone);
160 //Changes the thread priority each time time, for each thread by Random, Increment, from List, Fixed.
161 //pick up the priority option from thread table
162 void CSMPSoakThread::SetThreadPriority()
164 static TInt64 randSeed = KRandSeed;
165 static const TThreadPriority priorityTable[]=
167 EPriorityMuchLess, EPriorityLess, EPriorityNormal, EPriorityMore, EPriorityMuchMore,
168 EPriorityRealTime, EPriorityRealTime, EPriorityAbsoluteVeryLow, EPriorityAbsoluteLowNormal,
169 EPriorityAbsoluteLow, EPriorityAbsoluteBackgroundNormal, EPriorityAbsoluteBackground,
170 EPriorityAbsoluteForegroundNormal, EPriorityAbsoluteForeground, EPriorityAbsoluteHighNormal, EPriorityAbsoluteHigh
172 TInt priorityIndex = 0;
173 switch (iThreadData.threadPriorityChange)
179 if (++iPriority >= KPriorityOrder)
181 if (iThreadData.threadPriorities[iPriority] == 0)
183 // PRINT(_L("SetPriority List CPU %d index %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread),iPriority, iThreadData.threadPriorities[iPriority]);
184 iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[iPriority]);
187 case EPriorityIncrement:
188 while (priorityTable[priorityIndex] <= iPriority)
192 iPriority = priorityTable[priorityIndex];
193 if (iPriority > iThreadData.threadPriorities[2])
194 iPriority = iThreadData.threadPriorities[1];
195 // PRINT(_L("SetPriority Increment CPU %d iPriority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
196 iThread.SetPriority((TThreadPriority)iPriority);
199 case EPriorityRandom:
200 iPriority = Math::Rand(randSeed) % (iThreadData.threadPriorities[2] - iThreadData.threadPriorities[1] + 1);
201 iPriority += iThreadData.threadPriorities[1];
202 while (priorityTable[priorityIndex] < iPriority)
206 iPriority = priorityTable[priorityIndex];
207 // PRINT(_L("SetPriority Random CPU %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
208 iThread.SetPriority((TThreadPriority)iPriority);
213 void CSMPSoakThread::ResumeThread()
218 void CSMPSoakThread::CreateThread()
220 CSMPSoakThread* smpthread = new CSMPSoakThread[KNumThreads];
221 for (TInt i = 0; i < KNumThreads ; i++)
223 if(ThreadPriorityLow)
225 PRINT ((_L("Thread Table - Priority Low \n")));
226 smpthread[i].DoCreateThread(&KThreadTableLow[i]);
230 PRINT ((_L("Thread Table - Priority High \n")));
231 smpthread[i].DoCreateThread(&KThreadTableHigh[i]);
234 PRINT (_L("Resuming all threads\n"));
235 for (TInt i = 0; i < KNumThreads; i++)
236 smpthread[i].ResumeThread();
239 * CSMPSoakThread Thread Creation.
240 * @param aIndex to exercise each row(thread) in the thread table
244 * @pre Initialize thread Table values
247 void CSMPSoakThread::DoCreateThread(TAny* aThread)
249 //Initialize each thread data
250 iThreadData = ((TThread*)aThread)->threadData;
251 test.Next(_L("Create Thread"));
252 PRINT ((_L("%s CPU affinity %d Priority %d\n"),((TThread*)aThread)->threadName.Ptr(),iThreadData.cpuAffinity,iThreadData.threadPriorities[0]));
253 TInt r = iThread.Create(((TThread*)aThread)->threadName, ((TThread*)aThread)->threadFunction, KDefaultStackSize, KHeapMinSize, KHeapMaxSize,(TAny*)this);
255 if (iThreadData.threadPriorityChange == EPriorityList)
261 iPriority = iThreadData.threadPriorities[0];
263 iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[0]);
264 //Set the thread CPU Affinity
265 gSMPStressDrv.ChangeThreadAffinity(&iThread, iThreadData.cpuAffinity);
267 //Create Chunk - different types
268 void CSMPSoakThread::CreateChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
270 //RDebug::Print(_L("Creating chunk name %s type %d bottom %d top %d max %d\n"),aMemoryTablePtr->globalChunkName.Ptr(),aMemoryTablePtr->chunkType,aMemoryTablePtr->initialBottom,aMemoryTablePtr->initialTop,aMemoryTablePtr->maxSize);
271 TOwnerType ownerType = EOwnerProcess;
272 aChunkInfo->lastBottom = aMemoryTablePtr->initialBottom;
273 aChunkInfo->lastTop = aMemoryTablePtr->initialTop;
274 switch (aMemoryTablePtr->chunkType)
276 case EChunkNormalThread:
277 ownerType = EOwnerThread; // drop through to create chunk
278 case EChunkNormalProcess:
279 if (aMemoryTablePtr->globalChunkName.Length())
281 test_KErrNone(aChunkInfo->chunk.CreateGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
285 test_KErrNone(aChunkInfo->chunk.CreateLocal(aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
287 aChunkInfo->lastBottom = 0; // ensure that this is zero
290 case EChunkDisconnectedThread:
291 ownerType = EOwnerThread; // drop through to create chunk
292 case EChunkDisconnectedProcess:
293 if (aMemoryTablePtr->globalChunkName.Length())
295 test_KErrNone(aChunkInfo->chunk.CreateDisconnectedGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
299 test_KErrNone(aChunkInfo->chunk.CreateDisconnectedLocal(aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
303 case EChunkDoubleEndedThread:
304 ownerType = EOwnerThread; // drop through to create chunk
305 case EChunkDoubleEndedProcess:
306 if (aMemoryTablePtr->globalChunkName.Length())
308 test_KErrNone(aChunkInfo->chunk.CreateDoubleEndedGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
312 test_KErrNone(aChunkInfo->chunk.CreateDoubleEndedLocal(aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
318 void CSMPSoakThread::CommitChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
322 switch (aMemoryTablePtr->chunkType)
324 case EChunkNormalThread:
325 case EChunkNormalProcess:
326 if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
328 aChunkInfo->lastTop += (aMemoryTablePtr->maxSize - 1 - aChunkInfo->lastTop) / 2 + 1;
329 //PRINT(_L("Adjust chunk memory - top %d pagesize %d\n"),aChunkInfo->lastTop,gPageSize);
330 test_KErrNone(aChunkInfo->chunk.Adjust(aChunkInfo->lastTop*gPageSize));
334 case EChunkDisconnectedThread:
335 case EChunkDisconnectedProcess:
336 commitPages = ((aChunkInfo->lastTop - aChunkInfo->lastBottom) / 2) + 1;
337 //PRINT(_L("Decommitting from bottom %d of %d pages\n"),aChunkInfo->lastBottom,commitPages);
338 test_KErrNone(aChunkInfo->chunk.Decommit(aChunkInfo->lastBottom*gPageSize,commitPages * gPageSize));
339 if ((aChunkInfo->lastBottom > 0) && (aChunkInfo->lastTop <= aMemoryTablePtr->initialTop))
341 aChunkInfo->lastTop = aChunkInfo->lastBottom + commitPages - 1;
342 aChunkInfo->lastBottom /= 2;
343 commitPages = aChunkInfo->lastTop - aChunkInfo->lastBottom + 1;
347 if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize -1))
349 if (aChunkInfo->lastTop <= aMemoryTablePtr->initialTop)
351 aChunkInfo->lastBottom = aMemoryTablePtr->initialTop + 1;
355 aChunkInfo->lastBottom = aChunkInfo->lastTop + 1;
357 commitPages = ((aMemoryTablePtr->maxSize - aChunkInfo->lastBottom) / 2) + 1;
358 aChunkInfo->lastTop = aChunkInfo->lastBottom + commitPages - 1;
367 //PRINT(_L("Commit chunk memory bottom %d size %d pages\n"),aChunkInfo->lastBottom,commitPages);
368 test_KErrNone(aChunkInfo->chunk.Commit(aChunkInfo->lastBottom*gPageSize,commitPages*gPageSize));
372 case EChunkDoubleEndedThread:
373 case EChunkDoubleEndedProcess:
374 if (aChunkInfo->lastBottom > 0 || aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
376 if (aChunkInfo->lastBottom > 0)
378 aChunkInfo->lastBottom--;
380 if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
382 aChunkInfo->lastTop++;
384 // PRINT(_L("Adjust Double Ended bottom %d top %d\n"),aChunkInfo->lastBottom,aChunkInfo->lastTop);
385 test_KErrNone(aChunkInfo->chunk.AdjustDoubleEnded(aChunkInfo->lastBottom*gPageSize,aChunkInfo->lastTop*gPageSize));
390 //Write then read chunk
391 void CSMPSoakThread::WriteReadChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
393 if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
395 TInt chunkSize = aChunkInfo->lastTop*gPageSize - aChunkInfo->lastBottom*gPageSize;
396 //RDebug::Print(_L("WriteReadChunk Last Top %d lastBottom %d\n"),aChunkInfo->lastTop,aChunkInfo->lastBottom);
397 TUint8 *writeaddr = aChunkInfo->chunk.Base()+ aChunkInfo->lastBottom*gPageSize;
398 TPtr8 write(writeaddr,chunkSize);
399 write.Copy(pattern,sizeof(pattern));
400 test_KErrNone(Mem::Compare(writeaddr,sizeof(pattern),pattern,sizeof(pattern)));
403 //Memory Thread : will do memory associated operation
404 //param aSmp - CSMPSoakUtil pointer
405 TInt CSMPSoakThread::SMPStressMemoryThread(TAny* aSmp)
407 CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
408 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressMemoryThread Panic"),0));
409 return self->DoSMPStressMemoryThread();
411 // Member for thread function
412 TInt CSMPSoakThread::DoSMPStressMemoryThread()
414 RTest test(_L("SMPStressMemoryThread"));
416 TMemory *memoryTablePtr;
417 TChunkInfo chunkTable[KNumChunks];
419 test_KErrNone(UserHal::PageSizeInBytes(gPageSize));
428 memoryTablePtr = (TMemory *) (iThreadData.listPtr);
431 //Create different type of chunks and write/read/verfiy it
432 while (memoryTablePtr->chunkType != EChunkNone)
434 PRINT((_L("Create Chunk")));
435 CreateChunk (&chunkTable[ctIndex],memoryTablePtr);
437 PRINT(_L("Write and Read Chunk"));
438 WriteReadChunk (&chunkTable[ctIndex],memoryTablePtr);
444 //Commit different type of chunks
449 memoryTablePtr = (TMemory *) (iThreadData.listPtr);
451 while (memoryTablePtr->chunkType != EChunkNone)
454 PRINT((_L("Commit Chunk Memory")));
455 PRINT ((_L("CommitChunk %d bottom %d top %d\n"),ctIndex,memoryTablePtr->initialBottom,memoryTablePtr->initialTop));
456 CommitChunk (&chunkTable[ctIndex],memoryTablePtr);
460 WriteReadChunk (&chunkTable[ctIndex],memoryTablePtr);
461 PRINT((_L("Write Read Chunk Size %d\n"), (memoryTablePtr->initialTop) - (memoryTablePtr->initialBottom)));
469 memoryTablePtr = (TMemory *) (iThreadData.listPtr);
471 while (memoryTablePtr->chunkType != EChunkNone)
473 chunkTable[ctIndex].chunk.Close();
478 User::After(gPeriod);
482 //Device Thread : will do device associated operation
483 //param aSmp - CSMPSoakUtil pointer
484 TInt CSMPSoakThread::SMPStressDeviceThread(TAny* aSmp)
486 CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
487 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressDeviceThread Panic"),0));
488 return self->DoSMPStressDeviceThread();
490 // Member for thread function
491 TInt CSMPSoakThread::DoSMPStressDeviceThread()
493 RTest test(_L("SMPStressDeviceThread"));
497 TFileName sessionPath;
499 test_KErrNone(timer.CreateLocal());
502 TDesC** ptrDevices = (TDesC**) (iThreadData.listPtr);
503 PRINT ((_L("Devices Number %d [%s]\n"), ptrDevices[0]->Length(), ptrDevices[0]->Ptr()));
504 for (TInt i = 1; ptrDevices[i] ; i++)
505 PRINT ((_L("LDD%d=%s "),i,ptrDevices[i]->Ptr()));
510 for (TInt i = 0; i < ptrDevices[0]->Length(); i++)
512 TText driveLetter = (*ptrDevices[0])[i];
513 PRINT ((_L("Device %c\n"),driveLetter));
515 test_KErrNone(session.Connect());
517 sessionPath=(_L("?:\\SESSION_TEST\\"));
518 sessionPath[0]=driveLetter;
519 test_KErrNone(session.SetSessionPath(sessionPath));
522 test_KErrNone(session.CharToDrive(driveLetter, driveNumber));
524 TBuf<64> fileSystemName;
525 test_KErrNone(session.FileSystemName(fileSystemName,driveNumber));
527 PRINT ((_L("File System Name %s\n"),fileSystemName.PtrZ()));
529 TDriveInfo driveInfo;
530 test_KErrNone(session.Drive(driveInfo, driveNumber));
532 TVolumeInfo volumeInfo;
533 test_KErrNone(session.Volume(volumeInfo, driveNumber));
537 for (TInt i = 1; ptrDevices[i] ; i += 2)
541 TInt r = User::LoadLogicalDevice(*ptrDevices[i]);
542 test(r == KErrNone || r == KErrAlreadyExists);
544 test_KErrNone(device.Open(*ptrDevices[i+1]));
546 TBuf8<64> deviceCaps;
547 device.GetCaps(deviceCaps);
549 TVersion deviceVersion;
550 device.QueryVersionSupported(deviceVersion);
555 timer.After(s, iThreadData.delayTime*1000);
556 User::WaitForRequest(s);
557 test (s == KErrNone);
561 User::After(gPeriod);
564 PRINT((_L("SMPStressDeviceThread MyTimer.Cancel() called\n")));
567 //Spin Thread : will do thread sync
568 //param aSmp - CSMPSoakUtil pointer
569 TInt CSMPSoakThread::SMPStressSpinThread(TAny* aSmp)
571 CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
572 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressSpinThread Panic"),0));
573 return self->DoSMPStressSpinThread();
575 // Member for thread function
576 TInt CSMPSoakThread::DoSMPStressSpinThread()
578 RTest test(_L("SMPStressSpinThread"));
582 TTimeIntervalMicroSeconds loopTimeMicroSeconds;
583 PRINT (_L("SMPStressSpinThread\n"));
588 startTime.UniversalTime();
591 endTime.UniversalTime();
592 loopTimeMicroSeconds = endTime.MicroSecondsFrom(startTime);
593 }while (loopTimeMicroSeconds <= iThreadData.delayTime*1000);
597 User::After(gPeriod);
601 //Timer Thread : Timer operation and thread sync
602 //param aSmp - CSMPSoakUtil pointer
603 TInt CSMPSoakThread::SMPStressTimerThread(TAny* aSmp)
605 CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
606 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressTimerThread Panic"),0));
607 return self->DoSMPStressTimerThread();
609 // Member for thread function
610 TInt CSMPSoakThread::DoSMPStressTimerThread()
612 RTest test(_L("SMPStressTimerThread"));
614 PRINT (_L("SMPStressTimerThread\n"));
616 test_KErrNone(timer.CreateLocal());
621 timer.After(s, iThreadData.delayTime*1000);
622 User::WaitForRequest(s);
623 test (s == KErrNone);
625 gSwitchSem.Signal(iThreadData.numThreads);
629 User::After(gPeriod);
632 PRINT((_L("SMPStressTimerThread MyTimer.Cancel() called\n")));
635 // CActive class to monitor KeyStrokes from User
636 class CActiveConsole : public CActive
642 static TInt Callback(TAny* aCtrl);
643 static CPeriodic* TimerL();
645 // Defined as pure virtual by CActive;
646 // implementation provided by this class.
647 virtual void DoCancel();
648 // Defined as pure virtual by CActive;
649 // implementation provided by this class,
651 void ProcessKeyPressL(TChar aChar);
655 // Class CActiveConsole
656 CActiveConsole::CActiveConsole()
657 : CActive(EPriorityHigh)
659 CActiveScheduler::Add(this);
662 CActiveConsole::~CActiveConsole()
666 CPeriodic* CActiveConsole::TimerL()
668 return(CPeriodic::NewL(EPriorityNormal));
670 // Callback function for timer expiry
671 TInt CActiveConsole::Callback(TAny* aControl)
676 void CActiveConsole::GetCharacter()
678 test.Console()->Read(iStatus);
682 void CActiveConsole::DoCancel()
684 PRINT(_L("CActiveConsole::DoCancel\n"));
685 test.Console()->ReadCancel();
688 void CActiveConsole::ProcessKeyPressL(TChar aChar)
690 if (aChar == EKeyEscape)
692 PRINT(_L("CActiveConsole: ESC key pressed -> stopping active scheduler...\n"));
694 CActiveScheduler::Stop();
701 void CActiveConsole::RunL()
703 ProcessKeyPressL(static_cast<TChar>(test.Console()->KeyCode()));
706 // CActiveTimer class to monitor timeout expiry
707 class CActiveTimer : public CActive
712 void Delay(TTimeIntervalMicroSeconds32 aDelay);
715 // Defined as pure virtual by CActive;
716 // implementation provided by this class.
717 virtual void DoCancel();
718 // Defined as pure virtual by CActive;
719 // implementation provided by this class,
723 // Class CActiveConsole
724 CActiveTimer::CActiveTimer()
725 : CActive(EPriorityHigh)
727 CActiveScheduler::Add(this);
728 User::LeaveIfError(iTimer.CreateLocal());
731 CActiveTimer::~CActiveTimer()
738 void CActiveTimer::Delay(TTimeIntervalMicroSeconds32 aDelay)
740 iTimer.After(iStatus, aDelay);
744 void CActiveTimer::DoCancel()
749 void CActiveTimer::RunL()
751 PRINT(_L("CActiveTimer: Application runtime expired..."));
753 CActiveScheduler::Stop();
757 //T_SMPSOAK Entry Point
762 test.Start(_L("t_smpsoak.exe"));
764 // When running as a stand alone test,
765 // there needs to be a timeout
772 PRINT (_L("Load device driver\n"));
773 TInt r = User::LoadLogicalDevice(_L("d_smpsoak.ldd"));
774 if (r == KErrNotFound)
776 PRINT (_L("Test not supported on this platform because the D_SMPSOAK.LDD Driver is Not Present\n"));
779 PRINT (_L("Calling SMPStressDrv Open\n"));
780 r = gSMPStressDrv.Open();
783 PRINT (_L("Creating our local semaphore\n"));
784 r=gSwitchSem.CreateLocal(0);
787 CSMPSoakThread smpthread;
788 PRINT ((_L("Creating all threads =%d\n"),KNumThreads));
789 smpthread.CreateThread();
791 CSMPSoakThread *smpprocess= new CSMPSoakThread[NumProcess];
792 PRINT ((_L("Creating all process =%d\n"),NumProcess));
793 for (TInt i = 0; i < NumProcess; i++)
794 smpprocess[i].CreateChildProcess(i);
796 PRINT (_L("Resuming all process \n"));
797 for (TInt i = 0; i < NumProcess; i++)
798 smpprocess[i].ResumeChildProcess();
800 PRINT (_L("Starting ActiveScheduler\n"));
801 test.Next(_L("Press ESC Key to Shutdown SMPSoak...\n"));
802 CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
803 test(myScheduler != NULL);
804 CActiveScheduler::Install(myScheduler);
806 CPeriodic* theTimer=NULL;
807 TRAPD(ret,theTimer=CActiveConsole::TimerL())
809 theTimer->Start(0,KTimerPeriod,TCallBack(CActiveConsole::Callback));
812 CActiveTimer* myActiveTimer = new CActiveTimer();
813 test(myActiveTimer != NULL);
814 myActiveTimer->Delay(gTimeout*1000000);
816 CActiveConsole* myActiveConsole = new CActiveConsole();
817 test(myActiveConsole != NULL);
818 myActiveConsole->GetCharacter();
819 CActiveScheduler::Start();
822 PRINT (_L("gAbort TRUE \n"));
823 for (TInt i = 0; i < NumProcess; i++)
824 smpprocess[i].TerminateChildProcess();
827 gSMPStressDrv.Close();
835 void ParseCommandLine()
838 User::CommandLine(args);
840 PRINT ((_L("****Command line = %s\n"), args.PtrZ()));
844 TPtrC token=lex.NextToken();
845 if(token.Length()!=0)
847 if (token.Length()==0)
848 break; // ignore trailing whitespace
849 else if (token.Mid(0) == _L("-h"))
851 PRINT (_L("T_SMPSOAK.EXE Usage Options:\n"));
852 PRINT (_L("Type t_smpsoak.exe -h\n"));
857 else if (token.Mid(0) == _L("-l"))
859 //Read OOM entry from KProcessTable and run
860 test.Printf(_L("SMPSOAK:lowmem\n"));
861 NumProcess = KNumProcess+1;
864 else if (token.Mid(0) == _L("-b"))
866 test.Printf(_L("SMPSOAK: Test Silent Mode\n"));
867 ThreadPriorityLow = ETrue;
869 // If we have tests running in the background
870 // we want an endless loop
874 else if (token.Left(2) == _L("-t"))
876 test.Printf(_L("SMPSOAK:Timeout\n"));
877 lex.SkipSpaceAndMark();
878 token.Set(lex.NextToken());
880 lexNum.Val(gTimeout,EDecimal);
881 test.Printf(_L("Timeout in Seconds=%u \n"),gTimeout);
885 else if (token.Left(2) == _L("-p"))
887 test.Printf(_L("SMPSOAK:period\n"));
888 lex.SkipSpaceAndMark();
889 token.Set(lex.NextToken());
891 lexNum.Val(gPeriod,EDecimal);
892 test.Printf(_L("period in mSeconds=%d \n"),gPeriod);
898 test.Printf(_L("Error- Invalid SMPSOAK CMD Line Argument"));