|
1 // Copyright (c) 1997-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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\nkern\d_implicit.cpp |
|
15 // LDD for testing nanokernel implicit system lock |
|
16 // |
|
17 // |
|
18 |
|
19 #define __INCLUDE_NTHREADBASE_DEFINES__ |
|
20 |
|
21 #include "platform.h" |
|
22 #include "nk_priv.h" |
|
23 #include "d_implicit.h" |
|
24 |
|
25 #ifndef __SMP__ |
|
26 #include "../misc/prbs.h" |
|
27 |
|
28 const TInt KMajorVersionNumber=0; |
|
29 const TInt KMinorVersionNumber=1; |
|
30 const TInt KBuildVersionNumber=1; |
|
31 |
|
32 const TInt KStackSize=1024; |
|
33 |
|
34 inline NThreadBase::NThreadBase() |
|
35 { |
|
36 } |
|
37 |
|
38 class DImpSysTestFactory : public DLogicalDevice |
|
39 // |
|
40 // Implicit system lock test LDD factory |
|
41 // |
|
42 { |
|
43 public: |
|
44 DImpSysTestFactory(); |
|
45 virtual TInt Install(); //overriding pure virtual |
|
46 virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual |
|
47 virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual |
|
48 }; |
|
49 |
|
50 class DImpSysTest : public DLogicalChannelBase |
|
51 // |
|
52 // Implicit system lock test LDD channel |
|
53 // |
|
54 { |
|
55 public: |
|
56 DImpSysTest(); |
|
57 protected: |
|
58 virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); |
|
59 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
60 public: |
|
61 TInt CreateThread(TInt); |
|
62 TInt Start(TInt aTest); |
|
63 TInt Stop(SStats& aStats); |
|
64 static void Thread1(TAny*); |
|
65 static void Thread2(TAny*); |
|
66 static void Thread3(TAny*); |
|
67 public: |
|
68 TInt iFailCount; |
|
69 TInt iCount1; |
|
70 TInt iCount2; |
|
71 TInt iCount3; |
|
72 TInt iTestNum; |
|
73 NFastMutex iMutex; |
|
74 NThread iThread1; // holds fast mutex, imp sys |
|
75 NThread iThread2; // holds system lock, not imp sys |
|
76 NThread iThread3; // random stuff |
|
77 TUint32 iStack1[KStackSize/sizeof(TUint32)]; |
|
78 TUint32 iStack2[KStackSize/sizeof(TUint32)]; |
|
79 TUint32 iStack3[KStackSize/sizeof(TUint32)]; |
|
80 }; |
|
81 |
|
82 TInt DImpSysTest::CreateThread(TInt a) |
|
83 { |
|
84 SNThreadCreateInfo info; |
|
85 info.iStackSize=KStackSize; |
|
86 info.iPriority=(a==3)?16:12; |
|
87 info.iTimeslice=-1; |
|
88 info.iAttributes=(TUint8)((a==1)?KThreadAttImplicitSystemLock:0); |
|
89 info.iHandlers=NULL; |
|
90 info.iFastExecTable=NULL; |
|
91 info.iSlowExecTable=NULL; |
|
92 info.iParameterBlock=(const TUint32*)this; |
|
93 info.iParameterBlockSize=0; |
|
94 |
|
95 NThread* pT=NULL; |
|
96 switch (a) |
|
97 { |
|
98 case 1: |
|
99 pT=&iThread1; |
|
100 info.iFunction=&Thread1; |
|
101 info.iStackBase=iStack1; |
|
102 break; |
|
103 case 2: |
|
104 pT=&iThread2; |
|
105 info.iFunction=&Thread2; |
|
106 info.iStackBase=iStack2; |
|
107 break; |
|
108 case 3: |
|
109 pT=&iThread3; |
|
110 info.iFunction=&Thread3; |
|
111 info.iStackBase=iStack3; |
|
112 break; |
|
113 default: |
|
114 return KErrArgument; |
|
115 } |
|
116 |
|
117 return NKern::ThreadCreate(pT,info); |
|
118 } |
|
119 |
|
120 void DImpSysTest::Thread1(TAny* aPtr) |
|
121 { |
|
122 DImpSysTest& d=*(DImpSysTest*)aPtr; |
|
123 TScheduler* pS=TScheduler::Ptr(); |
|
124 NFastMutex& m=pS->iLock; |
|
125 TUint seed[2]; |
|
126 seed[0]=1; |
|
127 seed[1]=0; |
|
128 FOREVER |
|
129 { |
|
130 NKern::FMWait(&d.iMutex); |
|
131 Kern::NanoWait(1300000); // spin for 1.3ms |
|
132 TInt c = NKern::CurrentContext(); |
|
133 __NK_ASSERT_ALWAYS(c == NKern::EThread); |
|
134 NKern::FMSignal(&d.iMutex); |
|
135 if (m.iHoldingThread) |
|
136 ++d.iFailCount; |
|
137 TInt x=Random(seed)&3; |
|
138 if (x) |
|
139 NKern::Sleep(x); |
|
140 ++d.iCount1; |
|
141 } |
|
142 } |
|
143 |
|
144 void DImpSysTest::Thread2(TAny* aPtr) |
|
145 { |
|
146 DImpSysTest& d=*(DImpSysTest*)aPtr; |
|
147 TUint seed[2]; |
|
148 seed[0]=2; |
|
149 seed[1]=0; |
|
150 FOREVER |
|
151 { |
|
152 TInt c = NKern::CurrentContext(); |
|
153 __NK_ASSERT_ALWAYS(c == NKern::EThread); |
|
154 NKern::LockSystem(); |
|
155 Kern::NanoWait(1100000); // spin for 1.1ms |
|
156 NKern::UnlockSystem(); |
|
157 TInt x=Random(seed)&3; |
|
158 if (x) |
|
159 NKern::Sleep(x); |
|
160 ++d.iCount2; |
|
161 } |
|
162 } |
|
163 |
|
164 void DImpSysTest::Thread3(TAny* aPtr) |
|
165 { |
|
166 DImpSysTest& d=*(DImpSysTest*)aPtr; |
|
167 TUint seed[2]; |
|
168 seed[0]=3; |
|
169 seed[1]=0; |
|
170 if (d.iTestNum==RImpSysTest::ETestPriority) |
|
171 { |
|
172 FOREVER |
|
173 { |
|
174 TInt c = NKern::CurrentContext(); |
|
175 __NK_ASSERT_ALWAYS(c == NKern::EThread); |
|
176 TInt x=Random(seed)&15; |
|
177 NKern::Sleep(x+1); |
|
178 x=Random(seed)&1; |
|
179 TInt p=10+Random(seed)&3; |
|
180 if (x) |
|
181 NKern::ThreadSetPriority(&d.iThread1,p); |
|
182 else |
|
183 NKern::ThreadSetPriority(&d.iThread2,p); |
|
184 ++d.iCount3; |
|
185 } |
|
186 } |
|
187 else if (d.iTestNum==RImpSysTest::ETestRoundRobin) |
|
188 { |
|
189 FOREVER |
|
190 { |
|
191 TInt c = NKern::CurrentContext(); |
|
192 __NK_ASSERT_ALWAYS(c == NKern::EThread); |
|
193 TInt x=Random(seed)&15; |
|
194 NKern::Sleep(x+1); |
|
195 NKern::RotateReadyList(12); |
|
196 ++d.iCount3; |
|
197 } |
|
198 } |
|
199 else if (d.iTestNum==RImpSysTest::ETestDummy) |
|
200 { |
|
201 FOREVER |
|
202 { |
|
203 TInt c = NKern::CurrentContext(); |
|
204 __NK_ASSERT_ALWAYS(c == NKern::EThread); |
|
205 TInt x=Random(seed)&15; |
|
206 NKern::Sleep(x+1); |
|
207 x=Random(seed)&255; |
|
208 TInt p=10+Random(seed)&3; |
|
209 if (x<85) |
|
210 { |
|
211 NKern::LockSystem(); |
|
212 NKern::ThreadSetPriority(&d.iThread1,p); |
|
213 NKern::UnlockSystem(); |
|
214 } |
|
215 else if (x<170) |
|
216 { |
|
217 NKern::LockSystem(); |
|
218 NKern::ThreadSetPriority(&d.iThread2,p); |
|
219 NKern::UnlockSystem(); |
|
220 } |
|
221 else |
|
222 { |
|
223 NKern::FMWait(&d.iMutex); |
|
224 NKern::FMSignal(&d.iMutex); |
|
225 } |
|
226 ++d.iCount3; |
|
227 } |
|
228 } |
|
229 } |
|
230 |
|
231 TInt DImpSysTest::Start(TInt aTest) |
|
232 { |
|
233 if (iTestNum>=0) |
|
234 return KErrInUse; |
|
235 iTestNum=aTest; |
|
236 iFailCount=0; |
|
237 iCount1=0; |
|
238 iCount2=0; |
|
239 iCount3=0; |
|
240 new (&iMutex) NFastMutex; |
|
241 TInt r=CreateThread(1); |
|
242 if (r==KErrNone) |
|
243 r=CreateThread(2); |
|
244 if (r==KErrNone) |
|
245 r=CreateThread(3); |
|
246 if (r==KErrNone) |
|
247 { |
|
248 NKern::ThreadResume(&iThread3); |
|
249 NKern::ThreadResume(&iThread1); |
|
250 NKern::ThreadResume(&iThread2); |
|
251 } |
|
252 if (r!=KErrNone) |
|
253 iTestNum=-1; |
|
254 return r; |
|
255 } |
|
256 |
|
257 |
|
258 TInt DImpSysTest::Stop(SStats& a) |
|
259 { |
|
260 NKern::ThreadKill(&iThread1); |
|
261 NKern::ThreadKill(&iThread2); |
|
262 NKern::ThreadKill(&iThread3); |
|
263 NKern::ThreadSetPriority(&iThread1,16); |
|
264 NKern::ThreadSetPriority(&iThread2,16); |
|
265 NKern::ThreadSetPriority(&iThread3,16); |
|
266 while (iThread1.iNState!=NThread::EDead || iThread2.iNState!=NThread::EDead || iThread3.iNState!=NThread::EDead) |
|
267 NKern::Sleep(10); |
|
268 TInt size=3*(sizeof(NThread)+KStackSize)+sizeof(NFastMutex); |
|
269 memset(&iMutex,0xbb,size); |
|
270 a.iFailCount=iFailCount; |
|
271 a.iCount1=iCount1; |
|
272 a.iCount2=iCount2; |
|
273 a.iCount3=iCount3; |
|
274 iTestNum=-1; |
|
275 return KErrNone; |
|
276 } |
|
277 |
|
278 DImpSysTestFactory::DImpSysTestFactory() |
|
279 // |
|
280 // Constructor |
|
281 // |
|
282 { |
|
283 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
284 //iParseMask=0;//No units, no info, no PDD |
|
285 //iUnitsMask=0;//Only one thing |
|
286 } |
|
287 |
|
288 TInt DImpSysTestFactory::Create(DLogicalChannelBase*& aChannel) |
|
289 // |
|
290 // Create a new DImpSysTest on this logical device |
|
291 // |
|
292 { |
|
293 aChannel=new DImpSysTest; |
|
294 return aChannel?KErrNone:KErrNoMemory; |
|
295 } |
|
296 |
|
297 TInt DImpSysTestFactory::Install() |
|
298 // |
|
299 // Install the LDD - overriding pure virtual |
|
300 // |
|
301 { |
|
302 return SetName(&KLddName); |
|
303 } |
|
304 |
|
305 void DImpSysTestFactory::GetCaps(TDes8& aDes) const |
|
306 // |
|
307 // Get capabilities - overriding pure virtual |
|
308 // |
|
309 { |
|
310 TCapsImpSysTestV01 b; |
|
311 b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); |
|
312 Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); |
|
313 } |
|
314 |
|
315 DImpSysTest::DImpSysTest() |
|
316 // |
|
317 // Constructor |
|
318 // |
|
319 : iTestNum(-1) |
|
320 { |
|
321 } |
|
322 |
|
323 TInt DImpSysTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) |
|
324 // |
|
325 // Create channel |
|
326 // |
|
327 { |
|
328 |
|
329 if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) |
|
330 return KErrNotSupported; |
|
331 return KErrNone; |
|
332 } |
|
333 |
|
334 TInt DImpSysTest::Request(TInt aReqNo, TAny* a1, TAny*) |
|
335 { |
|
336 SStats s; |
|
337 TInt r=KErrNotSupported; |
|
338 switch (aReqNo) |
|
339 { |
|
340 case RImpSysTest::EControlStart: |
|
341 r=Start((TInt)a1); |
|
342 break; |
|
343 case RImpSysTest::EControlStop: |
|
344 { |
|
345 r=Stop(s); |
|
346 kumemput32(a1,&s,sizeof(s)); |
|
347 } |
|
348 break; |
|
349 default: |
|
350 break; |
|
351 } |
|
352 return r; |
|
353 } |
|
354 |
|
355 #endif |
|
356 |
|
357 |
|
358 DECLARE_STANDARD_LDD() |
|
359 { |
|
360 #ifdef __SMP__ |
|
361 return 0; // not used on SMP |
|
362 #else |
|
363 return new DImpSysTestFactory; |
|
364 #endif |
|
365 } |
|
366 |