os/kernelhwsrv/kerneltest/e32test/stack/t_stacksize.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) 2003-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\stack\t_stacksize.cpp
sl@0
    15
// Overview:
sl@0
    16
// Verifies the correct implementation of CreateStackOverride method of RProcess.
sl@0
    17
// Meanings of constants:
sl@0
    18
// KDefaultStackSize: 
sl@0
    19
// - System wide default stack size in actual version;
sl@0
    20
// KNumberOfFitIteration: 
sl@0
    21
// - Number of DummyRecursion which can fit in KDefaultStackSize. 
sl@0
    22
// Value = KDefaultStackSize / 2KB - 1 
sl@0
    23
// KNumberOfUnfitIteration: 
sl@0
    24
// - Number of DummyRecursion which is raised a Panic based on stack overflow.
sl@0
    25
// Value = KDefaultStackSize / 2KB rounded up to nearest integer
sl@0
    26
// Details:
sl@0
    27
// ETestProcess1: Create a process with original RProcess::Create() and start it
sl@0
    28
// - it passes with KNumberOfFitIteration DummyRecursion .
sl@0
    29
// ETestProcess2: Create a process with RProcess::CreateWithStackOverride(), default 
sl@0
    30
// stack size and start it
sl@0
    31
// - it passes with KNumberOfFitIteration DummyRecursion.
sl@0
    32
// ETestProcess3: Create a process with original RProcess::Create() and start it
sl@0
    33
// - it raised Panic on Stack overflow with KNumberOfUnfitIteration DummyRecursion.
sl@0
    34
// ETestProcess4: Create a process with RProcess::CreateWithStackOverride(), default 
sl@0
    35
// stack size and start it
sl@0
    36
// - it raised Panic on Stack overflow with KNumberOfUnfitIteration DummyRecursion.
sl@0
    37
// ETestProcess5: Create a process with RProcess::CreateWithStackOverride(), 2*KDefaultStackSize 
sl@0
    38
// stack and start it
sl@0
    39
// - it passes with KNumberOfUnfitIteration DummyRecursion.
sl@0
    40
// ETestProcess6: Create a process with RProcess::CreateWithStackOverride(), -2*KDefaultStackSize 
sl@0
    41
// stack.
sl@0
    42
// - the process creation interrupted with KErrArgument error code
sl@0
    43
// ETestProcess7: Create a process with RProcess::CreateWithStackOverride(), KDefaultStackSize/2 
sl@0
    44
// stack and start it
sl@0
    45
// - it passes with KNumberOfFitIteration DummyRecursion, because the process will be 
sl@0
    46
// create with (App. image) default stack size.
sl@0
    47
// Platforms/Drives/Compatibility:
sl@0
    48
// It is won't work on emulator, because the unlimited stack size.
sl@0
    49
// Assumptions/Requirement/Pre-requisites:
sl@0
    50
// No
sl@0
    51
// Failures and causes:
sl@0
    52
// Failures of this test will indicate defects in the implementation of CreateWithStackOverride().
sl@0
    53
// Base Port information:
sl@0
    54
// No?
sl@0
    55
// 
sl@0
    56
//
sl@0
    57
sl@0
    58
#include <e32test.h>
sl@0
    59
#include "u32std.h"
sl@0
    60
#include <u32hal.h>
sl@0
    61
#include <e32svr.h>
sl@0
    62
sl@0
    63
LOCAL_D RTest test(_L("T_STACKSIZE"));
sl@0
    64
LOCAL_D RTest test2(_L("*** T_STACKSIZE SLAVE ***"));
sl@0
    65
sl@0
    66
// We are here making the assumption that one quarter of the stack should be sufficient
sl@0
    67
// to accommodate for the overhead generated by the recursive calls as well as
sl@0
    68
// unpredictable compiler optimisations.
sl@0
    69
const TInt KStackGobbleSize = KDefaultStackSize / 4 - 8;
sl@0
    70
const TInt KNumberOfFitIteration = 3;
sl@0
    71
const TInt KNumberOfUnfitIteration = 4;
sl@0
    72
sl@0
    73
const TInt KImageStackSize = 0x2000; // Test app image stack size (epocstacksize in MMP file)
sl@0
    74
sl@0
    75
enum TTestProcessFunctions
sl@0
    76
	{
sl@0
    77
	ETestProcess1,
sl@0
    78
	ETestProcess2,
sl@0
    79
	ETestProcess3,
sl@0
    80
	ETestProcess4,
sl@0
    81
	ETestProcess5,
sl@0
    82
	ETestProcess6,
sl@0
    83
	ETestProcess7,
sl@0
    84
	};
sl@0
    85
