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); |