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\nkernsa\benchmark.cpp
18 #include <nktest/nkutils.h>
20 typedef void (*PFV)(void);
23 extern "C" TUint32 __get_static_data();
24 extern "C" TUint32 __get_rwno_tid();
25 extern "C" TUint32 __cpu_id();
26 extern "C" TUint32 __trace_cpu_num();
28 extern "C" TUint32 __get_local_timer_address();
29 extern "C" TUint32 __get_local_timer_count();
30 extern "C" TUint32 __set_local_timer_count();
31 extern "C" TUint32 __swp_local_timer_count();
33 void DoWatchdogTimerTest();
42 TSpinLock SL1(TSpinLock::EOrderGenericIrqLow0);
43 TSpinLock SL2(TSpinLock::EOrderGenericPreLow0);
46 NThread* PingPongThread;
47 NFastSemaphore PingPongExitSem;
48 void PingPong(TAny* aPtr)
50 NThread* t = (NThread*)aPtr;
53 NKern::WaitForAnyRequest();
55 NKern::ThreadRequestSignal(t);
59 void SetupPingPongThread(TInt aPri, TInt aCpu, TBool aReply=TRUE)
61 NThread* t = NKern::CurrentThread();
62 NKern::FSSetOwner(&PingPongExitSem, t);
63 PingPongThread = CreateThreadSignalOnExit("PingPong", &PingPong, aPri, aReply?t:0, 0, -1, &PingPongExitSem, aCpu);
66 void DestroyPingPongThread()
68 NKern::ThreadKill(PingPongThread);
69 NKern::FSWait(&PingPongExitSem);
72 extern "C" void dummy()
76 extern "C" void sleep1()
81 extern "C" void do_atomic_add_rlx32()
83 __e32_atomic_add_rlx32(&Counter, 1);
86 extern "C" void do_atomic_add_rel32()
88 __e32_atomic_add_rel32(&Counter, 1);
91 extern "C" void do_atomic_add_acq32()
93 __e32_atomic_add_acq32(&Counter, 1);
96 extern "C" void do_atomic_add_ord32()
98 __e32_atomic_add_ord32(&Counter, 1);
101 extern "C" void dis_ena_int()
103 TInt irq = NKern::DisableAllInterrupts();
104 NKern::RestoreInterrupts(irq);
107 extern "C" void dis_ena_preempt()
114 extern "C" void sl1_lock_unlock_irq()
120 extern "C" void sl1_lock_unlock_irq_save()
122 TInt irq = SL1.LockIrqSave();
123 SL1.UnlockIrqRestore(irq);
126 extern "C" void sl1_lock_unlock_only()
128 TInt irq = NKern::DisableAllInterrupts();
131 NKern::RestoreInterrupts(irq);
134 extern "C" void sl2_lock_unlock_only()
143 extern "C" void lock_unlock_system()
146 NKern::UnlockSystem();
149 extern "C" void enter_leave_cs()
151 NKern::ThreadEnterCS();
152 NKern::ThreadLeaveCS();
155 extern "C" void resched_to_same()
163 extern "C" void get_timestamp()
171 extern "C" void sem_signal()
173 NKern::FSSignal(&Sem);
176 extern "C" void sem_signal_wait()
178 NKern::FSSignal(&Sem);
185 void BenchmarkDfcFn(TAny* aPtr)
187 NThread* t = (NThread*)aPtr;
189 NKern::ThreadRequestSignal(t);
192 void BenchmarkIDfcFn(TAny* aPtr)
194 NThread* t = (NThread*)aPtr;
199 void SetupBenchmarkDfcQ(TInt aPri, TInt aCpu, TBool aReply=TRUE)
201 NThread* t = NKern::CurrentThread();
204 DfcQ = CreateDfcQ("Benchmark", aPri, (TUint32)aCpu);
205 Dfc = new TDfc(&BenchmarkDfcFn, aReply?t:0, DfcQ, 1);
208 Dfc = new TDfc(&BenchmarkIDfcFn, aReply?t:0);
211 void DestroyBenchmarkDfcQ()
224 TUint32 Ps(TUint64 x)
232 TUint64 Iterate(PFV f, TUint32 aCount)
234 TUint64 initial = fast_counter();
239 TUint64 final = fast_counter();
240 return final - initial;
243 TUint32 Measure(PFV f)
249 time = Iterate(f, n);
250 } while(time < Threshold);
255 return (TUint32)time;
258 void ping_pong_threads()
260 NKern::ThreadRequestSignal(PingPongThread);
261 NKern::WaitForAnyRequest();
264 void ping_pong_threads_nr()
266 NKern::ThreadRequestSignal(PingPongThread);
269 TUint32 DoPingPongTest(TInt aPri, TInt aCpu, TBool aReply=TRUE)
271 SetupPingPongThread(aPri, aCpu, aReply);
274 x = Measure(&ping_pong_threads);
276 x = Measure(&ping_pong_threads_nr);
277 DestroyPingPongThread();
278 TEST_PRINT4("PingPong: Pri %2d Cpu %2d Reply %1d -> %ups", aPri, aCpu, aReply, x);
285 NKern::WaitForAnyRequest();
288 void do_dfc_test_nr()
298 NKern::WaitForAnyRequest();
301 void do_idfc_test_nr()
308 TUint32 DoDfcTest(TInt aPri, TInt aCpu, TBool aReply=TRUE)
310 SetupBenchmarkDfcQ(aPri, aCpu, aReply);
312 PFV f = aReply ? (aPri<0 ? &do_idfc_test : &do_dfc_test) : (aPri<0 ? &do_idfc_test_nr : &do_dfc_test_nr);
314 DestroyBenchmarkDfcQ();
315 TEST_PRINT4("Dfc: Pri %2d Cpu %2d Reply %1d -> %ups", aPri, aCpu, aReply, x);
319 void BenchmarkTests()
321 TUint64 fcf = fast_counter_freq();
322 Threshold = (TUint32)fcf;
323 if (Threshold > 10000000u)
325 else if (Threshold > 1000000u)
326 Threshold = 1000000u;
327 TUint64 ps_per_tick = UI64LIT(1000000000000);
329 PsPerTick = (TUint32)ps_per_tick;
330 TEST_PRINT1("Threshold %u", Threshold);
331 TEST_PRINT1("PsPerTick %u", PsPerTick);
333 TUint32 dummy_time = Measure(&dummy);
334 TEST_PRINT1("Dummy %ups", dummy_time);
336 TUint32 dmb_time = Measure(&__e32_memory_barrier);
337 TEST_PRINT1("DMB loop %ups", dmb_time);
338 dmb_time -= dummy_time;
339 TEST_PRINT1("DMB %ups", dmb_time);
341 TUint32 dsb_time = Measure(&__e32_io_completion_barrier);
342 TEST_PRINT1("DSB loop %ups", dsb_time);
343 dsb_time -= dummy_time;
344 TEST_PRINT1("DSB %ups", dsb_time);
347 TUint32 timestamp_time = Measure(&get_timestamp) - dummy_time;
348 TEST_PRINT1("NKern::Timestamp() %ups", timestamp_time);
352 ps = Measure(&sleep1);
353 TEST_PRINT1("Sleep(1) %ups", ps-dummy_time);
354 ps = Measure(&do_atomic_add_rlx32);
355 TEST_PRINT1("atomic_add_rlx32 %ups", ps-dummy_time);
356 ps = Measure(&do_atomic_add_acq32);
357 TEST_PRINT1("atomic_add_acq32 %ups", ps-dummy_time);
358 ps = Measure(&do_atomic_add_rel32);
359 TEST_PRINT1("atomic_add_rel32 %ups", ps-dummy_time);
360 ps = Measure(&do_atomic_add_ord32);
361 TEST_PRINT1("atomic_add_ord32 %ups", ps-dummy_time);
363 TUint32 dis_ena_int_time = Measure(&dis_ena_int) - dummy_time;
364 TEST_PRINT1("dis_ena_int %ups", dis_ena_int_time);
366 TUint32 dis_ena_preempt_time = Measure(&dis_ena_preempt) - dummy_time;
367 TEST_PRINT1("dis_ena_preempt %ups", dis_ena_preempt_time);
370 TUint32 sl1_irq_time = Measure(&sl1_lock_unlock_irq) - dummy_time;
371 TEST_PRINT1("sl1_irq_time %ups", sl1_irq_time);
373 TUint32 sl1_irqsave_time = Measure(&sl1_lock_unlock_irq_save) - dummy_time;
374 TEST_PRINT1("sl1_irqsave_time %ups", sl1_irqsave_time);
376 TUint32 sl1_only_time = Measure(&sl1_lock_unlock_only) - dis_ena_int_time - dummy_time;
377 TEST_PRINT1("sl1_only_time %ups", sl1_only_time);
379 TUint32 sl2_only_time = Measure(&sl2_lock_unlock_only) - dis_ena_preempt_time - dummy_time;
380 TEST_PRINT1("sl2_only_time %ups", sl2_only_time);
383 TUint32 lock_unlock_system_time = Measure(&lock_unlock_system) - dummy_time;
384 TEST_PRINT1("lock_unlock_system_time %ups", lock_unlock_system_time);
386 TUint32 enter_leave_cs_time = Measure(&enter_leave_cs) - dummy_time;
387 TEST_PRINT1("enter_leave_cs_time %ups", enter_leave_cs_time);
389 TUint32 resched_to_same_time = Measure(&resched_to_same) - dummy_time;
390 TEST_PRINT1("resched_to_same_time %ups", resched_to_same_time);
393 TUint32 get_static_data_time = Measure((PFV)&__get_static_data) - dummy_time;
394 TEST_PRINT1("get_static_data_time %ups", get_static_data_time);
396 TUint32 get_sp_time = Measure((PFV)&__stack_pointer) - dummy_time;
397 TEST_PRINT1("get_sp_time %ups", get_sp_time);
399 TUint32 get_cpsr_time = Measure((PFV)&__cpu_status_reg) - dummy_time;
400 TEST_PRINT1("get_cpsr_time %ups", get_cpsr_time);
403 TUint32 get_cpu_id_time = Measure((PFV)&__cpu_id) - dummy_time;
404 TEST_PRINT1("get_cpu_id_time %ups", get_cpu_id_time);
406 TUint32 trace_cpu_num_time = Measure((PFV)&__trace_cpu_num) - dummy_time;
407 TEST_PRINT1("trace_cpu_num_time %ups", trace_cpu_num_time);
409 TUint32 get_rwno_tid_time = Measure((PFV)&__get_rwno_tid) - dummy_time;
410 TEST_PRINT1("get_rwno_tid_time %ups", get_rwno_tid_time);
412 TUint32 get_lta_time = Measure((PFV)&__get_local_timer_address) - dummy_time;
413 TEST_PRINT1("get_local_timer_address %ups", get_lta_time);
415 TUint32 get_ltc_time = Measure((PFV)&__get_local_timer_count) - dummy_time;
416 TEST_PRINT1("get_local_timer_count %ups", get_ltc_time);
418 TUint32 set_ltc_time = Measure((PFV)&__set_local_timer_count) - dummy_time;
419 TEST_PRINT1("set_local_timer_count %ups", set_ltc_time);
421 TUint32 swp_ltc_time = Measure((PFV)&__swp_local_timer_count) - dummy_time;
422 TEST_PRINT1("swp_local_timer_count %ups", swp_ltc_time);
425 TUint32 get_current_thread_time = Measure((PFV)&NKern::CurrentThread) - dummy_time;
426 TEST_PRINT1("get_current_thread_time %ups", get_current_thread_time);
429 TUint32 get_current_threadL_time = Measure((PFV)&NCurrentThreadL) - dummy_time;
430 TEST_PRINT1("get_current_threadL_time %ups", get_current_threadL_time);
434 NThread* t = NKern::CurrentThread();
435 NKern::FSSetOwner(&Sem, t);
437 TUint32 sem_signal_time = Measure(&sem_signal) - dummy_time;
438 TEST_PRINT1("sem_signal_time %ups", sem_signal_time);
440 new (&Sem) NFastSemaphore(t);
442 TUint32 sem_signal_wait_time = Measure(&sem_signal_wait) - dummy_time;
443 TEST_PRINT1("sem_signal_wait_time %ups", sem_signal_wait_time);
445 DoPingPongTest(31, 0);
446 DoPingPongTest(11, 0);
447 DoPingPongTest(31, 1);
448 DoPingPongTest(11, 1);
449 DoPingPongTest(31, -1);
450 DoPingPongTest(11, -1);
451 DoPingPongTest(31, 0, FALSE);
459 DoDfcTest(31, 0, FALSE);
460 DoDfcTest(-1, 0, TRUE);
461 DoDfcTest(-1, 0, FALSE);
462 #if defined(__MARM__) && defined(__SMP__)
463 DoWatchdogTimerTest();