sl@0
    86
class RTestProcess : public RProcess
sl@0
    87
	{
sl@0
    88
public:
sl@0
    89
	TInt Create(TTestProcessFunctions aFunction, TInt aStackSize=0, TInt aArg1=-1,TInt aArg2=-1);
sl@0
    90
	};
sl@0
    91
sl@0
    92
TInt RTestProcess::Create(TTestProcessFunctions aFunction, TInt aStackSize, TInt aArg1,TInt aArg2)
sl@0
    93
	{
sl@0
    94
	
sl@0
    95
	test.Printf(_L("RTestProcess::Create started with stack size:%d bytes\n"), aStackSize);
sl@0
    96
	if(aArg1==-1)
sl@0
    97
		aArg1 = RProcess().Id();
sl@0
    98
	TBuf<512> commandLine;
sl@0
    99
	commandLine.Num((TInt)aFunction);
sl@0
   100
	commandLine.Append(_L(" "));
sl@0
   101
	commandLine.AppendNum(aArg1);
sl@0
   102
	commandLine.Append(_L(" "));
sl@0
   103
	commandLine.AppendNum(aArg2);
sl@0
   104
sl@0
   105
	TFileName filename(RProcess().FileName());
sl@0
   106
	TInt pos=filename.LocateReverse(TChar('\\'));
sl@0
   107
	filename.SetLength(pos+1);
sl@0
   108
	filename+=_L("T_STACKSIZE.EXE");
sl@0
   109
	
sl@0
   110
	TInt r=KErrNone;
sl@0
   111
	switch (aFunction)
sl@0
   112
		{
sl@0
   113
		case ETestProcess1:
sl@0
   114
			test.Printf(_L("Call original Create.\n"));
sl@0
   115
			r = RProcess::Create(filename,commandLine); 
sl@0
   116
			break;
sl@0
   117
			
sl@0
   118
		case ETestProcess2:
sl@0
   119
			test.Printf(_L("Call CreateWithStackOverride\n"));	
sl@0
   120
			r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
sl@0
   121
			break;
sl@0
   122
			
sl@0
   123
		case ETestProcess3:
sl@0
   124
			test.Printf(_L("Call original Create.\n"));
sl@0
   125
			r = RProcess::Create(filename,commandLine); 
sl@0
   126
			break;
sl@0
   127
			
sl@0
   128
		case ETestProcess4:
sl@0
   129
			test.Printf(_L("Call CreateWithStackOverride\n"));	
sl@0
   130
			r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
sl@0
   131
			break;
sl@0
   132
			
sl@0
   133
		case ETestProcess5:
sl@0
   134
			test.Printf(_L("Call CreateWithStackOverride\n"));	
sl@0
   135
			r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
sl@0
   136
			break;
sl@0
   137
			
sl@0
   138
		case ETestProcess6:
sl@0
   139
			test.Printf(_L("Call CreateWithStackOverride\n"));	
sl@0
   140
			r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
sl@0
   141
			break;
sl@0
   142
			
sl@0
   143
		case ETestProcess7:
sl@0
   144
			test.Printf(_L("Call CreateWithStackOverride\n"));	
sl@0
   145
			r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
sl@0
   146
			break;
sl@0
   147
sl@0
   148
		default:
sl@0
   149
			User::Panic(_L("T_STACKSIZE"),1);
sl@0
   150
			
sl@0
   151
		}
sl@0
   152
sl@0
   153
	test.Printf(_L("RTestProcess::Create end.\n"));
sl@0
   154
	return r;
sl@0
   155
	}
sl@0
   156
sl@0
   157
sl@0
   158
TInt DummyRecursion(TInt aA)
sl@0
   159
	{
sl@0
   160
	TBuf8<KStackGobbleSize> gobble;	// gobble 1/4 of the stack
sl@0
   161
	gobble.Append(TChar(aA));	// stop compiler optimising out gobble buffer
sl@0
   162
	if (aA <= 1)
sl@0
   163
		return aA;
sl@0
   164
	return 1 + DummyRecursion(aA-1);
sl@0
   165
	}
sl@0
   166
sl@0
   167
// Make these global so we don't push too much stuff on the stack
sl@0
   168
TThreadStackInfo ThreadStackInfo;
sl@0
   169
_LIT(KStackSizeText, "Stack size is %d bytes\n");
sl@0
   170
sl@0
   171
TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
sl@0
   172
	{
sl@0
   173
	(void)aArg1;
sl@0
   174
	(void)aArg2;
sl@0
   175
	RThread().StackInfo(ThreadStackInfo);
sl@0
   176
sl@0
   177
	switch(aTestNum)
sl@0
   178
		{
sl@0
   179
	case ETestProcess1:
sl@0
   180
		{
sl@0
   181
		test2.Printf(_L("ETestProcess1 started with %d recursion...\n"), KNumberOfFitIteration);
sl@0
   182
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   183
#ifndef __WINS__
sl@0
   184
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
sl@0
   185
#endif
sl@0
   186
		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
sl@0
   187
		break;
sl@0
   188
		}
sl@0
   189
		
sl@0
   190
	case ETestProcess2:
sl@0
   191
		{
sl@0
   192
		test2.Printf(_L("ETestProcess2 started with %d recursion...\n"), KNumberOfFitIteration);
sl@0
   193
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   194
#ifndef __WINS__
sl@0
   195
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
sl@0
   196
#endif
sl@0
   197
		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
sl@0
   198
		break;
sl@0
   199
		}
sl@0
   200
		
sl@0
   201
	case ETestProcess3:
sl@0
   202
		{
sl@0
   203
		test2.Printf(_L("ETestProcess3 started with %d recusion...\n"), KNumberOfUnfitIteration);
sl@0
   204
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   205
#ifndef __WINS__
sl@0
   206
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
sl@0
   207
#endif
sl@0
   208
		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
sl@0
   209
		break;
sl@0
   210
		}
sl@0
   211
		
sl@0
   212
	case ETestProcess4:
sl@0
   213
		{
sl@0
   214
		test2.Printf(_L("ETestProcess4 started with %d recursion...\n"), KNumberOfUnfitIteration);
sl@0
   215
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   216
#ifndef __WINS__
sl@0
   217
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
sl@0
   218
#endif
sl@0
   219
		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
sl@0
   220
		break;
sl@0
   221
		}
sl@0
   222
		
sl@0
   223
	case ETestProcess5:
sl@0
   224
		{
sl@0
   225
		test2.Printf(_L("ETestProcess5 started with %d recursion...\n"), KNumberOfUnfitIteration);
sl@0
   226
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   227
#ifndef __WINS__
sl@0
   228
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize * 2);
sl@0
   229
#endif
sl@0
   230
		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
sl@0
   231
		break;
sl@0
   232
		}
sl@0
   233
		
sl@0
   234
	case ETestProcess6:
sl@0
   235
		{
sl@0
   236
		test2(EFalse); // Process creation should have failed
sl@0
   237
		}
sl@0
   238
sl@0
   239
	case ETestProcess7:
sl@0
   240
		{
sl@0
   241
		test2.Printf(_L("ETestProcess7 started with %d recursion\n"), KNumberOfFitIteration);
sl@0
   242
		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
sl@0
   243
#ifndef __WINS__
sl@0
   244
		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KImageStackSize); // Should default to stack size set in image header
sl@0
   245
		if (KImageStackSize == KDefaultStackSize) // If this is not the case, results can be a bit unpredictable
sl@0
   246
			{
sl@0
   247
			test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
sl@0
   248
			}
sl@0
   249
#endif
sl@0
   250
		break;
sl@0
   251
		}
sl@0
   252
		
sl@0
   253
	default:
sl@0
   254
		User::Panic(_L("T_STACKSIZE"),1);
sl@0
   255
		}
sl@0
   256
sl@0
   257
	test2.Printf(_L("\n\t finished.\n"));
sl@0
   258
	
sl@0
   259
	return KErrNone;
sl@0
   260
	}
sl@0
   261
sl@0
   262
