os/kernelhwsrv/kerneltest/e32test/smpsoak/t_smpsoak.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\smpsoak\t_smpsoak.cpp
sl@0
    15
sl@0
    16
//  User Includes
sl@0
    17
#include <e32hal.h>
sl@0
    18
#include "t_smpsoak.h"
sl@0
    19
sl@0
    20
void ParseCommandLine ();
sl@0
    21
sl@0
    22
// Global Variables
sl@0
    23
static TInt gPageSize;
sl@0
    24
//Timeout 2 Minutes
sl@0
    25
static TUint gTimeout = 120;
sl@0
    26
sl@0
    27
//class for smpsoak thread and it creates memory, device, timer and spin threads.
sl@0
    28
class CSMPSoakThread
sl@0
    29
	{
sl@0
    30
public:
sl@0
    31
	CSMPSoakThread();
sl@0
    32
	~CSMPSoakThread();
sl@0
    33
	void CreateThread();
sl@0
    34
	void ResumeThread();
sl@0
    35
	void CreateChildProcess(TInt aIndex);
sl@0
    36
	void ResumeChildProcess();
sl@0
    37
	void TerminateChildProcess();	
sl@0
    38
private:
sl@0
    39
    //Thread Functions
sl@0
    40
	static TInt SMPStressMemoryThread(TAny*);
sl@0
    41
	static TInt SMPStressDeviceThread(TAny*);
sl@0
    42
	static TInt SMPStressTimerThread(TAny*);
sl@0
    43
	static TInt SMPStressSpinThread(TAny*);
sl@0
    44
	//Thread Priority
sl@0
    45
	void DoCreateThread(TAny*);
sl@0
    46
	void SetThreadPriority();
sl@0
    47
private:
sl@0
    48
    //Utils for memory thread
sl@0
    49
	void CreateChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
sl@0
    50
	void CommitChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
sl@0
    51
	void WriteReadChunk(TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr);
sl@0
    52
private:
sl@0
    53
    //Memebers for threads 
sl@0
    54
    TInt DoSMPStressMemoryThread();
sl@0
    55
    TInt DoSMPStressDeviceThread();
sl@0
    56
    TInt DoSMPStressTimerThread();
sl@0
    57
    TInt DoSMPStressSpinThread();
sl@0
    58
private:
sl@0
    59
    TThreadData iThreadData;
sl@0
    60
    RProcess    iProcess;
sl@0
    61
    RThread     iThread;
sl@0
    62
    TInt        iPriority;
sl@0
    63
private:
sl@0
    64
// Thread Data for each thread- low priority
sl@0
    65
static TThread KThreadTableLow[];
sl@0
    66
// Thread Data for each thread- high priority
sl@0
    67
static TThread KThreadTableHigh[];
sl@0
    68
//Process Data for each process
sl@0
    69
static const TProcess KProcessTable[];
sl@0
    70
//Memory table for memory thread
sl@0
    71
static const TMemory KMemoryTable[];
sl@0
    72
//Device table for device thread
sl@0
    73
static const TDesC* KDeviceTable[];
sl@0
    74
sl@0
    75
	};
sl@0
    76
TThread CSMPSoakThread::KThreadTableLow[] =
sl@0
    77
    {
sl@0
    78
        { _L("Memory Thread"), CSMPSoakThread::SMPStressMemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow,   EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 250, 1, (TAny *)&KMemoryTable, NULL, NULL}},
sl@0
    79
		{ _L("Device Thread"), CSMPSoakThread::SMPStressDeviceThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 300, 1, &KDeviceTable, NULL, NULL}},
sl@0
    80
		{ _L("Spin Thread 0"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityAbsoluteVeryLow, EPriorityNormal,   EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 200, 0, NULL, NULL, NULL}},
sl@0
    81
		{ _L("Spin Thread 1"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityAbsoluteVeryLow,   EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 300, 0, NULL, NULL, NULL}},
sl@0
    82
		{ _L("Spin Thread 2"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal,   EPriorityAbsoluteVeryLow, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 400, 0, NULL, NULL, NULL}},
sl@0
    83
		{ _L("Spin Thread 3"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal,   EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow}, EPriorityList, KCpuAffinityAny, 500, 0, NULL, NULL, NULL}},
sl@0
    84
		{ _L("Timer Thread"), CSMPSoakThread::SMPStressTimerThread, {{EPriorityNormal, 0, 0, 0}, EPriorityList, KCpuAffinityAny, 1000, 4, NULL}},
sl@0
    85
    };
sl@0
    86
TThread CSMPSoakThread::KThreadTableHigh[] =
sl@0
    87
 {
sl@0
    88
        { _L("Memory Thread"), CSMPSoakThread::SMPStressMemoryThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow,   EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 250, 1, (TAny *)&KMemoryTable, NULL, NULL}},
sl@0
    89
        { _L("Device Thread"), CSMPSoakThread::SMPStressDeviceThread, {{EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow, EPriorityNormal, 0}, EPriorityList, KCpuAffinityAny, 300, 1, &KDeviceTable, NULL, NULL}},
sl@0
    90
        { _L("Spin Thread 0"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityAbsoluteVeryLow, EPriorityNormal,   EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 200, 0, NULL, NULL, NULL}},
sl@0
    91
        { _L("Spin Thread 1"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityAbsoluteVeryLow,   EPriorityNormal, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 300, 0, NULL, NULL, NULL}},
sl@0
    92
        { _L("Spin Thread 2"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal,   EPriorityAbsoluteVeryLow, EPriorityNormal}, EPriorityList, KCpuAffinityAny, 400, 0, NULL, NULL, NULL}},
sl@0
    93
        { _L("Spin Thread 3"), CSMPSoakThread::SMPStressSpinThread, {{EPriorityNormal, EPriorityNormal,   EPriorityAbsoluteLow, EPriorityAbsoluteVeryLow}, EPriorityList, KCpuAffinityAny, 500, 0, NULL, NULL, NULL}},
sl@0
    94
        { _L("Timer Thread"), CSMPSoakThread::SMPStressTimerThread, {{EPriorityNormal, 0, 0, 0}, EPriorityList, KCpuAffinityAny, 1000, 4, NULL}},
sl@0
    95
    };
sl@0
    96
