kerneltest/e32test/stack/t_stacksize.cpp
changeset 15 4122176ea935
parent 0 a41df078684a
--- a/kerneltest/e32test/stack/t_stacksize.cpp	Mon Oct 19 15:55:17 2009 +0100
+++ b/kerneltest/e32test/stack/t_stacksize.cpp	Mon Dec 21 16:14:42 2009 +0000
@@ -63,8 +63,14 @@
 LOCAL_D RTest test(_L("T_STACKSIZE"));
 LOCAL_D RTest test2(_L("*** T_STACKSIZE SLAVE ***"));
 
-const TInt KNumberOfFitIteration = KDefaultStackSize / 2048 - 1;
-const TInt KNumberOfUnfitIteration = (KDefaultStackSize + 2047) / 2048;
+// We are here making the assumption that one quarter of the stack should be sufficient
+// to accommodate for the overhead generated by the recursive calls as well as
+// unpredictable compiler optimisations.
+const TInt KStackGobbleSize = KDefaultStackSize / 4 - 8;
+const TInt KNumberOfFitIteration = 3;
+const TInt KNumberOfUnfitIteration = 4;
+
+const TInt KImageStackSize = 0x2000; // Test app image stack size (epocstacksize in MMP file)
 
 enum TTestProcessFunctions
 	{
@@ -86,9 +92,7 @@
 TInt RTestProcess::Create(TTestProcessFunctions aFunction, TInt aStackSize, TInt aArg1,TInt aArg2)
 	{
 	
-	test.Printf(_L("RTestProcess::Create started with stack size:%d bytes\n") 
-								, (0 == aStackSize ? KDefaultStackSize : aStackSize )
-								);
+	test.Printf(_L("RTestProcess::Create started with stack size:%d bytes\n"), aStackSize);
 	if(aArg1==-1)
 		aArg1 = RProcess().Id();
 	TBuf<512> commandLine;
@@ -153,24 +157,32 @@
 
 TInt DummyRecursion(TInt aA)
 	{
-	TBuf8<2040> gobble;	// gobble 2K of stack
+	TBuf8<KStackGobbleSize> gobble;	// gobble 1/4 of the stack
 	gobble.Append(TChar(aA));	// stop compiler optimising out gobble buffer
 	if (aA <= 1)
 		return aA;
 	return 1 + DummyRecursion(aA-1);
 	}
 
+// Make these global so we don't push too much stuff on the stack
+TThreadStackInfo ThreadStackInfo;
+_LIT(KStackSizeText, "Stack size is %d bytes\n");
+
 TInt DoTestProcess(TInt aTestNum,TInt aArg1,TInt aArg2)
 	{
 	(void)aArg1;
 	(void)aArg2;
-
+	RThread().StackInfo(ThreadStackInfo);
 
 	switch(aTestNum)
 		{
 	case ETestProcess1:
 		{
 		test2.Printf(_L("ETestProcess1 started with %d recursion...\n"), KNumberOfFitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
+#endif
 		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
 		break;
 		}
@@ -178,6 +190,10 @@
 	case ETestProcess2:
 		{
 		test2.Printf(_L("ETestProcess2 started with %d recursion...\n"), KNumberOfFitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
+#endif
 		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
 		break;
 		}
@@ -185,6 +201,10 @@
 	case ETestProcess3:
 		{
 		test2.Printf(_L("ETestProcess3 started with %d recusion...\n"), KNumberOfUnfitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
+#endif
 		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
 		break;
 		}
@@ -192,6 +212,10 @@
 	case ETestProcess4:
 		{
 		test2.Printf(_L("ETestProcess4 started with %d recursion...\n"), KNumberOfUnfitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize);
+#endif
 		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
 		break;
 		}
@@ -199,23 +223,30 @@
 	case ETestProcess5:
 		{
 		test2.Printf(_L("ETestProcess5 started with %d recursion...\n"), KNumberOfUnfitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KDefaultStackSize * 2);
+#endif
 		test2(DummyRecursion(KNumberOfUnfitIteration)==KNumberOfUnfitIteration);
 		break;
 		}
 		
 	case ETestProcess6:
 		{
-		test2.Printf(_L("ETestProcess6 started with %d recursion...\n"), KNumberOfFitIteration);
-		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
-		break;
+		test2(EFalse); // Process creation should have failed
 		}
 
 	case ETestProcess7:
 		{
-	
 		test2.Printf(_L("ETestProcess7 started with %d recursion\n"), KNumberOfFitIteration);
-		test2.Printf(_L("(it is raised a Panic with %d bytes stack)...\n"), KDefaultStackSize/2);
-		test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
+		test2.Printf(KStackSizeText, ThreadStackInfo.iBase - ThreadStackInfo.iLimit);
+#ifndef __WINS__
+		test2((TInt) (ThreadStackInfo.iBase - ThreadStackInfo.iLimit) == KImageStackSize); // Should default to stack size set in image header
+		if (KImageStackSize == KDefaultStackSize) // If this is not the case, results can be a bit unpredictable
+			{
+			test2(DummyRecursion(KNumberOfFitIteration)==KNumberOfFitIteration);
+			}
+#endif
 		break;
 		}
 		
@@ -258,25 +289,27 @@
 	TRequestStatus rendezvous;
 
 	test.Start(_L("Create process with original Create and default stack size"));
-	TInt r = rogueP.Create(ETestProcess1, 0 );
+	TInt r = rogueP.Create(ETestProcess1, KDefaultStackSize);
 	test(r==KErrNone);
 	rogueP.Rendezvous(rendezvous);
 	rogueP.Resume();
 	User::WaitForRequest(rendezvous);
 	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
 	test(rogueP.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(rogueP);
 	
 	test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
-	r = rogueP.Create(ETestProcess2, 0 );
+	r = rogueP.Create(ETestProcess2, KDefaultStackSize);
 	test(r==KErrNone);
 	rogueP.Rendezvous(rendezvous);
 	rogueP.Resume();
 	User::WaitForRequest(rendezvous);
 	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
 	test(rogueP.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(rogueP);
 	
 	test.Next(_L("Create process with original Create and default stack size"));
-	r = rogueP.Create(ETestProcess3, 0 );
+	r = rogueP.Create(ETestProcess3, KDefaultStackSize);
 	test(r==KErrNone);
 	rogueP.Rendezvous(rendezvous);
 	rogueP.Resume();
@@ -287,22 +320,22 @@
 #else
 	test(rogueP.ExitType()==EExitKill);
 #endif
+	CLOSE_AND_WAIT(rogueP);
 	
 	test.Next(_L("Create process with CreateWithStackOverride and default stack size"));
-	r = rogueP.Create(ETestProcess4, 0 );
+	r = rogueP.Create(ETestProcess4, KDefaultStackSize);
 	test(r==KErrNone);
 	rogueP.Rendezvous(rendezvous);
 	rogueP.Resume();
 	User::WaitForRequest(rendezvous);
-	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
-	
+	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType());
 #if !defined(__WINS__)
 	test(rogueP.ExitType()==EExitPanic);
 #else
 	test(rogueP.ExitType()==EExitKill);
 #endif
-	
-	
+	CLOSE_AND_WAIT(rogueP);
+
 	test.Next(_L("Create process with CreateWithStackOverride and 2 * KDefaultStackSize stack size"));
 	r = rogueP.Create(ETestProcess5, 2 * KDefaultStackSize );
 	test(r==KErrNone);
@@ -311,6 +344,7 @@
 	User::WaitForRequest(rendezvous);
 	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
 	test(rogueP.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(rogueP);
 
 #if !defined(__WINS__)
 	test.Next(_L("Create process with CreateWithStackOverride and negative stack size"));
@@ -318,14 +352,15 @@
 	test(r==KErrArgument);
 #endif
 
-	test.Next(_L("Create process with CreateWithStackOverride and KDefaultStackSize/2 stack size"));
-	r = rogueP.Create(ETestProcess7, KDefaultStackSize / 2 );
+	test.Next(_L("Create process with CreateWithStackOverride and KImageStackSize/2 stack size"));
+	r = rogueP.Create(ETestProcess7, KImageStackSize / 2 );
 	test(r==KErrNone);
 	rogueP.Rendezvous(rendezvous);
 	rogueP.Resume();
 	User::WaitForRequest(rendezvous);
 	test.Printf(_L("ExitType:%d\n"),rogueP.ExitType() );
 	test(rogueP.ExitType()==EExitKill);
+	CLOSE_AND_WAIT(rogueP);
 	
 	test.Printf(_L("Test finished.\n"));
 	test.End();