GLDEF_C TInt E32Main()
sl@0
   263
    {
sl@0
   264
    
sl@0
   265
	
sl@0
   266
	TBuf16<512> cmd;
sl@0
   267
	User::CommandLine(cmd);
sl@0
   268
	if(cmd.Length() && TChar(cmd[0]).IsDigit())
sl@0
   269
		{
sl@0
   270
		test2.Title();
sl@0
   271
		test2.Start(_L("Slave process started..."));
sl@0
   272
		TInt function = -1;
sl@0
   273
		TInt arg1 = -1;
sl@0
   274
		TInt arg2 = -1;
sl@0
   275
		TLex lex(cmd);
sl@0
   276
		lex.Val(function);
sl@0
   277
		lex.SkipSpace();
sl@0
   278
		lex.Val(arg1);
sl@0
   279
		lex.SkipSpace();
sl@0
   280
		lex.Val(arg2);
sl@0
   281
		int r = DoTestProcess(function,arg1,arg2); 
sl@0
   282
		test2.End();
sl@0
   283
		return r;
sl@0
   284
		}
sl@0
   285
sl@0
   286
	test.Title();
sl@0
   287
sl@0
   288
	RTestProcess rogueP;
sl@0
   289
	TRequestStatus rendezvous;
sl@0
   290
sl@0
   291
	test.Start(_L("Create process with original Create and default stack size"));
sl@0
   292
	TInt r = rogueP.Create(ETestProcess1, KDefaultStackSize);
sl@0
   293
	test(r==KErrNone);
sl@0
   294
	rogueP.Rendezvous(rendezvous);
sl@0
   295
	rogueP.Resume();
sl@0
   296
	User::WaitForRequest(rendezvous);
sl@0
   297
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
sl@0
   298
	test(rogueP.ExitType()==EExitKill);
sl@0
   299
	CLOSE_AND_WAIT(rogueP);
sl@0
   300
	
sl@0
   301
	test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
sl@0
   302
	r = rogueP.Create(ETestProcess2, KDefaultStackSize);
sl@0
   303
	test(r==KErrNone);
sl@0
   304
	rogueP.Rendezvous(rendezvous);
sl@0
   305
	rogueP.Resume();
sl@0
   306
	User::WaitForRequest(rendezvous);
sl@0
   307
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
sl@0
   308
	test(rogueP.ExitType()==EExitKill);
sl@0
   309
	CLOSE_AND_WAIT(rogueP);
sl@0
   310
	
sl@0
   311
	test.Next(_L("Create process with original Create and default stack size"));
sl@0
   312
	r = rogueP.Create(ETestProcess3, KDefaultStackSize);
sl@0
   313
	test(r==KErrNone);
sl@0
   314
	rogueP.Rendezvous(rendezvous);
sl@0
   315
	rogueP.Resume();
sl@0
   316
	User::WaitForRequest(rendezvous);
sl@0
   317
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
sl@0
   318
#if !defined(__WINS__)
sl@0
   319
	test(rogueP.ExitType()==EExitPanic);
sl@0
   320
#else
sl@0
   321
	test(rogueP.ExitType()==EExitKill);
sl@0
   322
#endif
sl@0
   323
	CLOSE_AND_WAIT(rogueP);
sl@0
   324
	
sl@0
   325
	test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
sl@0
   326
	r = rogueP.Create(ETestProcess4, KDefaultStackSize);
sl@0
   327
	test(r==KErrNone);
sl@0
   328
	rogueP.Rendezvous(rendezvous);
sl@0
   329
	rogueP.Resume();
sl@0
   330
	User::WaitForRequest(rendezvous);
sl@0
   331
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType());
sl@0
   332
#if !defined(__WINS__)
sl@0
   333
	test(rogueP.ExitType()==EExitPanic);
sl@0
   334
#else
sl@0
   335
	test(rogueP.ExitType()==EExitKill);
sl@0
   336
#endif
sl@0
   337
	CLOSE_AND_WAIT(rogueP);
sl@0
   338
sl@0
   339
	test.Next(_L("Create process with CreateWithStackOverride and 2 * KDefaultStackSize stack size"));
sl@0
   340
	r = rogueP.Create(ETestProcess5, 2 * KDefaultStackSize );
sl@0
   341
	test(r==KErrNone);
sl@0
   342
	rogueP.Rendezvous(rendezvous);
sl@0
   343
	rogueP.Resume();
sl@0
   344
	User::WaitForRequest(rendezvous);
sl@0
   345
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
sl@0
   346
	test(rogueP.ExitType()==EExitKill);
sl@0
   347
	CLOSE_AND_WAIT(rogueP);
sl@0
   348
sl@0
   349
#if !defined(__WINS__)
sl@0
   350
	test.Next(_L("Create process with CreateWithStackOverride and negative stack size"));
sl@0
   351
	r = rogueP.Create(ETestProcess6, - 2 * KDefaultStackSize );
sl@0
   352
	test(r==KErrArgument);
sl@0
   353
#endif
sl@0
   354
sl@0
   355
	test.Next(_L("Create process with CreateWithStackOverride and KImageStackSize/2 stack size"));
sl@0
   356
	r = rogueP.Create(ETestProcess7, KImageStackSize / 2 );
sl@0
   357
	test(r==KErrNone);
sl@0
   358
	rogueP.Rendezvous(rendezvous);
sl@0
   359
	rogueP.Resume();
sl@0
   360
	User::WaitForRequest(rendezvous);
sl@0
   361
	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
sl@0
   362
	test(rogueP.ExitType()==EExitKill);
sl@0
   363
	CLOSE_AND_WAIT(rogueP);
sl@0
   364
	
sl@0
   365
	test.Printf(_L("Test finished.\n"));
sl@0
   366
	test.End();
sl@0
   367
sl@0
   368
	return(0);
sl@0
   369
    }
sl@0
   370