--- /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);
+ }
+