const TProcess CSMPSoakThread::KProcessTable[] =
sl@0
    97
    {
sl@0
    98
        { _L("t_smpsoakprocess.exe"), _L("-W"), KCpuAffinityAny},
sl@0
    99
        { _L("t_smpsoakprocess.exe"), _L("-R"), KCpuAffinityAny},
sl@0
   100
        { _L("t_smpsoakprocess.exe"), _L("-F"), KCpuAffinityAny},
sl@0
   101
        { _L("t_smpsoakprocess.exe"), _L("-T"), KCpuAffinityAny},
sl@0
   102
        { _L("t_smpsoakprocess.exe"), _L("-O"), KCpuAffinityAny},
sl@0
   103
    };
sl@0
   104
const TMemory CSMPSoakThread::KMemoryTable[] =
sl@0
   105
    {
sl@0
   106
        {_L(""), EChunkNormalThread, 0, 10, 100 },
sl@0
   107
        {_L("Global Chunk 1"), EChunkNormalThread, 0, 20, 200 },
sl@0
   108
        {_L(""), EChunkDisconnectedThread, 3, 30, 300 },
sl@0
   109
        {_L("Global Chunk 2"), EChunkDisconnectedThread, 4, 40, 400 },
sl@0
   110
        {_L(""), EChunkDoubleEndedThread, 5, 50, 500 },
sl@0
   111
        {_L("Global Chunk 3"), EChunkDoubleEndedThread, 6, 60, 600 },
sl@0
   112
        {_L(""), EChunkNormalProcess, 0, 10, 100 },
sl@0
   113
        {_L("Global Chunk 4"), EChunkNormalProcess, 0, 20, 200 },
sl@0
   114
        {_L(""), EChunkDisconnectedProcess, 3, 30, 300 },
sl@0
   115
        {_L("Global Chunk 5"), EChunkDisconnectedProcess, 4, 40, 400 },
sl@0
   116
        {_L(""), EChunkDoubleEndedProcess, 5, 50, 500 },
sl@0
   117
        {_L("Global Chunk 6"), EChunkDoubleEndedProcess, 6, 60, 600 },
sl@0
   118
        {_L(""), EChunkNone, 0, 0, 0 },
sl@0
   119
    };
sl@0
   120
const TDesC* CSMPSoakThread::KDeviceTable[] =
sl@0
   121
    {
sl@0
   122
    &KDevices, &KDevLdd1, &KDevLdd1Name, &KDevLdd2, &KDevLdd2Name, &KDevLdd3, &KDevLdd3Name,
sl@0
   123
    &KDevLdd4, &KDevLdd4Name, &KDevLdd5, &KDevLdd5Name, NULL
sl@0
   124
    };
sl@0
   125
sl@0
   126
//Constructor
sl@0
   127
CSMPSoakThread::CSMPSoakThread()
sl@0
   128
    { 
sl@0
   129
    }
sl@0
   130
//Destructor
sl@0
   131
CSMPSoakThread::~CSMPSoakThread()
sl@0
   132
    {    
sl@0
   133
    }
sl@0
   134
//All child process creation
sl@0
   135
