|
1 // Copyright (c) 2005-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\bench\d_kernasmfnc.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32cmn.h> |
|
19 #include <e32cmn_private.h> |
|
20 #include <kernel/kern_priv.h> |
|
21 #include "d_kernbm.h" |
|
22 #include "d_kernasmbm.h" |
|
23 |
|
24 TUint8* UserPtr; // pointer to user-side buffer |
|
25 TUint8* KernelPtr; // pointer to kernel-side buffer |
|
26 |
|
27 NFastMutex* FastMutex; |
|
28 NFastSemaphore* FastSem; |
|
29 |
|
30 DThread* Thread; |
|
31 |
|
32 void DfcFunc(TAny*) |
|
33 { |
|
34 } |
|
35 |
|
36 TDfc Dfc(DfcFunc, NULL, Kern::DfcQue0(), 3); |
|
37 |
|
38 TPriList<TPriListLink, 64> PriList; |
|
39 |
|
40 _LIT(KObjectName, "This is a valid object name."); |
|
41 |
|
42 TBitMapAllocator* Bma; |
|
43 TInt BitmapList[32]; |
|
44 const TUint8* CharData = (const TUint8*) "Here's some char data to compare with memicmp"; |
|
45 |
|
46 // Allocate a 32-byte aligned block |
|
47 TAny* AllocAligned(TUint aSize) |
|
48 { |
|
49 TUint mem = (TUint)Kern::Alloc(aSize + 32 + 4); |
|
50 if (!mem) |
|
51 return NULL; |
|
52 TUint* ptr = (TUint*) ALIGN_ADDR(mem + 4); |
|
53 ptr[-1] = mem; |
|
54 return ptr; |
|
55 } |
|
56 |
|
57 // Free a block allocated by AllocAligned |
|
58 void FreeAligned(TAny* ptr) |
|
59 { |
|
60 Kern::Free((TAny*)((TUint*)ptr)[-1]); |
|
61 } |
|
62 |
|
63 TBitMapAllocator* AllocAlignedBMA(TInt aSize, TBool aState) |
|
64 { |
|
65 TInt nmapw=(aSize+31)>>5; |
|
66 TInt memsz=sizeof(TBitMapAllocator)+(nmapw-1)*sizeof(TUint32); |
|
67 TBitMapAllocator* pA=(TBitMapAllocator*)AllocAligned(memsz); |
|
68 if (pA) |
|
69 new(pA) TBitMapAllocator(aSize, aState); |
|
70 return pA; |
|
71 } |
|
72 |
|
73 TInt ThreadFunc(TAny* aPtr) |
|
74 { |
|
75 return KErrNone; |
|
76 } |
|
77 |
|
78 TInt InitData() |
|
79 { |
|
80 KernelPtr = (TUint8*)AllocAligned(KKernAsmBmBufferSize); |
|
81 if (!KernelPtr) |
|
82 return KErrNoMemory; |
|
83 |
|
84 Bma = AllocAlignedBMA(256, ETrue); |
|
85 if (!Bma) |
|
86 return KErrNoMemory; |
|
87 |
|
88 FastSem = (NFastSemaphore*) AllocAligned(sizeof(NFastSemaphore)); |
|
89 if (!FastSem) |
|
90 return KErrNoMemory; |
|
91 new (FastSem) NFastSemaphore; |
|
92 NKern::FSSetOwner(FastSem, NULL); |
|
93 |
|
94 FastMutex = (NFastMutex*) AllocAligned(sizeof(FastMutex)); |
|
95 if (!FastMutex) |
|
96 return KErrNoMemory; |
|
97 new (FastMutex) NFastMutex; |
|
98 |
|
99 SThreadCreateInfo info; |
|
100 info.iType=EThreadSupervisor; |
|
101 info.iFunction=ThreadFunc; |
|
102 info.iPtr=NULL; |
|
103 info.iSupervisorStack=NULL; |
|
104 info.iSupervisorStackSize=0; // zero means use default value |
|
105 info.iInitialThreadPriority=NKern::CurrentThread()->iPriority; |
|
106 info.iName.Set(_L("bmthread2")); |
|
107 info.iTotalSize = sizeof(info); |
|
108 |
|
109 NKern::ThreadEnterCS(); |
|
110 TInt r = Kern::ThreadCreate(info); |
|
111 NKern::ThreadLeaveCS(); |
|
112 if (r != KErrNone) |
|
113 return r; |
|
114 |
|
115 Thread = (DThread*)info.iHandle; |
|
116 |
|
117 return KErrNone; |
|
118 } |
|
119 |
|
120 void CloseData() |
|
121 { |
|
122 FreeAligned(KernelPtr); KernelPtr = NULL; |
|
123 FreeAligned(Bma); Bma = NULL; |
|
124 FreeAligned(FastSem); FastSem = NULL; |
|
125 FreeAligned(FastMutex); FastMutex = NULL; |
|
126 Kern::ThreadResume(*Thread); Thread = NULL; // thread will now exit |
|
127 } |
|
128 |
|
129 // 1. Functions that have C++ equivalents |
|
130 |
|
131 // 1.1 NKern |
|
132 |
|
133 // 1.1.1 DFCs |
|
134 |
|
135 DEFINE_BENCHMARK(Dfc_DoEnqueCancel, |
|
136 NKern::Lock(), |
|
137 Dfc.DoEnque(); Dfc.Cancel(), |
|
138 NKern::Unlock()); |
|
139 |
|
140 DEFINE_BENCHMARK(Dfc_AddCancel, |
|
141 NKern::Lock(), |
|
142 Dfc.Add(); Dfc.Cancel(), |
|
143 NKern::Unlock()); |
|
144 |
|
145 // Not exported: TDfc::DoEnqueFinal, TDfc::ThreadFunction |
|
146 |
|
147 // 1.1.2 Fast mutex |
|
148 |
|
149 DEFINE_BENCHMARK(NKern_LockUnlockSystem, |
|
150 , |
|
151 NKern::LockSystem(); NKern::UnlockSystem(), |
|
152 ); |
|
153 |
|
154 DEFINE_BENCHMARK(NFastMutex_WaitSignal, |
|
155 NKern::Lock(), |
|
156 FastMutex->Wait(); FastMutex->Signal(), |
|
157 NKern::Unlock()); // no contention |
|
158 |
|
159 DEFINE_BENCHMARK(NKern_FMWaitSignal, |
|
160 , |
|
161 NKern::FMWait(FastMutex); NKern::FMSignal(FastMutex), |
|
162 ); // no contention |
|
163 |
|
164 // Benchmark that exercises contention for fast mutex |
|
165 DEFINE_THREADED_BENCHMARK(NFastMutex_ThreadSwitch, |
|
166 -1, |
|
167 Kern::ThreadResume(*iThread2), |
|
168 NKern::FSWait(FastSem); NKern::FMWait(FastMutex); NKern::FMSignal(FastMutex), |
|
169 NKern::FMWait(FastMutex); NKern::FSSignal(FastSem); NKern::FMSignal(FastMutex), |
|
170 ); |
|
171 |
|
172 // Benchmark thread switching with suspend/resume for comparison |
|
173 DEFINE_THREADED_BENCHMARK(Kern_ThreadSwitch, |
|
174 1, |
|
175 , |
|
176 Kern::ThreadResume(*iThread2), |
|
177 Kern::ThreadSuspend(*iThread2, 1), |
|
178 Kern::ThreadResume(*iThread2)); |
|
179 |
|
180 // 1.1.3 Fast semaphore |
|
181 |
|
182 DEFINE_BENCHMARK(NFastSem_Wait, |
|
183 NKern::Lock(); FastSem->SignalN(aParams.iIts * 10), |
|
184 FastSem->Wait(), |
|
185 NKern::Unlock()); |
|
186 |
|
187 DEFINE_BENCHMARK(NFastSem_Signal, |
|
188 NKern::Lock(), |
|
189 FastSem->Signal(), |
|
190 FastSem->Reset(); NKern::Unlock()); |
|
191 |
|
192 DEFINE_BENCHMARK(NFastSem_SignalN, |
|
193 NKern::Lock(), |
|
194 FastSem->SignalN(1), |
|
195 FastSem->Reset(); NKern::Unlock()); |
|
196 |
|
197 DEFINE_BENCHMARK(NFastSem_Reset, |
|
198 NKern::Lock(), |
|
199 FastSem->Reset(), |
|
200 NKern::Unlock()); |
|
201 |
|
202 // NFastSemaphore::WaitCancel not exported |
|
203 |
|
204 DEFINE_THREADED_BENCHMARK(NFastSem_ThreadSwitch, |
|
205 -1, |
|
206 Kern::ThreadResume(*iThread2), |
|
207 NKern::FSWait(FastSem), |
|
208 NKern::FSSignal(FastSem), |
|
209 ); |
|
210 |
|
211 DEFINE_BENCHMARK(NKern_WaitForAnyReq, |
|
212 NKern::ThreadRequestSignal(NULL, aParams.iIts * 10), |
|
213 NKern::WaitForAnyRequest(), |
|
214 ); |
|
215 |
|
216 DEFINE_BENCHMARK(NKern_ThreadReqSignal, |
|
217 NThread* t = &Thread->iNThread; NKern::Lock(), |
|
218 NKern::ThreadRequestSignal(t), |
|
219 t->iRequestSemaphore.Reset();NKern::Unlock()); |
|
220 |
|
221 DEFINE_BENCHMARK(NKern_ThreadReqSignal2, |
|
222 NThread* t = &Thread->iNThread, |
|
223 NKern::FMWait(FastMutex); NKern::ThreadRequestSignal(t, FastMutex), |
|
224 NKern::Lock(); t->iRequestSemaphore.Reset(); NKern::Unlock();); |
|
225 |
|
226 // 1.1.4 Timers |
|
227 |
|
228 DEFINE_BENCHMARK(NTimer_OneShot, |
|
229 NTimer timer, |
|
230 timer.OneShot(100); timer.Cancel(), |
|
231 ); |
|
232 |
|
233 DEFINE_BENCHMARK(NTimer_Again, |
|
234 NTimer timer, |
|
235 timer.Again(100); timer.Cancel(), |
|
236 ); |
|
237 |
|
238 // Not exported: |
|
239 // NTimerQ::Add |
|
240 // NTimerQ::AddFinal |
|
241 // NTimerQ::DfcFn |
|
242 // NTimerQ::Dfc |
|
243 // Not tested: |
|
244 // NTimerQ::IdleTime |
|
245 |
|
246 // 1.1.5 Priority list |
|
247 |
|
248 DEFINE_BENCHMARK(TPriList_AddRemove, |
|
249 TPriListLink link(15), |
|
250 PriList.Add(&link); PriList.Remove(&link), |
|
251 ); |
|
252 |
|
253 DEFINE_BENCHMARK(TPriList_AddRemove2, |
|
254 TPriListLink link(15); TPriListLink link2(15); PriList.Add(&link2), |
|
255 PriList.Add(&link); PriList.Remove(&link), |
|
256 PriList.Remove(&link2)); |
|
257 |
|
258 DEFINE_BENCHMARK(TPriList_First, |
|
259 TPriListLink link(15); PriList.Add(&link), |
|
260 PriList.First(), |
|
261 PriList.Remove(&link)); |
|
262 |
|
263 DEFINE_BENCHMARK(TPriList_HighestPri, |
|
264 TPriListLink link(15); PriList.Add(&link), |
|
265 PriList.First(), |
|
266 PriList.Remove(&link)); |
|
267 |
|
268 DEFINE_BENCHMARK(TPriList_ChangePri, |
|
269 TPriListLink link(15); PriList.Add(&link); TInt pri = 15, |
|
270 pri ^= 32; PriList.ChangePriority(&link, pri), |
|
271 PriList.Remove(&link)); |
|
272 |
|
273 // 1.2 Kern |
|
274 |
|
275 DEFINE_BENCHMARK(Kern_ValidateFullName, |
|
276 , |
|
277 Kern::ValidateFullName(KObjectName), |
|
278 ); |
|
279 |
|
280 // 1.3. klib |
|
281 |
|
282 DEFINE_BENCHMARK(TBitMapAlloc_Ctor, |
|
283 , |
|
284 new (Bma) TBitMapAllocator(256, ETrue), |
|
285 ); |
|
286 |
|
287 DEFINE_BENCHMARK(TBitMapAlloc_AllocFree1, |
|
288 , |
|
289 Bma->Alloc(17, 119); Bma->Free(17, 119), |
|
290 ); |
|
291 |
|
292 DEFINE_BENCHMARK(TBitMapAlloc_AllocFree2, |
|
293 Bma->Alloc(0, 119), |
|
294 Bma->Free(Bma->Alloc()), |
|
295 Bma->Free(0, 119)); |
|
296 |
|
297 DEFINE_BENCHMARK(TBitMapAlloc_SelectFree, |
|
298 , |
|
299 Bma->SelectiveFree(0, 153), |
|
300 ); |
|
301 |
|
302 DEFINE_BENCHMARK(TBitMapAlloc_NotFree, |
|
303 , |
|
304 Bma->NotFree(0, 119), |
|
305 ); |
|
306 |
|
307 DEFINE_BENCHMARK(TBitMapAlloc_NotAlloc, |
|
308 , |
|
309 Bma->NotAllocated(0, 119), |
|
310 ); |
|
311 |
|
312 DEFINE_BENCHMARK(TBitMapAlloc_AllocList, |
|
313 , |
|
314 Bma->AllocList(32, BitmapList); Bma->Free(0, 32), |
|
315 ); |
|
316 |
|
317 DEFINE_BENCHMARK(TBitMapAlloc_AllocAligned, |
|
318 Bma->Alloc(0, 35); TInt a = 0; TInt b=0, |
|
319 Bma->AllocAligned(64, 3, 0, EFalse, a, b), |
|
320 Bma->Free(0, 35)); |
|
321 |
|
322 DEFINE_BENCHMARK(Kern_ValidateName, |
|
323 , |
|
324 Kern::ValidateName(KObjectName), |
|
325 ); |
|
326 |
|
327 DEFINE_BENCHMARK(memicmp, |
|
328 , |
|
329 memicmp(CharData, CharData, 49), |
|
330 ); |
|
331 |
|
332 // 2. Functions that have no C++ equivalent |
|
333 |
|
334 // 2.1. NKern |
|
335 |
|
336 DEFINE_BENCHMARK(NKern_LockedInc, |
|
337 TInt i, |
|
338 NKern::LockedInc(i), |
|
339 ); |
|
340 |
|
341 DEFINE_BENCHMARK(NKern_LockedDec, |
|
342 TInt i, |
|
343 NKern::LockedDec(i), |
|
344 ); |
|
345 |
|
346 DEFINE_BENCHMARK(NKern_LockedAdd, |
|
347 TInt i, |
|
348 NKern::LockedAdd(i, 0), |
|
349 ); |
|
350 |
|
351 DEFINE_BENCHMARK(NKern_LockedSetClear, |
|
352 TUint32 i, |
|
353 NKern::LockedSetClear(i, 0, 0), |
|
354 ); |
|
355 |
|
356 DEFINE_BENCHMARK(NKern_LockedSetClear8, |
|
357 TUint8 i, |
|
358 NKern::LockedSetClear8(i, 0, 0), |
|
359 ); |
|
360 |
|
361 DEFINE_BENCHMARK(NKern_SafeInc, |
|
362 TInt i = 0, |
|
363 NKern::SafeInc(i), |
|
364 ); |
|
365 |
|
366 DEFINE_BENCHMARK(NKern_SafeDec, |
|
367 TInt i = KMaxTInt, |
|
368 NKern::SafeDec(i), |
|
369 ); |
|
370 |
|
371 DEFINE_BENCHMARK(NKern_SafeSwap, |
|
372 TAny* i, |
|
373 NKern::SafeSwap(0, i), |
|
374 ); |
|
375 |
|
376 DEFINE_BENCHMARK(NKern_SafeSwap8, |
|
377 TUint8 i, |
|
378 NKern::SafeSwap8(0, i), |
|
379 ); |
|
380 |
|
381 DEFINE_BENCHMARK(NKern_LockUnlock, |
|
382 , |
|
383 NKern::Lock(); NKern::Unlock(), |
|
384 ); |
|
385 |
|
386 DEFINE_BENCHMARK(NKern_DisableInts1, |
|
387 , |
|
388 NKern::RestoreInterrupts(NKern::DisableInterrupts(1)), |
|
389 ); |
|
390 |
|
391 DEFINE_BENCHMARK(NKern_DisableInts2, |
|
392 , |
|
393 NKern::RestoreInterrupts(NKern::DisableInterrupts(2)), |
|
394 ); |
|
395 |
|
396 // 2.2 Kern |
|
397 |
|
398 DEFINE_BENCHMARK(Kern_NanoWait, |
|
399 , |
|
400 Kern::NanoWait(1000), |
|
401 ); // expect 1uS! |
|
402 |
|
403 DEFINE_BENCHMARK(Kern_KUSafeInc, |
|
404 umemset(UserPtr, 1, sizeof(TInt)), |
|
405 Kern::KUSafeInc(*(TInt*)UserPtr), |
|
406 ); |
|
407 |
|
408 DEFINE_BENCHMARK(Kern_KUSafeDec, |
|
409 umemset(UserPtr, KMaxTInt8, sizeof(TInt)), |
|
410 Kern::KUSafeDec(*(TInt*)UserPtr), |
|
411 ); |
|
412 |
|
413 DEFINE_BENCHMARK(DThread_ObjectFromHandle, |
|
414 DThread* thread = &Kern::CurrentThread(), |
|
415 thread->ObjectFromHandle(1), |
|
416 ); |
|
417 |
|
418 DEFINE_BENCHMARK(Kern_ObjectFromHandle, |
|
419 DThread* thread = &Kern::CurrentThread(), |
|
420 Kern::ObjectFromHandle(thread, 1, -1), |
|
421 ); |
|
422 |
|
423 DEFINE_BENCHMARK(Kern_KUSafeRead, |
|
424 TUint8 buf[128], |
|
425 Kern::KUSafeRead(UserPtr, buf, 128), |
|
426 ); |
|
427 |
|
428 DEFINE_BENCHMARK(Kern_SafeRead, |
|
429 TUint8 buf[128], |
|
430 Kern::SafeRead(KernelPtr, buf, 128), |
|
431 ); |
|
432 |
|
433 DEFINE_BENCHMARK(Kern_KUSafeWrite, |
|
434 TUint8 buf[128], |
|
435 Kern::KUSafeWrite(UserPtr, buf, 128), |
|
436 ); |
|
437 |
|
438 DEFINE_BENCHMARK(Kern_SafeWrite, |
|
439 TUint8 buf[128], |
|
440 Kern::SafeWrite(KernelPtr, buf, 128), |
|
441 ); |
|
442 |
|
443 DEFINE_BENCHMARK(Kern_SafeRead4, |
|
444 TUint8 buf[128], |
|
445 Kern::SafeRead(KernelPtr, buf, 4), |
|
446 ); |
|
447 |
|
448 DEFINE_BENCHMARK(Kern_SafeRead8, |
|
449 TUint8 buf[128], |
|
450 Kern::SafeRead(KernelPtr, buf, 8), |
|
451 ); |
|
452 |
|
453 // 2.3 klib |
|
454 |
|
455 DEFINE_BENCHMARK(umemput32_16, |
|
456 , |
|
457 umemput32(UserPtr, KernelPtr, 16), |
|
458 ); |
|
459 |
|
460 DEFINE_BENCHMARK(umemput32_4, |
|
461 , |
|
462 umemput32(UserPtr, KernelPtr, 4), |
|
463 ); |
|
464 |
|
465 DEFINE_MEMORY_BENCHMARK(umemput32_64K, |
|
466 4, |
|
467 KernelPtr, |
|
468 UserPtr, |
|
469 , |
|
470 umemput32(dest, src, 65536), |
|
471 ); |
|
472 |
|
473 DEFINE_BENCHMARK(umemput_32, |
|
474 , |
|
475 umemput(UserPtr, KernelPtr, 32), |
|
476 ); |
|
477 |
|
478 DEFINE_BENCHMARK(umemput_40, |
|
479 , |
|
480 umemput(UserPtr, KernelPtr, 40), |
|
481 ); |
|
482 |
|
483 DEFINE_MEMORY_BENCHMARK(umemput_64K, |
|
484 1, |
|
485 KernelPtr, |
|
486 UserPtr, |
|
487 , |
|
488 umemput(dest, src, 65536), |
|
489 ); |
|
490 |
|
491 DEFINE_BENCHMARK(umemget32_32, |
|
492 , |
|
493 umemget32(KernelPtr, UserPtr, 32), |
|
494 ); |
|
495 |
|
496 DEFINE_MEMORY_BENCHMARK(umemget32_64K, |
|
497 4, |
|
498 UserPtr, |
|
499 KernelPtr, |
|
500 , |
|
501 umemget32(dest, src, 65536), |
|
502 ); |
|
503 |
|
504 DEFINE_BENCHMARK(umemget_7, |
|
505 , |
|
506 umemget(KernelPtr, UserPtr, 7), |
|
507 ); |
|
508 |
|
509 DEFINE_MEMORY_BENCHMARK(umemget_64K, |
|
510 1, |
|
511 UserPtr, |
|
512 KernelPtr, |
|
513 , |
|
514 umemget(dest, src, 65536), |
|
515 ); |
|
516 |
|
517 DEFINE_BENCHMARK(umemset_64K, |
|
518 , |
|
519 umemset(UserPtr, 23, 65536), |
|
520 ); |
|
521 |
|
522 // Not exported: |
|
523 // K::ObjectFromHandle(TInt /*aHandle*/) |
|
524 // K::ObjectFromHandle(TInt /*aHandle*/, TInt /*aType*/) |
|
525 // ExecHandler::LockedInc |
|
526 // ExecHandler::LockedDec |
|
527 // ExecHandler::SafeInc |
|
528 // ExecHandler::SafeDec |