kerneltest/e32test/thread/t_smpsafe.cpp
changeset 33 0173bcd7697c
parent 0 a41df078684a
equal deleted inserted replaced
31:56f325a607ea 33:0173bcd7697c
    21 #include <e32svr.h>
    21 #include <e32svr.h>
    22 #include "u32std.h"
    22 #include "u32std.h"
    23 #include <u32hal.h>
    23 #include <u32hal.h>
    24 #include <d_ldrtst.h>
    24 #include <d_ldrtst.h>
    25 
    25 
       
    26 /////////////////////////////////////////////////////////////////////////////
       
    27 //
       
    28 //! @SYMTestCaseID			KBASE-T_SMPSAFE-2700
       
    29 //! @SYMTestType			UT
       
    30 //! @SYMPREQ				PREQ2094
       
    31 //! @SYMTestCaseDesc		SMP compatibility mode test
       
    32 //! @SYMTestActions			
       
    33 //! @SYMTestExpectedResults All tests should pass.
       
    34 //! @SYMTestPriority        Medium
       
    35 //! @SYMTestStatus          Implemented
       
    36 //
       
    37 // The test attempts to prove that the SMPSAFE compatibility mode mechanism
       
    38 // works and correctly forces processes which contain any unsafe code to run
       
    39 // as if they were on a single-cpu machine. This is done by loading and
       
    40 // unloading various combinations of DLLs into the test process itself, and
       
    41 // by spawning and exiting various EXEs.
       
    42 //
       
    43 // Two things are checked for each combination:
       
    44 //
       
    45 // 1) D_LDRTST is used to retrieve the relevant process's SMP unsafe count,
       
    46 //    the number of top-level binaries loaded into that process which are not
       
    47 //    SMP safe. This works on all systems, including uniprocessor, even if
       
    48 //    compatibility mode is not enabled, as this accounting is done
       
    49 //    unconditionally.
       
    50 //
       
    51 // 2) If the system running the test has multiple processors, and one of the
       
    52 //    compatibility modes is actually enabled, the test process runs a loop
       
    53 //    designed to see if concurrent execution of threads actually happens.
       
    54 //    (the loop is in smpsafe.cpp because it is shared between the test and
       
    55 //    the small slave programs used).
       
    56 
    26 RTest test(_L("T_SMPSAFE"));
    57 RTest test(_L("T_SMPSAFE"));
    27 RLdrTest ldd;
    58 RLdrTest ldd;
    28 
    59 
    29 RProcess pLoaded;
    60 RProcess pLoaded;
    30 TBool SMPPlatform;
    61 TBool SMPPlatform;
    31 TBool CompatMode;
    62 TBool CompatMode;
    32 
    63 
    33 extern TInt CheckAffinity();
    64 extern TInt CheckAffinity();
    34 
    65 
       
    66 // load an exe and check that it has the expected SMP unsafe count (check 1)
       
    67 // don't resume/delete it yet.
    35 void DoStartExe(RProcess& p, const TDesC &aFilename, TInt aExpectedUnsafe)
    68 void DoStartExe(RProcess& p, const TDesC &aFilename, TInt aExpectedUnsafe)
    36 	{
    69 	{
    37 	test_KErrNone(p.Create(aFilename, KNullDesC));
    70 	test_KErrNone(p.Create(aFilename, KNullDesC));
    38 	test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(p.Handle()));
    71 	test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(p.Handle()));
    39 	}
    72 	}
    40 
    73 
       
    74 // resume the exe and if compatibility mode is available, check that the
       
    75 // expected outcome of the test loop was observed (check 2)
       
    76 // delete it afterward.
    41 void DoStopExe(RProcess& p, TInt aExpectedUnsafe)
    77 void DoStopExe(RProcess& p, TInt aExpectedUnsafe)
    42 	{
    78 	{
    43 	TRequestStatus s;
    79 	TRequestStatus s;
    44 	p.Logon(s);
    80 	p.Logon(s);
    45 	p.Resume();
    81 	p.Resume();
    60 void StopExe(TInt aExpectedUnsafe)
    96 void StopExe(TInt aExpectedUnsafe)
    61 	{
    97 	{
    62 	DoStopExe(pLoaded, aExpectedUnsafe);
    98 	DoStopExe(pLoaded, aExpectedUnsafe);
    63 	}
    99 	}
    64 
   100 
       
   101 // start and stop an exe, doing both checks 1 and 2.
    65 void TryExe(const TDesC &aFilename, TInt aExpectedUnsafe)
   102 void TryExe(const TDesC &aFilename, TInt aExpectedUnsafe)
    66 	{
   103 	{
    67 	RProcess p;
   104 	RProcess p;
    68 	DoStartExe(p, aFilename, aExpectedUnsafe);
   105 	DoStartExe(p, aFilename, aExpectedUnsafe);
    69 	DoStopExe(p, aExpectedUnsafe);
   106 	DoStopExe(p, aExpectedUnsafe);
    70 	}
   107 	}
    71 
   108 
       
   109 // check the main test process, both checks 1 and 2.
    72 void CheckSelf(TInt aExpectedUnsafe)
   110 void CheckSelf(TInt aExpectedUnsafe)
    73 	{
   111 	{
    74 	test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(RProcess().Handle()));
   112 	test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(RProcess().Handle()));
    75 	if (CompatMode)
   113 	if (CompatMode)
    76 		test_Equal(aExpectedUnsafe ? 1 : 0, CheckAffinity());
   114 		test_Equal(aExpectedUnsafe ? 1 : 0, CheckAffinity());
    91 
   129 
    92 	test.Next(_L("Get number of CPUs"));
   130 	test.Next(_L("Get number of CPUs"));
    93 	TInt cpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
   131 	TInt cpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
    94 	test_Compare(cpus, >, 0);
   132 	test_Compare(cpus, >, 0);
    95 	SMPPlatform = cpus > 1;
   133 	SMPPlatform = cpus > 1;
    96 
   134 	if (!SMPPlatform)
    97 	test.Next(_L("Get compatibility mode setting"));
       
    98 	TInt flags = UserSvr::HalFunction(EHalGroupKernel, EKernelHalConfigFlags, 0, 0);
       
    99 	test_Compare(flags, >=, 0);
       
   100 	CompatMode = flags & (EKernelConfigSMPUnsafeCompat | EKernelConfigSMPUnsafeCPU0);
       
   101 	if (SMPPlatform && !CompatMode)
       
   102 		{
   135 		{
   103 		test.Printf(_L("*************************************************\n"));
   136 		CompatMode = EFalse;
   104 		test.Printf(_L("Compatibility mode is not enabled, not testing it\n"));
   137 		test.Printf(_L("*****************************************************\n"));
   105 		test.Printf(_L("*************************************************\n"));
   138 		test.Printf(_L("Uniprocessor system, not actually testing compat mode\n"));
       
   139 		test.Printf(_L("*****************************************************\n"));
       
   140 		}
       
   141 	else
       
   142 		{
       
   143 		test.Next(_L("Get compatibility mode setting"));
       
   144 		TInt flags = UserSvr::HalFunction(EHalGroupKernel, EKernelHalConfigFlags, 0, 0);
       
   145 		test_Compare(flags, >=, 0);
       
   146 		CompatMode = flags & (EKernelConfigSMPUnsafeCompat | EKernelConfigSMPUnsafeCPU0);
       
   147 		if (!CompatMode)
       
   148 			{
       
   149 			test.Printf(_L("*************************************************\n"));
       
   150 			test.Printf(_L("Compatibility mode is not enabled, not testing it\n"));
       
   151 			test.Printf(_L("*************************************************\n"));
       
   152 			}
   106 		}
   153 		}
   107 
   154 
   108 	test.Next(_L("Load test LDD"));
   155 	test.Next(_L("Load test LDD"));
   109 	TInt r = User::LoadLogicalDevice(_L("d_ldrtst.ldd"));
   156 	TInt r = User::LoadLogicalDevice(_L("d_ldrtst.ldd"));
   110 	test(r==KErrNone || r==KErrAlreadyExists);
   157 	test(r==KErrNone || r==KErrAlreadyExists);