void CSMPSoakThread::CreateChildProcess(TInt aIndex)
sl@0
   136
    {
sl@0
   137
    if(TestSilent)  
sl@0
   138
            gCmdLine.Format(KCmdLineBackground,(KProcessTable[aIndex].operation).Ptr());
sl@0
   139
    else if (Period)
sl@0
   140
        gCmdLine.Format(KCmdLinePeriod,gPeriod,(KProcessTable[aIndex].operation).Ptr());
sl@0
   141
    else
sl@0
   142
        gCmdLine.Format(KCmdLineProcess,(KProcessTable[aIndex].operation).Ptr());
sl@0
   143
    
sl@0
   144
    TInt r = iProcess.Create(KProcessTable[aIndex].processFileName,gCmdLine);
sl@0
   145
    test_KErrNone(r);
sl@0
   146
    iProcess.SetPriority(EPriorityLow);
sl@0
   147
    gSMPStressDrv.ChangeThreadAffinity(&iThread, KProcessTable[aIndex].cpuAffinity);
sl@0
   148
    PRINT ((_L("SetProcessPriority  CPU %d Priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iProcess.Priority()));
sl@0
   149
    }
sl@0
   150
//Terminate process when user press "Esc key"
sl@0
   151
void CSMPSoakThread::ResumeChildProcess()
sl@0
   152
    {
sl@0
   153
    iProcess.Resume();
sl@0
   154
    }
sl@0
   155
//Terminate process when user press "Esc key"
sl@0
   156
void CSMPSoakThread::TerminateChildProcess()
sl@0
   157
    {
sl@0
   158
    iProcess.Kill(KErrNone);
sl@0
   159
    }
sl@0
   160
//Changes the thread priority each time time, for each thread by Random, Increment, from List, Fixed.
sl@0
   161
//pick up the priority option from thread table
sl@0
   162
void CSMPSoakThread::SetThreadPriority()
sl@0
   163
    {
sl@0
   164
    static TInt64 randSeed = KRandSeed;
sl@0
   165
    static const TThreadPriority priorityTable[]=
sl@0
   166
        {
sl@0
   167
        EPriorityMuchLess, EPriorityLess, EPriorityNormal, EPriorityMore, EPriorityMuchMore,
sl@0
   168
        EPriorityRealTime, EPriorityRealTime, EPriorityAbsoluteVeryLow, EPriorityAbsoluteLowNormal,
sl@0
   169
        EPriorityAbsoluteLow, EPriorityAbsoluteBackgroundNormal, EPriorityAbsoluteBackground,
sl@0
   170
        EPriorityAbsoluteForegroundNormal, EPriorityAbsoluteForeground, EPriorityAbsoluteHighNormal, EPriorityAbsoluteHigh
sl@0
   171
        };
sl@0
   172
    TInt priorityIndex = 0;
sl@0
   173
    switch (iThreadData.threadPriorityChange)
sl@0
   174
        {
sl@0
   175
        case EpriorityFixed:
sl@0
   176
            break;
sl@0
   177
sl@0
   178
        case EPriorityList:
sl@0
   179
            if (++iPriority >= KPriorityOrder)
sl@0
   180
                iPriority = 0;
sl@0
   181
            if (iThreadData.threadPriorities[iPriority] == 0)
sl@0
   182
                iPriority = 0;
sl@0
   183
          //  PRINT(_L("SetPriority List CPU %d index %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread),iPriority, iThreadData.threadPriorities[iPriority]);
sl@0
   184
            iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[iPriority]);
sl@0
   185
            break;
sl@0
   186
sl@0
   187
        case EPriorityIncrement:
sl@0
   188
            while (priorityTable[priorityIndex] <= iPriority)
sl@0
   189
                {
sl@0
   190
                priorityIndex++;
sl@0
   191
                }
sl@0
   192
            iPriority = priorityTable[priorityIndex];
sl@0
   193
            if (iPriority > iThreadData.threadPriorities[2])
sl@0
   194
                iPriority = iThreadData.threadPriorities[1];
sl@0
   195
          //  PRINT(_L("SetPriority Increment CPU %d iPriority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
sl@0
   196
            iThread.SetPriority((TThreadPriority)iPriority);
sl@0
   197
            break;
sl@0
   198
sl@0
   199
        case EPriorityRandom:
sl@0
   200
            iPriority = Math::Rand(randSeed) % (iThreadData.threadPriorities[2] - iThreadData.threadPriorities[1] + 1);
sl@0
   201
            iPriority += iThreadData.threadPriorities[1];
sl@0
   202
            while (priorityTable[priorityIndex] < iPriority)
sl@0
   203
                {
sl@0
   204
                priorityIndex++;
sl@0
   205
                }
sl@0
   206
            iPriority = priorityTable[priorityIndex];
sl@0
   207
         //   PRINT(_L("SetPriority Random CPU %d priority %d\n"),gSMPStressDrv.GetThreadCPU(&iThread), iPriority);
sl@0
   208
            iThread.SetPriority((TThreadPriority)iPriority);
sl@0
   209
            break;
sl@0
   210
        }
sl@0
   211
    }
sl@0
   212
//Resume each thread
sl@0
   213
void CSMPSoakThread::ResumeThread()
sl@0
   214
    {
sl@0
   215
    iThread.Resume();
sl@0
   216
    }
sl@0
   217
//thread creation
sl@0
   218
void CSMPSoakThread::CreateThread()
sl@0
   219
    {
sl@0
   220
    CSMPSoakThread* smpthread = new CSMPSoakThread[KNumThreads];
sl@0
   221
    for (TInt i = 0; i < KNumThreads ; i++)
sl@0
   222
        {
sl@0
   223
        if(ThreadPriorityLow)
sl@0
   224
            {
sl@0
   225
            PRINT ((_L("Thread Table - Priority Low \n")));
sl@0
   226
            smpthread[i].DoCreateThread(&KThreadTableLow[i]);
sl@0
   227
            }
sl@0
   228
        else
sl@0
   229
            {
sl@0
   230
            PRINT ((_L("Thread Table - Priority High \n")));
sl@0
   231
            smpthread[i].DoCreateThread(&KThreadTableHigh[i]);
sl@0
   232
            }
sl@0
   233
        }
sl@0
   234
    PRINT (_L("Resuming all threads\n"));
sl@0
   235
    for (TInt i = 0; i < KNumThreads; i++)
sl@0
   236
           smpthread[i].ResumeThread();
sl@0
   237
    }
sl@0
   238
/**
sl@0
   239
 * CSMPSoakThread Thread Creation.
sl@0
   240
 * @param aIndex to exercise each row(thread) in the thread table          
sl@0
   241
 *
sl@0
   242
 * @return  N/A
sl@0
   243
 *
sl@0
   244
 * @pre     Initialize thread Table values
sl@0
   245
 * @post    None
sl@0
   246
 */
sl@0
   247
void CSMPSoakThread::DoCreateThread(TAny* aThread)
sl@0
   248
    {
sl@0
   249
    //Initialize each thread data
sl@0
   250
       iThreadData = ((TThread*)aThread)->threadData;
sl@0
   251
       test.Next(_L("Create Thread"));
sl@0
   252
       PRINT ((_L("%s   CPU affinity %d  Priority %d\n"),((TThread*)aThread)->threadName.Ptr(),iThreadData.cpuAffinity,iThreadData.threadPriorities[0]));
sl@0
   253
       TInt r = iThread.Create(((TThread*)aThread)->threadName, ((TThread*)aThread)->threadFunction, KDefaultStackSize, KHeapMinSize, KHeapMaxSize,(TAny*)this);
sl@0
   254
       test_KErrNone(r);
sl@0
   255
       if (iThreadData.threadPriorityChange == EPriorityList)
sl@0
   256
           {
sl@0
   257
           iPriority = 0;
sl@0
   258
           }
sl@0
   259
       else
sl@0
   260
           {
sl@0
   261
           iPriority = iThreadData.threadPriorities[0];
sl@0
   262
           }
sl@0
   263
       iThread.SetPriority((TThreadPriority)iThreadData.threadPriorities[0]);
sl@0
   264
       //Set the thread CPU Affinity
sl@0
   265
       gSMPStressDrv.ChangeThreadAffinity(&iThread, iThreadData.cpuAffinity);
sl@0
   266
      }
sl@0
   267
//Create Chunk - different types 
sl@0
   268
void CSMPSoakThread::CreateChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
sl@0
   269
	{
sl@0
   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);
sl@0
   271
	TOwnerType ownerType = EOwnerProcess;
sl@0
   272
	aChunkInfo->lastBottom = aMemoryTablePtr->initialBottom;
sl@0
   273
	aChunkInfo->lastTop = aMemoryTablePtr->initialTop;
sl@0
   274
	switch (aMemoryTablePtr->chunkType)
sl@0
   275
		{
sl@0
   276
		case EChunkNormalThread:
sl@0
   277
			ownerType = EOwnerThread;			// drop through to create chunk
sl@0
   278
		case EChunkNormalProcess:
sl@0
   279
			if (aMemoryTablePtr->globalChunkName.Length())
sl@0
   280
				{
sl@0
   281
				test_KErrNone(aChunkInfo->chunk.CreateGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   282
				}
sl@0
   283
			else
sl@0
   284
				{
sl@0
   285
				test_KErrNone(aChunkInfo->chunk.CreateLocal(aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   286
				}
sl@0
   287
			aChunkInfo->lastBottom = 0;			// ensure that this is zero
sl@0
   288
			break;
sl@0
   289
sl@0
   290
		case EChunkDisconnectedThread:
sl@0
   291
			ownerType = EOwnerThread;			// drop through to create chunk
sl@0
   292
		case EChunkDisconnectedProcess:
sl@0
   293
			if (aMemoryTablePtr->globalChunkName.Length())
sl@0
   294
				{
sl@0
   295
				test_KErrNone(aChunkInfo->chunk.CreateDisconnectedGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   296
				}
sl@0
   297
			else
sl@0
   298
				{
sl@0
   299
				test_KErrNone(aChunkInfo->chunk.CreateDisconnectedLocal(aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   300
				}
sl@0
   301
			break;
sl@0
   302
sl@0
   303
		case EChunkDoubleEndedThread:
sl@0
   304
			ownerType = EOwnerThread;			// drop through to create chunk
sl@0
   305
		case EChunkDoubleEndedProcess:
sl@0
   306
			if (aMemoryTablePtr->globalChunkName.Length())
sl@0
   307
				{
sl@0
   308
				test_KErrNone(aChunkInfo->chunk.CreateDoubleEndedGlobal(aMemoryTablePtr->globalChunkName,aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   309
				}
sl@0
   310
			else
sl@0
   311
				{
sl@0
   312
				test_KErrNone(aChunkInfo->chunk.CreateDoubleEndedLocal(aMemoryTablePtr->initialBottom*gPageSize,aMemoryTablePtr->initialTop*gPageSize,aMemoryTablePtr->maxSize*gPageSize,ownerType));
sl@0
   313
				}
sl@0
   314
			break;
sl@0
   315
		}
sl@0
   316
	}
sl@0
   317
//Commit chunk
sl@0
   318
void CSMPSoakThread::CommitChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
sl@0
   319
	{
sl@0
   320
	TInt commitPages;
sl@0
   321
sl@0
   322
	switch (aMemoryTablePtr->chunkType)
sl@0
   323
		{
sl@0
   324
		case EChunkNormalThread:
sl@0
   325
		case EChunkNormalProcess:
sl@0
   326
			if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
sl@0
   327
				{
sl@0
   328
				aChunkInfo->lastTop += (aMemoryTablePtr->maxSize - 1 - aChunkInfo->lastTop) / 2 + 1;
sl@0
   329
				//PRINT(_L("Adjust chunk memory - top %d pagesize %d\n"),aChunkInfo->lastTop,gPageSize);
sl@0
   330
				test_KErrNone(aChunkInfo->chunk.Adjust(aChunkInfo->lastTop*gPageSize));
sl@0
   331
				}
sl@0
   332
			break;
sl@0
   333
sl@0
   334
		case EChunkDisconnectedThread:
sl@0
   335
		case EChunkDisconnectedProcess:
sl@0
   336
			commitPages = ((aChunkInfo->lastTop - aChunkInfo->lastBottom) / 2) + 1;
sl@0
   337
			//PRINT(_L("Decommitting from bottom %d of %d pages\n"),aChunkInfo->lastBottom,commitPages);
sl@0
   338
			test_KErrNone(aChunkInfo->chunk.Decommit(aChunkInfo->lastBottom*gPageSize,commitPages * gPageSize));
sl@0
   339
			if ((aChunkInfo->lastBottom > 0) && (aChunkInfo->lastTop <= aMemoryTablePtr->initialTop))
sl@0
   340
				{
sl@0
   341
				aChunkInfo->lastTop = aChunkInfo->lastBottom + commitPages - 1;
sl@0
   342
				aChunkInfo->lastBottom /= 2;
sl@0
   343
				commitPages = aChunkInfo->lastTop - aChunkInfo->lastBottom + 1;
sl@0
   344
				}
sl@0
   345
			else
sl@0
   346
				{
sl@0
   347
				if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize -1))
sl@0
   348
					{
sl@0
   349
					if (aChunkInfo->lastTop <= aMemoryTablePtr->initialTop)
sl@0
   350
						{
sl@0
   351
						aChunkInfo->lastBottom = aMemoryTablePtr->initialTop + 1;
sl@0
   352
						}
sl@0
   353
					else
sl@0
   354
						{
sl@0
   355
						aChunkInfo->lastBottom = aChunkInfo->lastTop + 1;
sl@0
   356
						}
sl@0
   357
					commitPages = ((aMemoryTablePtr->maxSize - aChunkInfo->lastBottom) / 2) + 1;
sl@0
   358
					aChunkInfo->lastTop = aChunkInfo->lastBottom + commitPages - 1;
sl@0
   359
					}
sl@0
   360
				else
sl@0
   361
					{
sl@0
   362
					commitPages = 0;
sl@0
   363
					}
sl@0
   364
				}
sl@0
   365
			if (commitPages)
sl@0
   366
				{
sl@0
   367
				//PRINT(_L("Commit chunk memory bottom %d size %d pages\n"),aChunkInfo->lastBottom,commitPages);
sl@0
   368
				test_KErrNone(aChunkInfo->chunk.Commit(aChunkInfo->lastBottom*gPageSize,commitPages*gPageSize));
sl@0
   369
				}
sl@0
   370
		break;
sl@0
   371
sl@0
   372
		case EChunkDoubleEndedThread:
sl@0
   373
		case EChunkDoubleEndedProcess:
sl@0
   374
			if (aChunkInfo->lastBottom > 0 || aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
sl@0
   375
				{
sl@0
   376
				if (aChunkInfo->lastBottom > 0)
sl@0
   377
					{
sl@0
   378
					aChunkInfo->lastBottom--;
sl@0
   379
					}
sl@0
   380
				if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
sl@0
   381
					{
sl@0
   382
					aChunkInfo->lastTop++;
sl@0
   383
					}
sl@0
   384
			//	PRINT(_L("Adjust Double Ended bottom %d top %d\n"),aChunkInfo->lastBottom,aChunkInfo->lastTop);
sl@0
   385
				test_KErrNone(aChunkInfo->chunk.AdjustDoubleEnded(aChunkInfo->lastBottom*gPageSize,aChunkInfo->lastTop*gPageSize));
sl@0
   386
				}
sl@0
   387
			break;
sl@0
   388
		}
sl@0
   389
	}
sl@0
   390
//Write then read chunk
sl@0
   391
void CSMPSoakThread::WriteReadChunk (TChunkInfo * aChunkInfo, TMemory * aMemoryTablePtr)
sl@0
   392
	{
sl@0
   393
	if (aChunkInfo->lastTop < (aMemoryTablePtr->maxSize - 1))
sl@0
   394
		{
sl@0
   395
		TInt chunkSize = aChunkInfo->lastTop*gPageSize - aChunkInfo->lastBottom*gPageSize;
sl@0
   396
		//RDebug::Print(_L("WriteReadChunk Last Top %d lastBottom %d\n"),aChunkInfo->lastTop,aChunkInfo->lastBottom);
sl@0
   397
		TUint8 *writeaddr = aChunkInfo->chunk.Base()+ aChunkInfo->lastBottom*gPageSize;
sl@0
   398
		TPtr8 write(writeaddr,chunkSize);
sl@0
   399
		write.Copy(pattern,sizeof(pattern));
sl@0
   400
		test_KErrNone(Mem::Compare(writeaddr,sizeof(pattern),pattern,sizeof(pattern)));
sl@0
   401
		}
sl@0
   402
	}
sl@0
   403
//Memory Thread : will do memory associated operation
sl@0
   404
//param aSmp - CSMPSoakUtil pointer
sl@0
   405
TInt CSMPSoakThread::SMPStressMemoryThread(TAny* aSmp)
sl@0
   406
    {
sl@0
   407
    CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
sl@0
   408
     __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressMemoryThread Panic"),0));
sl@0
   409
    return self->DoSMPStressMemoryThread();
sl@0
   410
    }
sl@0
   411
// Member for thread function
sl@0
   412
TInt CSMPSoakThread::DoSMPStressMemoryThread()
sl@0
   413
	{
sl@0
   414
	RTest test(_L("SMPStressMemoryThread"));
sl@0
   415
	
sl@0
   416
	TMemory *memoryTablePtr;
sl@0
   417
	TChunkInfo chunkTable[KNumChunks];
sl@0
   418
	TInt ctIndex = 0;
sl@0
   419
	test_KErrNone(UserHal::PageSizeInBytes(gPageSize));
sl@0
   420
sl@0
   421
	FOREVER
sl@0
   422
		{
sl@0
   423
		SetThreadPriority();
sl@0
   424
sl@0
   425
		if (gAbort)
sl@0
   426
			break;
sl@0
   427
sl@0
   428
		memoryTablePtr = (TMemory *) (iThreadData.listPtr);
sl@0
   429
		ctIndex = 0;
sl@0
   430
		
sl@0
   431
		//Create different type of chunks and write/read/verfiy it
sl@0
   432
		while (memoryTablePtr->chunkType != EChunkNone)
sl@0
   433
			{
sl@0
   434
			PRINT((_L("Create Chunk")));
sl@0
   435
			CreateChunk (&chunkTable[ctIndex],memoryTablePtr);
sl@0
   436
sl@0
   437
			PRINT(_L("Write and Read Chunk"));
sl@0
   438
			WriteReadChunk (&chunkTable[ctIndex],memoryTablePtr);
sl@0
   439
sl@0
   440
			ctIndex++;
sl@0
   441
			memoryTablePtr++;
sl@0
   442
			}
sl@0
   443
		
sl@0
   444
		//Commit different type of chunks
sl@0
   445
		TBool anyCommit;
sl@0
   446
		do
sl@0
   447
			{
sl@0
   448
			anyCommit = EFalse;
sl@0
   449
			memoryTablePtr = (TMemory *) (iThreadData.listPtr);
sl@0
   450
			ctIndex = 0;
sl@0
   451
			while (memoryTablePtr->chunkType != EChunkNone)
sl@0
   452
				{
sl@0
   453
				//Commit Chunks
sl@0
   454
				PRINT((_L("Commit Chunk Memory")));
sl@0
   455
				PRINT ((_L("CommitChunk %d bottom %d top %d\n"),ctIndex,memoryTablePtr->initialBottom,memoryTablePtr->initialTop));
sl@0
   456
				CommitChunk (&chunkTable[ctIndex],memoryTablePtr);
sl@0
   457
				anyCommit = ETrue;
sl@0
   458
				
sl@0
   459
				//Write into Chunks
sl@0
   460
				WriteReadChunk (&chunkTable[ctIndex],memoryTablePtr);
sl@0
   461
				PRINT((_L("Write Read Chunk Size %d\n"), (memoryTablePtr->initialTop) - (memoryTablePtr->initialBottom)));
sl@0
   462
				ctIndex++;
sl@0
   463
				memoryTablePtr++;
sl@0
   464
				}
sl@0
   465
			}
sl@0
   466
		while (anyCommit);
sl@0
   467
		
sl@0
   468
		//Close the Chunks
sl@0
   469
		memoryTablePtr = (TMemory *) (iThreadData.listPtr);
sl@0
   470
		ctIndex = 0;
sl@0
   471
		while (memoryTablePtr->chunkType != EChunkNone)
sl@0
   472
			{
sl@0
   473
			chunkTable[ctIndex].chunk.Close();
sl@0
   474
sl@0
   475
			ctIndex++;
sl@0
   476
			memoryTablePtr++;
sl@0
   477
			}
sl@0
   478
		User::After(gPeriod);
sl@0
   479
		}
sl@0
   480
	return 0x00;
sl@0
   481
	}
sl@0
   482
//Device Thread : will do device associated operation
sl@0
   483
//param aSmp - CSMPSoakUtil pointer
sl@0
   484
TInt CSMPSoakThread::SMPStressDeviceThread(TAny* aSmp)
sl@0
   485
    {
sl@0
   486
    CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
sl@0
   487
     __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressDeviceThread Panic"),0));
sl@0
   488
    return self->DoSMPStressDeviceThread();
sl@0
   489
    }
sl@0
   490
// Member for thread function
sl@0
   491
TInt CSMPSoakThread::DoSMPStressDeviceThread()
sl@0
   492
	{
sl@0
   493
	RTest test(_L("SMPStressDeviceThread"));
sl@0
   494
	
sl@0
   495
	RTimer timer;
sl@0
   496
	RFs session;
sl@0
   497
	TFileName sessionPath;
sl@0
   498
sl@0
   499
	test_KErrNone(timer.CreateLocal());
sl@0
   500
	TRequestStatus s;
sl@0
   501
sl@0
   502
	TDesC** ptrDevices =  (TDesC**) (iThreadData.listPtr);
sl@0
   503
	PRINT ((_L("Devices  Number %d [%s]\n"), ptrDevices[0]->Length(), ptrDevices[0]->Ptr()));
sl@0
   504
	for (TInt i = 1; ptrDevices[i] ; i++)
sl@0
   505
		PRINT ((_L("LDD%d=%s "),i,ptrDevices[i]->Ptr()));
sl@0
   506
	PRINT (_L("\n"));
sl@0
   507
sl@0
   508
	FOREVER
sl@0
   509
		{
sl@0
   510
		for (TInt i = 0; i < ptrDevices[0]->Length(); i++)
sl@0
   511
			{
sl@0
   512
			TText driveLetter = (*ptrDevices[0])[i];
sl@0
   513
			PRINT ((_L("Device %c\n"),driveLetter));
sl@0
   514
sl@0
   515
			test_KErrNone(session.Connect());
sl@0
   516
sl@0
   517
			sessionPath=(_L("?:\\SESSION_TEST\\"));
sl@0
   518
			sessionPath[0]=driveLetter;
sl@0
   519
			test_KErrNone(session.SetSessionPath(sessionPath));
sl@0
   520
sl@0
   521
			TInt driveNumber;
sl@0
   522
			test_KErrNone(session.CharToDrive(driveLetter, driveNumber));
sl@0
   523
sl@0
   524
			TBuf<64> fileSystemName;
sl@0
   525
			test_KErrNone(session.FileSystemName(fileSystemName,driveNumber));
sl@0
   526
sl@0
   527
			PRINT ((_L("File System Name %s\n"),fileSystemName.PtrZ()));
sl@0
   528
sl@0
   529
			TDriveInfo driveInfo;
sl@0
   530
			test_KErrNone(session.Drive(driveInfo, driveNumber));
sl@0
   531
sl@0
   532
			TVolumeInfo volumeInfo;
sl@0
   533
			test_KErrNone(session.Volume(volumeInfo, driveNumber));
sl@0
   534
sl@0
   535
			session.Close();
sl@0
   536
			}
sl@0
   537
		for (TInt i = 1; ptrDevices[i] ; i += 2)
sl@0
   538
			{
sl@0
   539
			RDevice device;
sl@0
   540
sl@0
   541
			TInt r = User::LoadLogicalDevice(*ptrDevices[i]);
sl@0
   542
			test(r == KErrNone || r == KErrAlreadyExists);
sl@0
   543
sl@0
   544
			test_KErrNone(device.Open(*ptrDevices[i+1]));
sl@0
   545
sl@0
   546
			TBuf8<64> deviceCaps;
sl@0
   547
			device.GetCaps(deviceCaps);
sl@0
   548
sl@0
   549
			TVersion deviceVersion;
sl@0
   550
			device.QueryVersionSupported(deviceVersion);
sl@0
   551
sl@0
   552
			device.Close();
sl@0
   553
			}
sl@0
   554
		SetThreadPriority();
sl@0
   555
		timer.After(s, iThreadData.delayTime*1000);
sl@0
   556
		User::WaitForRequest(s);
sl@0
   557
		test (s == KErrNone);
sl@0
   558
sl@0
   559
		if (gAbort)
sl@0
   560
			break;
sl@0
   561
		User::After(gPeriod);
sl@0
   562
		}
sl@0
   563
	timer.Close();
sl@0
   564
	PRINT((_L("SMPStressDeviceThread MyTimer.Cancel() called\n")));
sl@0
   565
	return 0x00;
sl@0
   566
	}
sl@0
   567
//Spin Thread : will do thread sync 
sl@0
   568
//param aSmp - CSMPSoakUtil pointer
sl@0
   569
TInt CSMPSoakThread::SMPStressSpinThread(TAny* aSmp)
sl@0
   570
    {
sl@0
   571
    CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
sl@0
   572
     __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressSpinThread Panic"),0));
sl@0
   573
    return self->DoSMPStressSpinThread();
sl@0
   574
    }
sl@0
   575
// Member for thread function
sl@0
   576
TInt CSMPSoakThread::DoSMPStressSpinThread()
sl@0
   577
	{
sl@0
   578
	RTest test(_L("SMPStressSpinThread"));
sl@0
   579
sl@0
   580
	TTime startTime;
sl@0
   581
	TTime endTime;
sl@0
   582
	TTimeIntervalMicroSeconds loopTimeMicroSeconds;
sl@0
   583
	PRINT (_L("SMPStressSpinThread\n"));
sl@0
   584
	FOREVER
sl@0
   585
		{
sl@0
   586
		SetThreadPriority();
sl@0
   587
		gSwitchSem.Wait();
sl@0
   588
		startTime.UniversalTime();
sl@0
   589
		do
sl@0
   590
		{
sl@0
   591
			endTime.UniversalTime();
sl@0
   592
			loopTimeMicroSeconds = endTime.MicroSecondsFrom(startTime);
sl@0
   593
		}while (loopTimeMicroSeconds <= iThreadData.delayTime*1000);
sl@0
   594
sl@0
   595
		if (gAbort)
sl@0
   596
			break;
sl@0
   597
		User::After(gPeriod);
sl@0
   598
		}
sl@0
   599
	return 0x00;
sl@0
   600
	}
sl@0
   601
//Timer Thread : Timer operation and  thread sync 
sl@0
   602
//param aSmp - CSMPSoakUtil pointer
sl@0
   603
TInt CSMPSoakThread::SMPStressTimerThread(TAny* aSmp)
sl@0
   604
    {
sl@0
   605
    CSMPSoakThread* self = (CSMPSoakThread*)aSmp;
sl@0
   606
     __ASSERT_ALWAYS(self !=NULL, User::Panic(_L("CSMPSoakThread::SMPStressTimerThread Panic"),0));
sl@0
   607
    return self->DoSMPStressTimerThread();
sl@0
   608
    }
sl@0
   609
// Member for thread function
sl@0
   610
TInt CSMPSoakThread::DoSMPStressTimerThread()
sl@0
   611
	{
sl@0
   612
	RTest test(_L("SMPStressTimerThread"));
sl@0
   613
sl@0
   614
	PRINT (_L("SMPStressTimerThread\n"));
sl@0
   615
	RTimer timer;
sl@0
   616
	test_KErrNone(timer.CreateLocal());
sl@0
   617
	TRequestStatus s;
sl@0
   618
sl@0
   619
	FOREVER
sl@0
   620
		{
sl@0
   621
		timer.After(s, iThreadData.delayTime*1000);
sl@0
   622
		User::WaitForRequest(s);
sl@0
   623
		test (s == KErrNone);
sl@0
   624
		PRINT ((_L("*")));
sl@0
   625
		gSwitchSem.Signal(iThreadData.numThreads);
sl@0
   626
sl@0
   627
		if (gAbort)
sl@0
   628
			break;
sl@0
   629
		User::After(gPeriod);
sl@0
   630
		}
sl@0
   631
	timer.Cancel();
sl@0
   632
	PRINT((_L("SMPStressTimerThread MyTimer.Cancel() called\n")));
sl@0
   633
	return 0x00;
sl@0
   634
	}
sl@0
   635
// CActive class to monitor KeyStrokes from User
sl@0
   636
class CActiveConsole : public CActive
sl@0
   637
	{
sl@0
   638
public:
sl@0
   639
	CActiveConsole();
sl@0
   640
	~CActiveConsole();
sl@0
   641
	void GetCharacter();
sl@0
   642
	static TInt Callback(TAny* aCtrl);
sl@0
   643
	static CPeriodic* TimerL();
sl@0
   644
private:
sl@0
   645
	// Defined as pure virtual by CActive;
sl@0
   646
	// implementation provided by this class.
sl@0
   647
	virtual void DoCancel();
sl@0
   648
	// Defined as pure virtual by CActive;
sl@0
   649
	// implementation provided by this class,
sl@0
   650
	virtual void RunL();
sl@0
   651
	void ProcessKeyPressL(TChar aChar);
sl@0
   652
private:
sl@0
   653
    
sl@0
   654
	};
sl@0
   655
// Class CActiveConsole
sl@0
   656
CActiveConsole::CActiveConsole()
sl@0
   657
	: CActive(EPriorityHigh)
sl@0
   658
	{
sl@0
   659
	CActiveScheduler::Add(this);
sl@0
   660
	}
sl@0
   661
sl@0
   662
CActiveConsole::~CActiveConsole()
sl@0
   663
	{
sl@0
   664
	Cancel();
sl@0
   665
	}
sl@0
   666
CPeriodic* CActiveConsole::TimerL()
sl@0
   667
    {
sl@0
   668
    return(CPeriodic::NewL(EPriorityNormal));
sl@0
   669
    }
sl@0
   670
// Callback function for timer expiry
sl@0
   671
TInt CActiveConsole::Callback(TAny* aControl)
sl@0
   672
	{
sl@0
   673
	return KErrNone;
sl@0
   674
	}
sl@0
   675
sl@0
   676
void CActiveConsole::GetCharacter()
sl@0
   677
	{
sl@0
   678
	test.Console()->Read(iStatus);
sl@0
   679
	SetActive();
sl@0
   680
	}
sl@0
   681
sl@0
   682
void CActiveConsole::DoCancel()
sl@0
   683
	{
sl@0
   684
	PRINT(_L("CActiveConsole::DoCancel\n"));
sl@0
   685
	test.Console()->ReadCancel();
sl@0
   686
	}
sl@0
   687
sl@0
   688
void CActiveConsole::ProcessKeyPressL(TChar aChar)
sl@0
   689
	{
sl@0
   690
	if (aChar == EKeyEscape)
sl@0
   691
		{
sl@0
   692
		PRINT(_L("CActiveConsole: ESC key pressed -> stopping active scheduler...\n"));
sl@0
   693
		gAbort = ETrue;
sl@0
   694
		CActiveScheduler::Stop();
sl@0
   695
		return;
sl@0
   696
		}
sl@0
   697
	aChar.UpperCase();
sl@0
   698
	GetCharacter();
sl@0
   699
	}
sl@0
   700
sl@0
   701
void CActiveConsole::RunL()
sl@0
   702
	{
sl@0
   703
	ProcessKeyPressL(static_cast<TChar>(test.Console()->KeyCode()));
sl@0
   704
	}
sl@0
   705
sl@0
   706
// CActiveTimer class to monitor timeout expiry
sl@0
   707
class CActiveTimer : public CActive
sl@0
   708
    {
sl@0
   709
public:
sl@0
   710
    CActiveTimer();
sl@0
   711
    ~CActiveTimer();
sl@0
   712
    void Delay(TTimeIntervalMicroSeconds32 aDelay);
sl@0
   713
private:
sl@0
   714
    RTimer iTimer;
sl@0
   715
    // Defined as pure virtual by CActive;
sl@0
   716
    // implementation provided by this class.
sl@0
   717
    virtual void DoCancel();
sl@0
   718
    // Defined as pure virtual by CActive;
sl@0
   719
    // implementation provided by this class,
sl@0
   720
    virtual void RunL();
sl@0
   721
   
sl@0
   722
    };
sl@0
   723
// Class CActiveConsole
sl@0
   724
CActiveTimer::CActiveTimer()
sl@0
   725
    : CActive(EPriorityHigh)
sl@0
   726
    {
sl@0
   727
    CActiveScheduler::Add(this);
sl@0
   728
    User::LeaveIfError(iTimer.CreateLocal());
sl@0
   729
    }
sl@0
   730
sl@0
   731
CActiveTimer::~CActiveTimer()
sl@0
   732
    {
sl@0
   733
    Cancel();
sl@0
   734
    iTimer.Close();
sl@0
   735
    }
sl@0
   736
sl@0
   737
sl@0
   738
void CActiveTimer::Delay(TTimeIntervalMicroSeconds32 aDelay)
sl@0
   739
    {
sl@0
   740
    iTimer.After(iStatus, aDelay);
sl@0
   741
    SetActive();
sl@0
   742
    }
sl@0
   743
sl@0
   744
void CActiveTimer::DoCancel()
sl@0
   745
    {
sl@0
   746
    iTimer.Cancel();
sl@0
   747
    }
sl@0
   748
sl@0
   749
void CActiveTimer::RunL()
sl@0
   750
    {
sl@0
   751
    PRINT(_L("CActiveTimer: Application runtime expired..."));
sl@0
   752
    gAbort = ETrue;
sl@0
   753
    CActiveScheduler::Stop();
sl@0
   754
    return;
sl@0
   755
    }
sl@0
   756
sl@0
   757
//T_SMPSOAK Entry Point
sl@0
   758
TInt E32Main()
sl@0
   759
	{
sl@0
   760
	test.Title();
sl@0
   761
	__UHEAP_MARK;
sl@0
   762
	test.Start(_L("t_smpsoak.exe"));
sl@0
   763
	
sl@0
   764
	// When running as a stand alone test, 
sl@0
   765
	// there needs to be a timeout
sl@0
   766
	timeout = ETrue;
sl@0
   767
sl@0
   768
	ParseCommandLine();
sl@0
   769
	if (gAbort)
sl@0
   770
		return 0x00;
sl@0
   771
sl@0
   772
	PRINT (_L("Load device driver\n"));
sl@0
   773
	TInt r = User::LoadLogicalDevice(_L("d_smpsoak.ldd"));
sl@0
   774
	if (r == KErrNotFound)
sl@0
   775
		{
sl@0
   776
		PRINT (_L("Test not supported on this platform because the D_SMPSOAK.LDD Driver is Not Present\n"));
sl@0
   777
		test(EFalse);
sl@0
   778
		}
sl@0
   779
	PRINT (_L("Calling SMPStressDrv Open\n"));
sl@0
   780
	r = gSMPStressDrv.Open();
sl@0
   781
	test_KErrNone(r);
sl@0
   782
sl@0
   783
	PRINT (_L("Creating our local semaphore\n"));
sl@0
   784
	r=gSwitchSem.CreateLocal(0);
sl@0
   785
	test_KErrNone(r);
sl@0
   786
sl@0
   787
	CSMPSoakThread smpthread;
sl@0
   788
	PRINT ((_L("Creating all threads =%d\n"),KNumThreads));
sl@0
   789
	smpthread.CreateThread();
sl@0
   790
			
sl@0
   791
	CSMPSoakThread *smpprocess= new CSMPSoakThread[NumProcess];
sl@0
   792
	PRINT ((_L("Creating all process =%d\n"),NumProcess));
sl@0
   793
	for (TInt i = 0; i < NumProcess; i++)
sl@0
   794
	    smpprocess[i].CreateChildProcess(i);
sl@0
   795
	
sl@0
   796
	PRINT (_L("Resuming all process \n"));
sl@0
   797
	for (TInt i = 0; i < NumProcess; i++)
sl@0
   798
	    smpprocess[i].ResumeChildProcess();
sl@0
   799
	
sl@0
   800
	PRINT (_L("Starting ActiveScheduler\n"));
sl@0
   801
	test.Next(_L("Press ESC Key to Shutdown SMPSoak...\n"));
sl@0
   802
	CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
sl@0
   803
	test(myScheduler != NULL);
sl@0
   804
	CActiveScheduler::Install(myScheduler);
sl@0
   805
	
sl@0
   806
	CPeriodic* theTimer=NULL;
sl@0
   807
	TRAPD(ret,theTimer=CActiveConsole::TimerL())
sl@0
   808
	test_KErrNone(ret);
sl@0
   809
	theTimer->Start(0,KTimerPeriod,TCallBack(CActiveConsole::Callback));
sl@0
   810
	if(timeout)
sl@0
   811
	    {
sl@0
   812
	    CActiveTimer* myActiveTimer = new CActiveTimer();
sl@0
   813
	    test(myActiveTimer != NULL);
sl@0
   814
	    myActiveTimer->Delay(gTimeout*1000000);
sl@0
   815
	    }
sl@0
   816
	CActiveConsole* myActiveConsole = new CActiveConsole();
sl@0
   817
	test(myActiveConsole != NULL);
sl@0
   818
	myActiveConsole->GetCharacter();
sl@0
   819
	CActiveScheduler::Start();
sl@0
   820
	if (gAbort)
sl@0
   821
			{
sl@0
   822
			PRINT (_L("gAbort TRUE \n"));
sl@0
   823
			for (TInt i = 0; i < NumProcess; i++)
sl@0
   824
			smpprocess[i].TerminateChildProcess();
sl@0
   825
			delete[] smpprocess;
sl@0
   826
			delete theTimer;
sl@0
   827
			gSMPStressDrv.Close();
sl@0
   828
			gSwitchSem.Close();
sl@0
   829
			return 0;
sl@0
   830
			}
sl@0
   831
	__UHEAP_MARKEND;
sl@0
   832
	test.End();
sl@0
   833
	return 0;
sl@0
   834
	}
sl@0
   835
void ParseCommandLine()
sl@0
   836
	{
sl@0
   837
	TBuf<256> args;
sl@0
   838
	User::CommandLine(args);
sl@0
   839
	TLex	lex(args);
sl@0
   840
	PRINT ((_L("****Command line = %s\n"), args.PtrZ()));
sl@0
   841
sl@0
   842
	FOREVER
sl@0
   843
		{
sl@0
   844
		TPtrC  token=lex.NextToken();
sl@0
   845
		if(token.Length()!=0)
sl@0
   846
			{
sl@0
   847
                if (token.Length()==0)
sl@0
   848
			        break;  // ignore trailing whitespace
sl@0
   849
                else if (token.Mid(0) == _L("-h"))
sl@0
   850
				{
sl@0
   851
                    PRINT (_L("T_SMPSOAK.EXE Usage Options:\n"));
sl@0
   852
                    PRINT (_L("Type t_smpsoak.exe -h\n"));
sl@0
   853
					ShowHelp();
sl@0
   854
					gAbort = ETrue;
sl@0
   855
					break;
sl@0
   856
				}
sl@0
   857
				else if (token.Mid(0) == _L("-l"))
sl@0
   858
				{
sl@0
   859
                    //Read OOM entry from KProcessTable and run
sl@0
   860
                    test.Printf(_L("SMPSOAK:lowmem\n"));
sl@0
   861
                    NumProcess = KNumProcess+1;
sl@0
   862
                    break;
sl@0
   863
				}
sl@0
   864
				else if (token.Mid(0) == _L("-b"))
sl@0
   865
				{
sl@0
   866
                    test.Printf(_L("SMPSOAK: Test Silent Mode\n")); 
sl@0
   867
                    ThreadPriorityLow = ETrue;
sl@0
   868
                    TestSilent = ETrue;
sl@0
   869
					// If we have tests running in the background
sl@0
   870
					// we want an endless loop
sl@0
   871
					timeout = EFalse;
sl@0
   872
                    break;
sl@0
   873
				}
sl@0
   874
				else if (token.Left(2) == _L("-t"))
sl@0
   875
				{
sl@0
   876
				    test.Printf(_L("SMPSOAK:Timeout\n"));
sl@0
   877
				    lex.SkipSpaceAndMark();
sl@0
   878
				    token.Set(lex.NextToken());
sl@0
   879
				    TLex lexNum(token);
sl@0
   880
				    lexNum.Val(gTimeout,EDecimal);   
sl@0
   881
				    test.Printf(_L("Timeout in Seconds=%u \n"),gTimeout);  
sl@0
   882
				    timeout = ETrue;
sl@0
   883
                    break;
sl@0
   884
				}
sl@0
   885
				else if (token.Left(2) == _L("-p"))
sl@0
   886
				{
sl@0
   887
                    test.Printf(_L("SMPSOAK:period\n"));
sl@0
   888
                    lex.SkipSpaceAndMark();
sl@0
   889
                    token.Set(lex.NextToken());
sl@0
   890
                    TLex lexNum(token);
sl@0
   891
                    lexNum.Val(gPeriod,EDecimal);   
sl@0
   892
				    test.Printf(_L("period in mSeconds=%d \n"),gPeriod);  
sl@0
   893
				    Period = ETrue;
sl@0
   894
				    break;
sl@0
   895
				}
sl@0
   896
				else
sl@0
   897
				{
sl@0
   898
                    test.Printf(_L("Error- Invalid SMPSOAK CMD Line Argument"));
sl@0
   899
				  	break;
sl@0
   900
				}
sl@0
   901
			}
sl@0
   902
		break;
sl@0
   903
		}
sl@0
   904
	}