kerneltest/e32test/dll/t_tdll12.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/dll/t_tdll12.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,363 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\dll\t_tdll12.cpp
+// Overview:
+// Test DLL Thread Local Storage data and DLL Global data access.
+// API Information:
+// Dll
+// Details:
+// - Test that the local storage of two different DLLs, when accessed from
+// two different threads is unique. Verify that results are as expected.
+// - Test the access of DLL Global data including Alloc, Read and Write. Test
+// the protection of the global data. Verify results are as expected.
+// Platforms/Drives/Compatibility:
+// All.
+// Assumptions/Requirement/Pre-requisites:
+// Failures and causes:
+// Base Port information:
+// 
+//
+
+#include "t_dll.h"
+#include "../mmu/mmudetect.h"
+
+const TInt KHeapSize=0x2000;
+
+LOCAL_D RTest test(_L("T_TDLL12"));
+
+TBool KernProt=EFalse;
+TUint8* Kern;
+TUint8* Garbage;
+
+void SetupAddresses()
+	{
+	KernProt=HaveDirectKernProt();
+	Kern=KernData();
+	TUint32 mm_attr=MemModelAttributes();
+	TUint32 mm_type=mm_attr & EMemModelTypeMask;
+	switch (mm_type)
+		{
+		case EMemModelTypeDirect:
+			Garbage=(TUint8*)0xa8000000;
+			break;
+		case EMemModelTypeMoving:
+			Garbage=(TUint8*)0x60f00000;
+			break;
+		case EMemModelTypeMultiple:
+			Garbage=(TUint8*)0xfe000000;
+			break;
+		case EMemModelTypeFlexible:
+			Garbage=(TUint8*)0x8ff00000;
+			break;
+		case EMemModelTypeEmul:
+			Garbage=(TUint8*)0xf0000000;
+			break;
+		default:
+			test(0);
+			break;
+		}
+	}
+
+void RunTestInThread(TThreadFunction aFn, TAny* aParameter, const TDesC* aPanicCat, TInt aExitCode)
+	{
+	RThread t;
+	TInt r=t.Create(KNullDesC(),aFn,0x2000,NULL,aParameter);
+	test(r==KErrNone);
+	TRequestStatus s;
+	t.Logon(s);
+	t.Resume();
+	User::WaitForRequest(s);
+	if (aPanicCat)
+		{
+		test(t.ExitType()==EExitPanic);
+		test(t.ExitCategory()==*aPanicCat);
+		test(t.ExitReason()==aExitCode);
+		}
+	else
+		{
+		test(t.ExitType()==EExitKill);
+		test(t.ExitReason()==aExitCode);
+		}
+	CLOSE_AND_WAIT(t);
+	}
+
+TInt GlobalReadThread(TAny* a)
+	{
+	return TestDll1::GlobalRead(122,*(TDes8*)a);
+	}
+
+TInt GlobalWriteThread(TAny* a)
+	{
+	return TestDll1::GlobalWrite(0,*(TDes8*)a);
+	}
+
+_LIT(KLitKernExec,"KERN-EXEC");
+void TestProtection()
+	{
+	test.Next(_L("Test protection"));
+	TBool jit=User::JustInTime();
+	User::SetJustInTime(EFalse);
+	TUint x=0xffffffff;
+	TBuf8<64> ubuf;
+	TPtrC8 uptrc(ubuf.Ptr(),11);
+	TPtr8 uptr((TUint8*)ubuf.Ptr(),1,20);
+	TPtrC8 kptrc(Kern,1);
+	TPtr8 kptr(Kern,10,256);
+	TPtrC8 gptrc(Garbage,1);
+	TPtr8 gptr(Garbage,10,256);
+	RunTestInThread(GlobalReadThread,&x,&KLitKernExec,EKUDesInfoInvalidType);
+	RunTestInThread(GlobalReadThread,&ubuf,NULL,KErrNone);
+	RunTestInThread(GlobalReadThread,&uptr,NULL,KErrNone);
+	RunTestInThread(GlobalReadThread,&uptrc,&KLitKernExec,EKUDesInfoInvalidType);
+	RunTestInThread(GlobalReadThread,&kptrc,&KLitKernExec,EKUDesInfoInvalidType);
+	RunTestInThread(GlobalReadThread,&gptrc,&KLitKernExec,EKUDesInfoInvalidType);
+	RunTestInThread(GlobalReadThread,&gptr,&KLitKernExec,ECausedException);
+	if (KernProt)
+		{
+		RunTestInThread(GlobalReadThread,Kern,&KLitKernExec,ECausedException);
+		RunTestInThread(GlobalReadThread,&kptr,&KLitKernExec,ECausedException);
+		}
+	RunTestInThread(GlobalWriteThread,&x,&KLitKernExec,EKUDesInfoInvalidType);
+	RunTestInThread(GlobalWriteThread,&ubuf,NULL,KErrNone);
+	RunTestInThread(GlobalWriteThread,&uptr,NULL,KErrNone);
+	RunTestInThread(GlobalWriteThread,&uptrc,NULL,KErrNone);
+	RunTestInThread(GlobalWriteThread,&gptrc,&KLitKernExec,ECausedException);
+	RunTestInThread(GlobalWriteThread,&gptr,&KLitKernExec,ECausedException);
+	if (KernProt)
+		{
+		RunTestInThread(GlobalWriteThread,Kern,&KLitKernExec,ECausedException);
+		RunTestInThread(GlobalWriteThread,&kptrc,&KLitKernExec,ECausedException);
+		RunTestInThread(GlobalWriteThread,&kptr,&KLitKernExec,ECausedException);
+		}
+	User::SetJustInTime(jit);
+	}
+
+LOCAL_C TInt Dll1Thread2(TAny* /*anArg*/)
+//
+// The entry point for thread2.
+//
+	{
+
+    test(TestDll1::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll1::Data()==0x12345678);
+	TestDll1::SetData(0xfedcba98);
+	test((TUint)TestDll1::Data()==0xfedcba98);
+    test(TestDll1::Attach(EFalse)==KErrNone);
+	return KErrNone;
+	}
+	
+LOCAL_C TInt Dll2Thread2(TAny* /*anArg*/)
+//
+// The entry point for thread2.
+//
+	{
+
+    test(TestDll2::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll2::Data()==0xABCDABCD);
+	TestDll2::SetData(0x12341234);
+	test((TUint)TestDll2::Data()==0x12341234);
+    test(TestDll2::Attach(EFalse)==KErrNone);
+	return KErrNone;
+	}
+
+void testGlobalAlloc()
+//
+//
+//
+	{
+
+	__KHEAP_MARK;
+	test.Start(_L("Test Dll::GlobalAlloc"));
+	TInt r;
+	test(TestDll1::GlobalAllocated()==EFalse);
+	test(TestDll2::GlobalAllocated()==EFalse);
+	r=TestDll2::GlobalAlloc(0);
+	test(r==KErrNone);
+	r=TestDll1::GlobalAlloc(256);
+	test(r==KErrNone);
+	test(TestDll1::GlobalAllocated());
+	test(TestDll2::GlobalAllocated()==EFalse);
+	r=TestDll2::GlobalAlloc(256);
+	test(r==KErrNone);
+	test(TestDll1::GlobalAllocated());
+	test(TestDll2::GlobalAllocated());
+
+	test.Next(_L("Write"));
+	// Write 256 bytes
+	TBuf8<0x100> buf100;
+	TInt i;
+	buf100.SetLength(0x100);
+	for (i=0; i<256; i++)
+		buf100[i]=(TText8)('A'+i%26);
+	r=TestDll1::GlobalWrite(0, buf100);
+	test(r==KErrNone);
+	buf100.Fill('X');
+	r=TestDll2::GlobalWrite(0, buf100);
+	test(r==KErrNone);
+
+	test.Next(_L("Read"));
+	// Read 256 bytes
+	r=TestDll1::GlobalRead(0, buf100);
+	test(r==KErrNone);
+	for (i=0; i<256; i++)
+		test(buf100[i]=='A'+i%26);
+	buf100.Fill('D');
+	r=TestDll2::GlobalRead(0, buf100);
+	test(r==KErrNone);
+	for (i=0; i<256; i++)
+		test(buf100[i]=='X');
+
+	test.Next(_L("Realloc"));
+	r=TestDll1::GlobalAlloc(128);
+	test(r==KErrNone);
+	test(TestDll1::GlobalAllocated());
+	test(TestDll2::GlobalAllocated());
+	test.Next(_L("Read"));
+	r=TestDll1::GlobalRead(0,buf100);
+	for (i=0; i<128; i++)
+		test(buf100[i]=='A'+i%26);
+	test(buf100.Length()==128);
+	r=TestDll2::GlobalRead(0,buf100);
+	test(r==KErrNone);
+	for (i=0; i<256; i++)
+		test(buf100[i]=='X');
+	test(buf100.Length()==256);
+
+	test.Next(_L("Read @ pos"));
+	// Read from position
+	r=TestDll1::GlobalRead(1, buf100);
+	test(r==KErrNone);
+	test(buf100.Length()==127);
+	for (i=0; i<127; i++)
+		test(buf100[i]=='A'+(i+1)%26);
+	test.Next(_L("Write @ pos"));
+	buf100=_L8("LALALALALALA");
+	r=TestDll1::GlobalWrite(5, buf100);
+	test(r==KErrNone);
+	buf100=_L8("POPOPOPOPO");
+	r=TestDll2::GlobalWrite(4, buf100);
+	test(r==KErrNone);
+	r=TestDll1::GlobalRead(0, buf100);
+	buf100.SetLength(20);
+	test(buf100==_L8("ABCDELALALALALALARST"));
+	r=TestDll2::GlobalRead(0, buf100);
+	buf100.SetLength(20);
+	test(buf100==_L8("XXXXPOPOPOPOPOXXXXXX"));
+
+	TestProtection();
+
+	test.Next(_L("Free Global Alloc"));
+	r=TestDll1::GlobalAlloc(0);
+	test(r==KErrNone);
+	test(TestDll1::GlobalAllocated()==EFalse);
+	test(TestDll2::GlobalAllocated());
+
+	r=TestDll2::GlobalWrite(0, _L8("WEEEEEEEEEE"));
+	test(r==KErrNone);
+	r=TestDll2::GlobalRead(0, buf100);
+	buf100.SetLength(11);
+	test(buf100==_L8("WEEEEEEEEEE"));
+	r=TestDll1::GlobalAlloc(0);
+	test(r==KErrNone);
+	r=TestDll2::GlobalAlloc(0);
+	test(r==KErrNone);
+	test(TestDll1::GlobalAllocated()==EFalse);
+	test(TestDll2::GlobalAllocated()==EFalse);
+	__KHEAP_MARKEND;
+	test.End();
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Test DLL Thread Local Storage data.
+//
+    {
+
+	test.Title();
+	SetupAddresses();
+//
+	test.Start(_L("Dll1 Thread 1"));
+    test(TestDll1::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll1::Data()==0x12345678);
+	TestDll1::SetData(0x87654321);
+	test((TUint)TestDll1::Data()==0x87654321);
+//
+	test.Next(_L("Dll1 Thread 2"));
+	RThread t;
+	TInt r=t.Create(_L("Dll1 Thread2"),Dll1Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
+	test(r==KErrNone);
+	TRequestStatus tStat;
+	t.Logon(tStat);
+	test(tStat==KRequestPending);
+	t.Resume();
+	User::WaitForRequest(tStat);
+	test(tStat==KErrNone);
+//
+	test.Next(_L("Dll1 Thread 1 again"));
+	test((TUint)TestDll1::Data()==0x87654321);
+	TestDll1::SetData(0x12345678);
+	test((TUint)TestDll1::Data()==0x12345678);
+//
+    test(TestDll1::Attach(EFalse)==KErrNone);
+//
+	test.Next(_L("Dll2 Thread 1"));
+    test(TestDll2::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll2::Data()==0xABCDABCD);
+	TestDll2::SetData(0xDCBADCBA);
+	test((TUint)TestDll2::Data()==0xDCBADCBA);
+//
+	test.Next(_L("Dll2 Thread 2"));
+	r=t.Create(_L("Dll2 Thread2"),Dll2Thread2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
+	test(r==KErrNone);
+	t.Logon(tStat);
+	test(tStat==KRequestPending);
+	t.Resume();
+	User::WaitForRequest(tStat);
+	test(tStat==KErrNone);
+//
+	test.Next(_L("Dll2 Thread 1 again"));
+	test((TUint)TestDll2::Data()==0xDCBADCBA);
+	TestDll2::SetData(0xABCDABCD);
+	test((TUint)TestDll2::Data()==0xABCDABCD);
+//
+    test(TestDll2::Attach(EFalse)==KErrNone);
+//
+	test.Next(_L("Dll1 Thread 1"));
+    test(TestDll1::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll1::Data()==0x12345678);
+	TestDll1::SetData(0x87654321);
+	test((TUint)TestDll1::Data()==0x87654321);
+//
+	test.Next(_L("Dll2 Thread 1"));
+    test(TestDll2::Attach(ETrue)==KErrNone);
+	test((TUint)TestDll2::Data()==0xABCDABCD);
+	TestDll2::SetData(0xDCBADCBA);
+	test((TUint)TestDll2::Data()==0xDCBADCBA);
+//
+	test((TUint)TestDll1::Data()==0x87654321);
+	TestDll1::SetData(0x12345678);
+	test((TUint)TestDll1::Data()==0x12345678);
+//
+	test((TUint)TestDll2::Data()==0xDCBADCBA);
+	TestDll2::SetData(0xABCDABCD);
+	test((TUint)TestDll2::Data()==0xABCDABCD);
+//
+    test(TestDll1::Attach(EFalse)==KErrNone);
+    test(TestDll2::Attach(EFalse)==KErrNone);
+//
+
+	test.End();
+	return(0);
+    }
+