First public contribution.
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_smpsoakprocess.cpp
17 #include "t_smpsoak.h"
25 //class for soak process and same executable(t_smpsoakprocess.exe) will be lauched with different process operation
26 //Example: IPC Read, IPC Write, File Process, Timer Process
32 void CreateThread(TPtrC aThreadType);
35 static TInt FileThread(TAny*);
36 static TInt TimerThread(TAny*);
37 static TInt MemoryThread(TAny*);
39 // Thread member functions
42 TInt DoMemoryThread();
43 void DoCreateThread(TAny*);
49 void SetThreadPriority();
50 //Utils for soak process
51 void SetSoakProcessPriority();
52 void CommitChunk(RChunk& aChunk, TInt aSize);
53 void ReadChunk(RChunk& aChunk, TInt aSize);
54 void WriteToChunk(RChunk& aChunk, TInt aSize);
55 void DeleteChunk(RChunk& aChunk);
58 static TThread KOOMemoryTable[];
59 static TThread KFileTable[];
60 static TThread KTimerTable[];
62 TThreadData iThreadData;
68 TThread CSMPSoakProcess::KOOMemoryTable[] =
70 { _L("SMPOOMemoryThread1"), CSMPSoakProcess::MemoryThread, {{EPriorityAbsoluteLowNormal, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, NULL,NULL}},
71 { _L("SMPOOMemoryThread2"), CSMPSoakProcess::MemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, NULL,NULL}},
72 { _L("SMPOOMemoryThread3"), CSMPSoakProcess::MemoryThread, {{EPriorityMore, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, NULL,NULL}},
73 { _L("SMPOOMemoryThread4"), CSMPSoakProcess::MemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, NULL,NULL}},
77 TThread CSMPSoakProcess::KFileTable[] =
79 { _L("SMPFileThread1"), CSMPSoakProcess::FileThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, 11, 5}},
80 { _L("SMPFileThread2"), CSMPSoakProcess::FileThread, {{EPriorityNormal, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, 22, 10}},
81 { _L("SMPFileThread3"), CSMPSoakProcess::FileThread, {{EPriorityMore, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, 33, 15}},
82 { _L("SMPFileThread4"), CSMPSoakProcess::FileThread, {{EPriorityAbsoluteVeryLow, EPriorityMore, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 0, 4, NULL, 44, 20}},
86 TThread CSMPSoakProcess::KTimerTable[] =
88 { _L("SMPTimerThread1"), CSMPSoakProcess::TimerThread, {{EPriorityAbsoluteLowNormal, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 1000, 2, NULL, NULL,NULL}},
89 { _L("SMPTimerThread2"), CSMPSoakProcess::TimerThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 1500, 2, NULL, NULL,NULL}},
92 CSMPSoakProcess::CSMPSoakProcess()
96 CSMPSoakProcess::~CSMPSoakProcess()
99 //Set the process priority each time for each process
100 void CSMPSoakProcess::SetSoakProcessPriority()
104 static TInt priorityindex = 0;
105 static const TProcessPriority priorityTable[]=
112 if(++priorityindex >= 4)
114 priority = priorityTable[priorityindex];
115 proc.SetPriority((TProcessPriority)priority);
116 PRINT((_L("Process Priority:%d \n"),proc.Priority()));
118 //Changes the thread priority each time time, for each thread by Random, Increment, from List, Fixed.
119 //pick up the priority option from thread table
120 void CSMPSoakProcess::SetThreadPriority()
122 static TInt64 randSeed = KRandSeed;
123 static const TThreadPriority priorityTable[]=
125 EPriorityMuchLess, EPriorityLess, EPriorityNormal, EPriorityMore, EPriorityMuchMore,
126 EPriorityRealTime, EPriorityRealTime, EPriorityAbsoluteVeryLow, EPriorityAbsoluteLowNormal,
127 EPriorityAbsoluteLow, EPriorityAbsoluteBackgroundNormal, EPriorityAbsoluteBackground,
128 EPriorityAbsoluteForegroundNormal, EPriorityAbsoluteForeground, EPriorityAbsoluteHighNormal, EPriorityAbsoluteHigh
130 TInt priorityIndex = 0;
131 switch (iThreadData.threadPriorityChange)
137 if (++iPriority >= KPriorityOrder)
139 if (iThreadData.threadPriorities[iPriority] == 0)
141 // PRINT(_L("SetPriority List CPU %d index %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread),iPriority, iThreadData.threadPriorities[iPriority]);
142 iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[iPriority]);
145 case EPriorityIncrement:
146 while (priorityTable[priorityIndex] <= iPriority)
150 iPriority = priorityTable[priorityIndex];
151 if (iPriority > iThreadData.threadPriorities[2])
152 iPriority = iThreadData.threadPriorities[1];
153 // PRINT(_L("SetPriority Increment CPU %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
154 iThread.SetPriority((TThreadPriority)iPriority);
157 case EPriorityRandom:
158 iPriority = Math::Rand(randSeed) % (iThreadData.threadPriorities[2] - iThreadData.threadPriorities[1] + 1);
159 iPriority += iThreadData.threadPriorities[1];
160 while (priorityTable[priorityIndex] < iPriority)
164 iPriority = priorityTable[priorityIndex];
165 // PRINT(_L("SetPriority Random CPU %d iPriority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
166 iThread.SetPriority((TThreadPriority)iPriority);
171 void CSMPSoakProcess::ResumeThread()
175 // CSMPSoakProcess Thread Creation.
176 // @param aThread thread table data
177 void CSMPSoakProcess::DoCreateThread(TAny* aThread)
179 //Initialize each thread data
180 iThreadData = ((TThread*)aThread)->threadData;
181 test.Next(_L("Create Thread"));
182 PRINT ((_L("%s CPU affinity %d Priority %d\n"),((TThread*)aThread)->threadName.Ptr(),iThreadData.cpuAffinity,iThreadData.threadPriorities[0]));
183 TInt r = iThread.Create(((TThread*)aThread)->threadName, ((TThread*)aThread)->threadFunction, KDefaultStackSize, KHeapMinSize, KHeapMaxSize,(TAny*)this);
185 if (iThreadData.threadPriorityChange == EPriorityList)
191 iPriority = iThreadData.threadPriorities[0];
193 iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[0]);
194 //Set the thread CPU Affinity
195 gSMPStressDrv.ChangeThreadAffinity(&iThread, iThreadData.cpuAffinity);
197 //Commit the chunk with aSize
198 void CSMPSoakProcess::CommitChunk(RChunk& aChunk, TInt aSize)
200 //PRINT ((_L("Commit Chunk \n")));
201 test_KErrNone(aChunk.Adjust(aSize));
203 //Write some data into the chunk
204 void CSMPSoakProcess::WriteToChunk(RChunk& aChunk, TInt aSize)
206 TUint8 *writeaddr = aChunk.Base();
207 TPtr8 write(writeaddr,aSize);
208 write.Fill('S',aSize);
211 //Read the data from chunk and verify
212 void CSMPSoakProcess::ReadChunk(RChunk& aChunk, TInt aSize)
214 TUint8 *readaddr = aChunk.Base();
215 TPtr8 read(readaddr,aSize);
216 test_KErrNone(read.Compare(memData));
219 void CSMPSoakProcess::DeleteChunk(RChunk& aChunk)
221 test_KErrNone(aChunk.Adjust(0));
224 void CSMPSoakProcess::ReadProcess()
226 RTest test(_L("SMPSoakReadProcess"));
229 // SetSoakProcessPriority();
230 gWriteSem.Wait(); //Wait for write completion
231 PRINT((_L("Read Chunk\n")));
232 ReadChunk( gChunk,KChunkSize);
233 PRINT((_L("Delete Chunk\n")));
235 gReadSem.Signal(); //Read completion
238 //IPC Write operation
239 void CSMPSoakProcess::WriteProcess()
241 RTest test(_L("SMPSoakWriteProcess"));
244 // SetSoakProcessPriority();
245 CommitChunk( gChunk, KChunkSize);
246 PRINT((_L("Write To Chunk\n")));
247 WriteToChunk( gChunk,KChunkSize);
248 gWriteSem.Signal(); //Write completion
249 gReadSem.Wait(); //Wait for read completion
252 //File Thread - creates Dir's, Files, Fileread, Filewrite and verify
253 //param aSoakThread - CSMPSoakUtil pointer
254 TInt CSMPSoakProcess::FileThread(TAny* aSoakThread)
256 CSMPSoakProcess* self = (CSMPSoakProcess*)aSoakThread;
257 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakProcess::TimerThread Panic"),0));
258 return self->DoFileThread();
261 TInt CSMPSoakProcess::DoFileThread()
263 RTest test(_L("SMPFileThread"));
266 TFileName sessionPath;
267 TBuf8<KFileNameLength> fileData;
268 fileData.Copy(KFileData);
272 TBuf<KFileNameLength> filename;
273 TBuf<KFileNameLength> directory;
274 TBuf<KFileNameLength> tempdir;
276 //Setup Dir structure
277 tempdir.Format(KDir,iThreadData.dirID);
278 test_KErrNone(fs.Connect());
279 sessionPath=KSessionPath;
282 //Setup Drive and Session
283 test_KErrNone(fs.DriveToChar(EDriveD,driveLetter));
284 sessionPath[0]=(TText)driveLetter;
285 test_KErrNone(fs.SetSessionPath(sessionPath));
286 test.Printf(_L("SessionPath=%S\n"),&sessionPath);
287 directory=sessionPath;
288 directory.Append(tempdir);
289 PRINT((_L("Dir Level =%S Creation\n"),&directory));
293 r= fs.MkDirAll(directory);
294 test(r == KErrNone || r == KErrAlreadyExists);
296 //Create Number of files then write data into it.
297 for (TInt i = 0; i < iThreadData.numFile; i++)
299 filename.Format(KFile,iThreadData.dirID,i);
300 PRINT((_L("File = %S Write\n"),&filename));
301 test_KErrNone(file.Create(fs,filename,EFileWrite));
302 test_KErrNone(file.Write(fileData));
306 //Read those files and verify it
307 for (TInt i = 0; i < iThreadData.numFile; i++)
309 TBuf8<KFileNameLength> readData;
310 filename.Format(KFile,iThreadData.dirID,i);
311 PRINT((_L("File = %S Read/Verify\n"),&filename));
312 test_KErrNone(file.Open(fs,filename,EFileRead));
313 test_KErrNone(file.Read(readData));
314 test_KErrNone(readData.Compare(fileData));
319 for (TInt i = 0; i < iThreadData.numFile; i++)
321 filename.Format(KFile,iThreadData.dirID,i);
322 PRINT((_L("File = %S Delete\n"),&filename));
323 test_KErrNone(fs.Delete(filename));
327 PRINT((_L("Dir Level =%S Removed\n"),&directory));
328 test_KErrNone(fs.RmDir(directory));
332 User::After(gPeriod);
337 //Timer Thread - produces DFC's in the kernel side
338 //param aSoakThread - CSMPSoakUtil pointer
339 TInt CSMPSoakProcess::TimerThread(TAny* aSoakThread)
341 CSMPSoakProcess* self = (CSMPSoakProcess*)aSoakThread;
342 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakProcess::TimerThread Panic"),0));
343 return self->DoTimerThread();
346 TInt CSMPSoakProcess::DoTimerThread()
348 RTest test(_L("SMPSoakTimerThread"));
351 test_KErrNone(timer.CreateLocal());
352 TRequestStatus status;
356 timer.After(status, iThreadData.delayTime*1000);
357 User::WaitForRequest(status);
358 test(status == KErrNone);
363 User::After(gPeriod);
370 //OOM Thread - produces out of memory condition on SMP threads run on different cpu cores
371 //param aSoakThread - this pointer
372 TInt CSMPSoakProcess::MemoryThread(TAny* aSoakThread)
374 CSMPSoakProcess* self = (CSMPSoakProcess*)aSoakThread;
375 __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakProcess::MemoryThread Panic"),0));
376 return self->DoMemoryThread();
378 //Memory thread member
379 TInt CSMPSoakProcess::DoMemoryThread()
381 RTest test(_L("SMPOOMemoryThread"));
383 static TInt memOKCount =0;
384 TAny* oomheap = NULL;
387 //Reserve the memory in heap
389 heap = UserHeap::ChunkHeap(NULL, KHeapMinSize, KHeapMaxiSize);
391 //Keep produce OOM condition and inform to other threads (run on different CPU cores)
394 TInt allocsize = KHeapMaxiSize - KHeapReserveSize;
396 if(memOKCount == iThreadData.numThreads-1)
397 allocsize = KHeapMaxiSize;
400 oomheap = heap->Alloc(allocsize);
403 PRINT(_L("Out Of Memory\n"));
405 PRINT(_L("Recover Back Memory\n"));
407 ooMemSem.Signal(iThreadData.numThreads - 1);
412 PRINT((_L("%d:Here MemOK\n"),memOKCount));
415 //Change Thread Priority
419 User::After(gPeriod);
426 void CSMPSoakProcess::CreateThread(TPtrC aThreadType)
428 if (aThreadType == _L("-W"))
430 CSMPSoakProcess smpipcwrite;
431 smpipcwrite.WriteProcess();
433 else if (aThreadType == _L("-R"))
435 CSMPSoakProcess smpipcread;
436 smpipcread.ReadProcess();
438 else if (aThreadType == _L("-F"))
440 CSMPSoakProcess smpfilethread[KNumFileThreads];
441 for (TInt i = 0; i < KNumFileThreads; i++)
442 smpfilethread[i].DoCreateThread(&KFileTable[i]);
443 for (TInt i = 0; i < KNumFileThreads; i++)
444 smpfilethread[i].ResumeThread();
446 else if (aThreadType == _L("-T"))
448 CSMPSoakProcess smptimerthread[KNumTimerThreads];
449 for (TInt i = 0; i < KNumTimerThreads; i++)
450 smptimerthread[i].DoCreateThread(&KTimerTable[i]);
451 for (TInt i = 0; i < KNumTimerThreads; i++)
452 smptimerthread[i].ResumeThread();
454 else if (aThreadType == _L("-O"))
456 CSMPSoakProcess smpoomthread[KNumOOMThreads];
457 for (TInt i = 0; i < KNumOOMThreads; i++)
458 smpoomthread[i].DoCreateThread(&KOOMemoryTable[i]);
459 for (TInt i = 0; i < KNumOOMThreads; i++)
460 smpoomthread[i].ResumeThread();
464 test.Printf(_L("Invalid Argument for Soak Process \n"));
468 //Command line arg to launch operation specific process
472 User::CommandLine(cmd);
474 PRINT ((_L("Command for Process = %s\n"), cmd.PtrZ()));
475 CSMPSoakProcess smpp;
478 TPtrC token=lex.NextToken();
479 if(token.Length()!=0)
481 if (token.Length()==0)
482 break; // ignore trailing whitespace
483 else if (token.Mid(0) == _L("-b"))
485 test.Printf(_L("SMPSOAKPROCESS: Silent Mode\n"));
487 lex.SkipSpaceAndMark();
488 token.Set(lex.NextToken());
489 test.Printf(_L("-b Thread Type = %s\n"), token.Ptr());
490 smpp.CreateThread(token);
493 else if (token.Left(2) == _L("-p"))
495 test.Printf(_L("SMPSOAKPROCESS: period\n"));
496 lex.SkipSpaceAndMark();
497 token.Set(lex.NextToken());
499 lexNum.Val(gPeriod,EDecimal);
500 test.Printf(_L("SMPSOAKPROCESS:period in mSeconds=%d \n"),gPeriod);
501 token.Set(lex.NextToken());
502 test.Printf(_L("-p Thread Type = %s\n"), token.Ptr());
503 smpp.CreateThread(token);
508 test.Printf(_L("-d Thread Type = %s\n"), token.Ptr());
509 smpp.CreateThread(token);
516 // Child process called by (T_SMPSOAK) Main Process
521 test.Start(_L("t_SMPSoakProcess.exe"));
522 test.Next(_L("Load device driver"));
523 TInt r = User::LoadLogicalDevice(_L("d_smpsoak.ldd"));
524 if (r == KErrNotFound)
526 PRINT (_L("Test not supported on this platform because the D_SMPSOAK.LDD Driver is Not Present\n"));
530 PRINT (_L("Calling SMPStressDrv.Open\n"));
531 r = gSMPStressDrv.Open();
534 PRINT (_L("Create/Open Global Write Semaphores\n"));
535 r = gWriteSem.CreateGlobal(KGlobalWriteSem,0);
536 if (r==KErrAlreadyExists)
538 r = gWriteSem.OpenGlobal(KGlobalWriteSem);
542 PRINT ((_L("Error- OpenGlobal Write Semaphore:%d\n"),r));
546 PRINT (_L("Create/Open Global Read Semaphores\n"));
547 r = gReadSem.CreateGlobal(KGlobalReadSem,0);
548 if (r==KErrAlreadyExists)
550 r = gReadSem.OpenGlobal(KGlobalReadSem);
554 PRINT( (_L("Error- OpenGlobal Read Semaphore:%d\n"),r));
558 PRINT (_L("Creating Global Chunk\n"));
559 r = gChunk.CreateGlobal(KGlobalWRChunk,KChunkSize,KChunkMaxSize);
560 if(r==KErrAlreadyExists)
562 test_KErrNone( gChunk.OpenGlobal(KGlobalWRChunk,EFalse));
565 PRINT (_L("Creating local OOM Memory semaphore\n"));
566 r=ooMemSem.CreateLocal(0);
569 PRINT ((_L("Error- Creating local OOM Memory semaphore:%d\n"),r));
575 CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
576 test(myScheduler != NULL);
577 CActiveScheduler::Install(myScheduler);
578 CActiveScheduler::Start();
584 gSMPStressDrv.Close();
585 CActiveScheduler::Stop();