1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/stack/t_stacksize.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,370 @@
1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\stack\t_stacksize.cpp
1.18 +// Overview:
1.19 +// Verifies the correct implementation of CreateStackOverride method of RProcess.
1.20 +// Meanings of constants:
1.21 +// KDefaultStackSize:
1.22 +// - System wide default stack size in actual version;
1.23 +// KNumberOfFitIteration:
1.24 +// - Number of DummyRecursion which can fit in KDefaultStackSize.
1.25 +// Value = KDefaultStackSize / 2KB - 1
1.26 +// KNumberOfUnfitIteration:
1.27 +// - Number of DummyRecursion which is raised a Panic based on stack overflow.
1.28 +// Value = KDefaultStackSize / 2KB rounded up to nearest integer
1.29 +// Details:
1.30 +// ETestProcess1: Create a process with original RProcess::Create() and start it
1.31 +// - it passes with KNumberOfFitIteration DummyRecursion .
1.32 +// ETestProcess2: Create a process with RProcess::CreateWithStackOverride(), default
1.33 +// stack size and start it
1.34 +// - it passes with KNumberOfFitIteration DummyRecursion.
1.35 +// ETestProcess3: Create a process with original RProcess::Create() and start it
1.36 +// - it raised Panic on Stack overflow with KNumberOfUnfitIteration DummyRecursion.
1.37 +// ETestProcess4: Create a process with RProcess::CreateWithStackOverride(), default
1.38 +// stack size and start it
1.39 +// - it raised Panic on Stack overflow with KNumberOfUnfitIteration DummyRecursion.
1.40 +// ETestProcess5: Create a process with RProcess::CreateWithStackOverride(), 2*KDefaultStackSize
1.41 +// stack and start it
1.42 +// - it passes with KNumberOfUnfitIteration DummyRecursion.
1.43 +// ETestProcess6: Create a process with RProcess::CreateWithStackOverride(), -2*KDefaultStackSize
1.44 +// stack.
1.45 +// - the process creation interrupted with KErrArgument error code
1.46 +// ETestProcess7: Create a process with RProcess::CreateWithStackOverride(), KDefaultStackSize/2
1.47 +// stack and start it
1.48 +// - it passes with KNumberOfFitIteration DummyRecursion, because the process will be
1.49 +// create with (App. image) default stack size.
1.50 +// Platforms/Drives/Compatibility:
1.51 +// It is won't work on emulator, because the unlimited stack size.
1.52 +// Assumptions/Requirement/Pre-requisites:
1.53 +// No
1.54 +// Failures and causes:
1.55 +// Failures of this test will indicate defects in the implementation of CreateWithStackOverride().
1.56 +// Base Port information:
1.57 +// No?
1.58 +//
1.59 +//
1.60 +
1.61 +#include <e32test.h>
1.62 +#include "u32std.h"
1.63 +#include <u32hal.h>
1.64 +#include <e32svr.h>
1.65 +
1.66 +LOCAL_D RTest test(_L("T_STACKSIZE"));
1.67 +LOCAL_D RTest test2(_L("*** T_STACKSIZE SLAVE ***"));
1.68 +
1.69 +// We are here making the assumption that one quarter of the stack should be sufficient
1.70 +// to accommodate for the overhead generated by the recursive calls as well as
1.71 +// unpredictable compiler optimisations.
1.72 +const TInt KStackGobbleSize = KDefaultStackSize / 4 - 8;
1.73 +const TInt KNumberOfFitIteration = 3;
1.74 +const TInt KNumberOfUnfitIteration = 4;
1.75 +
1.76 +const TInt KImageStackSize = 0x2000; // Test app image stack size (epocstacksize in MMP file)
1.77 +
1.78 +enum TTestProcessFunctions
1.79 + {
1.80 + ETestProcess1,
1.81 + ETestProcess2,
1.82 + ETestProcess3,
1.83 + ETestProcess4,
1.84 + ETestProcess5,
1.85 + ETestProcess6,
1.86 + ETestProcess7,
1.87 + };
1.88 +
1.89 +class RTestProcess : public RProcess
1.90 + {
1.91 +public:
1.92 + TInt Create(TTestProcessFunctions aFunction, TInt aStackSize=0, TInt aArg1=-1,TInt aArg2=-1);
1.93 + };
1.94 +
1.95 +TInt RTestProcess::Create(TTestProcessFunctions aFunction, TInt aStackSize, TInt aArg1,TInt aArg2)
1.96 + {
1.97 +
1.98 + test.Printf(_L("RTestProcess::Create started with stack size:%d bytes\n"), aStackSize);
1.99 + if(aArg1==-1)
1.100 + aArg1 = RProcess().Id();
1.101 + TBuf<512> commandLine;
1.102 + commandLine.Num((TInt)aFunction);
1.103 + commandLine.Append(_L(" "));
1.104 + commandLine.AppendNum(aArg1);
1.105 + commandLine.Append(_L(" "));
1.106 + commandLine.AppendNum(aArg2);
1.107 +
1.108 + TFileName filename(RProcess().FileName());
1.109 + TInt pos=filename.LocateReverse(TChar('\\'));
1.110 + filename.SetLength(pos+1);
1.111 + filename+=_L("T_STACKSIZE.EXE");
1.112 +
1.113 + TInt r=KErrNone;
1.114 + switch (aFunction)
1.115 + {
1.116 + case ETestProcess1:
1.117 + test.Printf(_L("Call original Create.\n"));
1.118 + r = RProcess::Create(filename,commandLine);
1.119 + break;
1.120 +
1.121 + case ETestProcess2:
1.122 + test.Printf(_L("Call CreateWithStackOverride\n"));
1.123 + r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
1.124 + break;
1.125 +
1.126 + case ETestProcess3:
1.127 + test.Printf(_L("Call original Create.\n"));
1.128 + r = RProcess::Create(filename,commandLine);
1.129 + break;
1.130 +
1.131 + case ETestProcess4:
1.132 + test.Printf(_L("Call CreateWithStackOverride\n"));
1.133 + r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
1.134 + break;
1.135 +
1.136 + case ETestProcess5:
1.137 + test.Printf(_L("Call CreateWithStackOverride\n"));
1.138 + r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
1.139 + break;
1.140 +
1.141 + case ETestProcess6:
1.142 + test.Printf(_L("Call CreateWithStackOverride\n"));
1.143 + r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
1.144 + break;
1.145 +
1.146 + case ETestProcess7:
1.147 + test.Printf(_L("Call CreateWithStackOverride\n"));
1.148 + r = RProcess::CreateWithStackOverride(filename, commandLine, TUidType(), aStackSize, EOwnerProcess);
1.149 + break;
1.150 +
1.151 + default:
1.152 + User::Panic(_L("T_STACKSIZE"),1);
1.153 +
1.154 + }
1.155 +
1.156 + test.Printf(_L("RTestProcess::Create end.\n"));
1.157 + return r;
1.158 + }
1.159 +
1.160 +
1.161 +TInt DummyRecursion(TInt aA)
1.162 + {
1.163 + TBuf8<KStackGobbleSize> gobble; // gobble 1/4 of the stack
1.164 + gobble.Append(TChar(aA)); // stop compiler optimising out gobble buffer
1.165 + if (aA <= 1)
1.166 + return aA;
1.167 + return 1 + DummyRecursion(aA-1);
1.168 + }
1.169 +
1.170 +// Make these global so we don't push too much stuff on the stack
1.171 +TThreadStackInfo ThreadStackInfo;
1.172 +_LIT(KStackSizeText, "Stack size is %d bytes\n");
1.173 +
1.174 +TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
1.175 + {
1.176 + (void)aArg1;
1.177 + (void)aArg2;
1.178 + RThread().StackInfo(ThreadStackInfo);
1.179 +
1.180 + switch(aTestNum)
1.181 + {
1.182 + case ETestProcess1:
1.183 + {
1.184 + test2.Printf(_L("ETestProcess1 started with %d recursion...\n"), KNumberOfFitIteration);
1.185 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.186 +#ifndef __WINS__
1.187 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
1.188 +#endif
1.189 + test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
1.190 + break;
1.191 + }
1.192 +
1.193 + case ETestProcess2:
1.194 + {
1.195 + test2.Printf(_L("ETestProcess2 started with %d recursion...\n"), KNumberOfFitIteration);
1.196 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.197 +#ifndef __WINS__
1.198 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
1.199 +#endif
1.200 + test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
1.201 + break;
1.202 + }
1.203 +
1.204 + case ETestProcess3:
1.205 + {
1.206 + test2.Printf(_L("ETestProcess3 started with %d recusion...\n"), KNumberOfUnfitIteration);
1.207 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.208 +#ifndef __WINS__
1.209 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
1.210 +#endif
1.211 + test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
1.212 + break;
1.213 + }
1.214 +
1.215 + case ETestProcess4:
1.216 + {
1.217 + test2.Printf(_L("ETestProcess4 started with %d recursion...\n"), KNumberOfUnfitIteration);
1.218 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.219 +#ifndef __WINS__
1.220 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
1.221 +#endif
1.222 + test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
1.223 + break;
1.224 + }
1.225 +
1.226 + case ETestProcess5:
1.227 + {
1.228 + test2.Printf(_L("ETestProcess5 started with %d recursion...\n"), KNumberOfUnfitIteration);
1.229 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.230 +#ifndef __WINS__
1.231 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize * 2);
1.232 +#endif
1.233 + test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
1.234 + break;
1.235 + }
1.236 +
1.237 + case ETestProcess6:
1.238 + {
1.239 + test2(EFalse); // Process creation should have failed
1.240 + }
1.241 +
1.242 + case ETestProcess7:
1.243 + {
1.244 + test2.Printf(_L("ETestProcess7 started with %d recursion\n"), KNumberOfFitIteration);
1.245 + test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
1.246 +#ifndef __WINS__
1.247 + test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KImageStackSize); // Should default to stack size set in image header
1.248 + if (KImageStackSize == KDefaultStackSize) // If this is not the case, results can be a bit unpredictable
1.249 + {
1.250 + test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
1.251 + }
1.252 +#endif
1.253 + break;
1.254 + }
1.255 +
1.256 + default:
1.257 + User::Panic(_L("T_STACKSIZE"),1);
1.258 + }
1.259 +
1.260 + test2.Printf(_L("\n\t finished.\n"));
1.261 +
1.262 + return KErrNone;
1.263 + }
1.264 +
1.265 +GLDEF_C TInt E32Main()
1.266 + {
1.267 +
1.268 +
1.269 + TBuf16<512> cmd;
1.270 + User::CommandLine(cmd);
1.271 + if(cmd.Length() && TChar(cmd[0]).IsDigit())
1.272 + {
1.273 + test2.Title();
1.274 + test2.Start(_L("Slave process started..."));
1.275 + TInt function = -1;
1.276 + TInt arg1 = -1;
1.277 + TInt arg2 = -1;
1.278 + TLex lex(cmd);
1.279 + lex.Val(function);
1.280 + lex.SkipSpace();
1.281 + lex.Val(arg1);
1.282 + lex.SkipSpace();
1.283 + lex.Val(arg2);
1.284 + int r = DoTestProcess(function,arg1,arg2);
1.285 + test2.End();
1.286 + return r;
1.287 + }
1.288 +
1.289 + test.Title();
1.290 +
1.291 + RTestProcess rogueP;
1.292 + TRequestStatus rendezvous;
1.293 +
1.294 + test.Start(_L("Create process with original Create and default stack size"));
1.295 + TInt r = rogueP.Create(ETestProcess1, KDefaultStackSize);
1.296 + test(r==KErrNone);
1.297 + rogueP.Rendezvous(rendezvous);
1.298 + rogueP.Resume();
1.299 + User::WaitForRequest(rendezvous);
1.300 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
1.301 + test(rogueP.ExitType()==EExitKill);
1.302 + CLOSE_AND_WAIT(rogueP);
1.303 +
1.304 + test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
1.305 + r = rogueP.Create(ETestProcess2, KDefaultStackSize);
1.306 + test(r==KErrNone);
1.307 + rogueP.Rendezvous(rendezvous);
1.308 + rogueP.Resume();
1.309 + User::WaitForRequest(rendezvous);
1.310 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
1.311 + test(rogueP.ExitType()==EExitKill);
1.312 + CLOSE_AND_WAIT(rogueP);
1.313 +
1.314 + test.Next(_L("Create process with original Create and default stack size"));
1.315 + r = rogueP.Create(ETestProcess3, KDefaultStackSize);
1.316 + test(r==KErrNone);
1.317 + rogueP.Rendezvous(rendezvous);
1.318 + rogueP.Resume();
1.319 + User::WaitForRequest(rendezvous);
1.320 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
1.321 +#if !defined(__WINS__)
1.322 + test(rogueP.ExitType()==EExitPanic);
1.323 +#else
1.324 + test(rogueP.ExitType()==EExitKill);
1.325 +#endif
1.326 + CLOSE_AND_WAIT(rogueP);
1.327 +
1.328 + test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
1.329 + r = rogueP.Create(ETestProcess4, KDefaultStackSize);
1.330 + test(r==KErrNone);
1.331 + rogueP.Rendezvous(rendezvous);
1.332 + rogueP.Resume();
1.333 + User::WaitForRequest(rendezvous);
1.334 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType());
1.335 +#if !defined(__WINS__)
1.336 + test(rogueP.ExitType()==EExitPanic);
1.337 +#else
1.338 + test(rogueP.ExitType()==EExitKill);
1.339 +#endif
1.340 + CLOSE_AND_WAIT(rogueP);
1.341 +
1.342 + test.Next(_L("Create process with CreateWithStackOverride and 2 * KDefaultStackSize stack size"));
1.343 + r = rogueP.Create(ETestProcess5, 2 * KDefaultStackSize );
1.344 + test(r==KErrNone);
1.345 + rogueP.Rendezvous(rendezvous);
1.346 + rogueP.Resume();
1.347 + User::WaitForRequest(rendezvous);
1.348 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
1.349 + test(rogueP.ExitType()==EExitKill);
1.350 + CLOSE_AND_WAIT(rogueP);
1.351 +
1.352 +#if !defined(__WINS__)
1.353 + test.Next(_L("Create process with CreateWithStackOverride and negative stack size"));
1.354 + r = rogueP.Create(ETestProcess6, - 2 * KDefaultStackSize );
1.355 + test(r==KErrArgument);
1.356 +#endif
1.357 +
1.358 + test.Next(_L("Create process with CreateWithStackOverride and KImageStackSize/2 stack size"));
1.359 + r = rogueP.Create(ETestProcess7, KImageStackSize / 2 );
1.360 + test(r==KErrNone);
1.361 + rogueP.Rendezvous(rendezvous);
1.362 + rogueP.Resume();
1.363 + User::WaitForRequest(rendezvous);
1.364 + test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
1.365 + test(rogueP.ExitType()==EExitKill);
1.366 + CLOSE_AND_WAIT(rogueP);
1.367 +
1.368 + test.Printf(_L("Test finished.\n"));
1.369 + test.End();
1.370 +
1.371 + return(0);
1.372 + }
1.373 +