Update contrib.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\thread\t_smpsafe.cpp
18 #define __E32TEST_EXTENSION__
26 /////////////////////////////////////////////////////////////////////////////
28 //! @SYMTestCaseID KBASE-T_SMPSAFE-2700
31 //! @SYMTestCaseDesc SMP compatibility mode test
33 //! @SYMTestExpectedResults All tests should pass.
34 //! @SYMTestPriority Medium
35 //! @SYMTestStatus Implemented
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.
43 // Two things are checked for each combination:
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
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).
57 RTest test(_L("T_SMPSAFE"));
64 extern TInt CheckAffinity();
66 // load an exe and check that it has the expected SMP unsafe count (check 1)
67 // don't resume/delete it yet.
68 void DoStartExe(RProcess& p, const TDesC &aFilename, TInt aExpectedUnsafe)
70 test_KErrNone(p.Create(aFilename, KNullDesC));
71 test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(p.Handle()));
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.
77 void DoStopExe(RProcess& p, TInt aExpectedUnsafe)
82 User::WaitForRequest(s);
84 test_Equal(aExpectedUnsafe ? 1 : 0, s.Int());
85 test_Equal(EExitKill, p.ExitType());
86 p.NotifyDestruction(s);
88 User::WaitForRequest(s);
91 void StartExe(const TDesC &aFilename, TInt aExpectedUnsafe)
93 DoStartExe(pLoaded, aFilename, aExpectedUnsafe);
96 void StopExe(TInt aExpectedUnsafe)
98 DoStopExe(pLoaded, aExpectedUnsafe);
101 // start and stop an exe, doing both checks 1 and 2.
102 void TryExe(const TDesC &aFilename, TInt aExpectedUnsafe)
105 DoStartExe(p, aFilename, aExpectedUnsafe);
106 DoStopExe(p, aExpectedUnsafe);
109 // check the main test process, both checks 1 and 2.
110 void CheckSelf(TInt aExpectedUnsafe)
112 test_Equal(aExpectedUnsafe, ldd.ProcessSMPUnsafeCount(RProcess().Handle()));
114 test_Equal(aExpectedUnsafe ? 1 : 0, CheckAffinity());
117 GLDEF_C TInt E32Main()
121 // Turn off evil lazy dll unloading
123 test(ldr.Connect()==KErrNone);
124 test(ldr.CancelLazyDllUnload()==KErrNone);
128 test.Start(_L("Test SMP safe binary flag"));
130 test.Next(_L("Get number of CPUs"));
131 TInt cpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
132 test_Compare(cpus, >, 0);
133 SMPPlatform = cpus > 1;
137 test.Printf(_L("*****************************************************\n"));
138 test.Printf(_L("Uniprocessor system, not actually testing compat mode\n"));
139 test.Printf(_L("*****************************************************\n"));
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);
149 test.Printf(_L("*************************************************\n"));
150 test.Printf(_L("Compatibility mode is not enabled, not testing it\n"));
151 test.Printf(_L("*************************************************\n"));
155 test.Next(_L("Load test LDD"));
156 TInt r = User::LoadLogicalDevice(_L("d_ldrtst.ldd"));
157 test(r==KErrNone || r==KErrAlreadyExists);
158 test_KErrNone(ldd.Open());
160 test.Next(_L("Check we are safe ourselves"));
163 test.Next(_L("Check safe exe"));
164 StartExe(_L("smpsafe0.exe"), 0);
165 test.Next(_L("Load already loaded safe exe (self)"));
166 TryExe(_L("smpsafe0.exe"), 0);
169 test.Next(_L("Check safe XIP exe"));
170 StartExe(_L("smpsafex0.exe"), 0);
171 test.Next(_L("Load already loaded safe XIP exe (self)"));
172 TryExe(_L("smpsafex0.exe"), 0);
175 test.Next(_L("Load unsafe exe"));
176 StartExe(_L("smpsafe1.exe"), 1);
177 test.Next(_L("Load already loaded unsafe exe"));
178 TryExe(_L("smpsafe1.exe"), 1);
181 test.Next(_L("Load safe exe directly linked to unsafe dll"));
182 TryExe(_L("smpsafe2.exe"), 1);
184 test.Next(_L("Dynamically load unsafe dll"));
185 test_KErrNone(l.Load(_L("smpsafea.dll")));
187 test.Next(_L("Load safe exe directly linked to loaded unsafe dll"));
188 TryExe(_L("smpsafe2.exe"), 1);
189 test.Next(_L("Dynamically unload unsafe dll"));
193 test.Next(_L("Load safe XIP exe directly linked to unsafe XIP dll"));
194 TryExe(_L("smpsafex2.exe"), 1);
196 test.Next(_L("Dynamically load unsafe XIP dll"));
197 test_KErrNone(l.Load(_L("smpsafexa.dll")));
199 test.Next(_L("Load safe XIP exe directly linked to loaded unsafe XIP dll"));
200 TryExe(_L("smpsafex2.exe"), 1);
201 test.Next(_L("Dynamically unload unsafe XIP dll"));
205 test.Next(_L("Load safe exe indirectly linked to unsafe dll"));
206 TryExe(_L("smpsafe3.exe"), 1);
208 test.Next(_L("Dynamically load unsafe dll"));
209 test_KErrNone(l.Load(_L("smpsafea.dll")));
211 test.Next(_L("Load safe exe indirectly linked to loaded unsafe dll"));
212 TryExe(_L("smpsafe3.exe"), 1);
213 test.Next(_L("Dynamically unload unsafe dll"));
217 test.Next(_L("Dynamically load safe dll linked to unsafe dll"));
218 test_KErrNone(l.Load(_L("smpsafeb.dll")));
220 test.Next(_L("Load safe exe indirectly linked to unsafe dll, inbetween loaded"));
221 TryExe(_L("smpsafe3.exe"), 1);
222 test.Next(_L("Dynamically load unsafe dll as well"));
223 test_KErrNone(l2.Load(_L("smpsafea.dll")));
225 test.Next(_L("Dynamically unload safe dll linked to unsafe dll"));
228 test.Next(_L("Dynamically unload unsafe dll as well"));
232 test.Next(_L("Load safe exe directly linked to unsafe XIP dll"));
233 TryExe(_L("smpsafe4.exe"), 1);
235 test.Next(_L("Dynamically load unsafe XIP dll"));
236 test_KErrNone(l.Load(_L("smpsafexa.dll")));
238 test.Next(_L("Load safe exe directly linked to loaded unsafe XIP dll"));
239 TryExe(_L("smpsafe4.exe"), 1);
240 test.Next(_L("Dynamically unload unsafe XIP dll"));
244 test.Next(_L("Dynamically load figure-eight dll cycle"));
245 test_KErrNone(l.Load(_L("smpsafec.dll")));
247 test.Next(_L("Load figure-eight from a different point"));
248 test_KErrNone(l2.Load(_L("smpsafed.dll")));
250 test.Next(_L("Unload original point"));
253 test.Next(_L("Unload second point"));
257 test.Next(_L("Close test LDD"));
259 test_KErrNone(User::FreeLogicalDevice(KLdrTestLddName));