📄 tm_basic.cxx
字号:
wait_for_tick(); // Wait until the next clock tick to minimize aberations
for (i = 0; i < ntimers; i++) {
HAL_CLOCK_READ(&timer_ft[i].start);
sigev.sigev_signo = SIGRTMIN;
sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
res = timer_create( CLOCK_REALTIME, &sigev, &timers[i]);
HAL_CLOCK_READ(&timer_ft[i].end);
CYG_ASSERT( res == 0 , "timer_create() returned error");
}
show_times(timer_ft, ntimers, "Create timer");
wait_for_tick(); // Wait until the next clock tick to minimize aberations
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 0;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 0;
for (i = 0; i < ntimers; i++) {
HAL_CLOCK_READ(&timer_ft[i].start);
res = timer_settime( timers[i], 0, &tp, NULL );
HAL_CLOCK_READ(&timer_ft[i].end);
CYG_ASSERT( res == 0 , "timer_settime() returned error");
}
show_times(timer_ft, ntimers, "Initialize timer to zero");
wait_for_tick(); // Wait until the next clock tick to minimize aberations
tp.it_value.tv_sec = 1;
tp.it_value.tv_nsec = 250000000;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 0;
for (i = 0; i < ntimers; i++) {
HAL_CLOCK_READ(&timer_ft[i].start);
res = timer_settime( timers[i], 0, &tp, NULL );
HAL_CLOCK_READ(&timer_ft[i].end);
CYG_ASSERT( res == 0 , "timer_settime() returned error");
}
show_times(timer_ft, ntimers, "Initialize timer to 1.25 sec");
wait_for_tick(); // Wait until the next clock tick to minimize aberations
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 0;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 0;
for (i = 0; i < ntimers; i++) {
HAL_CLOCK_READ(&timer_ft[i].start);
res = timer_settime( timers[i], 0, &tp, NULL );
HAL_CLOCK_READ(&timer_ft[i].end);
CYG_ASSERT( res == 0 , "timer_settime() returned error");
}
show_times(timer_ft, ntimers, "Disable timer");
wait_for_tick(); // Wait until the next clock tick to minimize aberations
for (i = 0; i < ntimers; i++) {
HAL_CLOCK_READ(&timer_ft[i].start);
res = timer_delete( timers[i] );
HAL_CLOCK_READ(&timer_ft[i].end);
CYG_ASSERT( res == 0 , "timer_settime() returned error");
}
show_times(timer_ft, ntimers, "Delete timer");
sigev.sigev_signo = SIGRTMIN+1;
sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
CYG_ASSERT( res == 0 , "timer_create() returned error");
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 50000000;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 50000000;;
timer_cnt = 0;
res = timer_settime( timers[0], 0, &tp, NULL );
CYG_ASSERT( res == 0 , "timer_settime() returned error");
sem_init(&synchro, 0, 0);
wait_for_tick(); // Wait until the next clock tick to minimize aberations
do
{ res = sem_wait(&synchro);
} while( res == -1 && errno == EINTR );
CYG_ASSERT( res == 0 , "sem_wait() returned error");
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 0;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 0;
res = timer_settime( timers[0], 0, &tp, NULL );
CYG_ASSERT( res == 0 , "timer_settime() returned error");
res = timer_delete( timers[0] );
CYG_ASSERT( res == 0 , "timer_delete() returned error");
show_times(sched_ft, nscheds, "Timer latency [0 threads]");
struct sched_param schedparam;
pthread_attr_t attr;
void *retval;
// Set my priority higher than any I plan to create
schedparam.sched_priority = 20;
pthread_setschedparam( pthread_self(), SCHED_RR, &schedparam );
// Initiaize thread creation attributes
pthread_attr_init( &attr );
pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
pthread_attr_setschedpolicy( &attr, SCHED_RR );
schedparam.sched_priority = 10;
pthread_attr_setschedparam( &attr, &schedparam );
for (i = 0; i < 2; i++) {
pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
pthread_attr_setstacksize( &attr, STACK_SIZE );
res = pthread_create( &threads[i],
&attr,
timer_test,
(void *)i
);
CYG_ASSERT( res == 0 , "pthread_create() returned error");
}
wait_for_tick(); // Wait until the next clock tick to minimize aberations
sigev.sigev_signo = SIGRTMIN+1;
sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
CYG_ASSERT( res == 0 , "timer_create() returned error");
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 50000000;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 50000000;;
timer_cnt = 0;
res = timer_settime( timers[0], 0, &tp, NULL );
CYG_ASSERT( res == 0 , "timer_settime() returned error");
sem_init(&synchro, 0, 0);
do
{ res = sem_wait(&synchro);
} while( res == -1 && errno == EINTR );
CYG_ASSERT( res == 0 , "sem_wait() returned error");
res = timer_delete(timers[0]);
CYG_ASSERT( res == 0 , "timerdelete() returned error");
show_times(sched_ft, nscheds, "Timer latency [2 threads]");
for (i = 0; i < 2; i++) {
pthread_cancel(threads[i]);
pthread_join(threads[i], &retval);
}
for (i = 0; i < ntest_threads; i++) {
pthread_attr_setstackaddr( &attr, &stacks[i][STACK_SIZE] );
pthread_attr_setstacksize( &attr, STACK_SIZE );
res = pthread_create( &threads[i],
&attr,
timer_test,
(void *)i
);
CYG_ASSERT( res == 0 , "pthread_create() returned error");
}
wait_for_tick(); // Wait until the next clock tick to minimize aberations
sigev.sigev_signo = SIGRTMIN+1;
sigev.sigev_value.sival_ptr = (void*)(&timers[i]);
res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
CYG_ASSERT( res == 0 , "timer_create() returned error");
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 50000000;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 50000000;;
timer_cnt = 0;
res = timer_settime( timers[0], 0, &tp, NULL );
CYG_ASSERT( res == 0 , "timer_settime() returned error");
sem_init(&synchro, 0, 0);
do
{ res = sem_wait(&synchro);
} while( res == -1 && errno == EINTR );
CYG_ASSERT( res == 0 , "sem_wait() returned error");
res = timer_delete(timers[0]);
CYG_ASSERT( res == 0 , "timerdelete() returned error");
show_times(sched_ft, nscheds, "Timer latency [many threads]");
for (i = 0; i < ntest_threads; i++) {
pthread_cancel(threads[i]);
pthread_join(threads[i], &retval);
}
sem_init(&synchro, 0, 0);
sem_init(&timer_sem, 0, 0);
pthread_attr_setstackaddr( &attr, &stacks[0][STACK_SIZE] );
pthread_attr_setstacksize( &attr, STACK_SIZE );
res = pthread_create( &threads[0],
&attr,
timer_test2,
(void *)0
);
CYG_ASSERT( res == 0 , "pthread_create() returned error");
wait_for_tick(); // Wait until the next clock tick to minimize aberations
sigev.sigev_signo = SIGRTMIN+2;
sigev.sigev_value.sival_ptr = (void*)(threads[0]);
res = timer_create( CLOCK_REALTIME, &sigev, &timers[0]);
CYG_ASSERT( res == 0 , "timer_create() returned error");
tp.it_value.tv_sec = 0;
tp.it_value.tv_nsec = 50000000;
tp.it_interval.tv_sec = 0;
tp.it_interval.tv_nsec = 50000000;;
timer_cnt = 0;
res = timer_settime( timers[0], 0, &tp, NULL );
CYG_ASSERT( res == 0 , "timer_settime() returned error");
do
{ res = sem_wait(&synchro);
} while( res == -1 && errno == EINTR );
CYG_ASSERT( res == 0 , "sem_wait() returned error");
res = timer_delete(timers[0]);
CYG_ASSERT( res == 0 , "timerdelete() returned error");
show_times(sched_ft, nscheds, "Timer -> thread post latency");
sem_post(&timer_sem);
// pthread_cancel(threads[0]);
pthread_join(threads[0], &retval);
end_of_test_group();
}
//--------------------------------------------------------------------------
void
run_all_tests()
{
int i;
cyg_uint32 tv[nsamples], tv0, tv1;
// cyg_uint32 min_stack, max_stack, total_stack, actual_stack, j;
cyg_tick_count_t ticks, tick0, tick1;
#ifdef CYG_SCHEDULER_LOCK_TIMINGS
cyg_uint32 lock_ave, lock_max;
#endif
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
cyg_int32 clock_ave;
#endif
disable_clock_latency_measurement();
// cyg_test_dump_thread_stack_stats( "Startup, main stack", thread[0] );
cyg_test_dump_interrupt_stack_stats( "Startup" );
cyg_test_dump_idlethread_stack_stats( "Startup" );
cyg_test_clear_interrupt_stack();
diag_printf("\neCos Kernel Timings\n");
diag_printf("Notes: all times are in microseconds (.000001) unless otherwise stated\n");
#ifdef STATS_WITHOUT_FIRST_SAMPLE
diag_printf(" second line of results have first sample removed\n");
#endif
cyg_thread_delay(2); // Make sure the clock is actually running
ns_per_system_clock = 1000000/rtc_resolution[1];
for (i = 0; i < nsamples; i++) {
HAL_CLOCK_READ(&tv[i]);
}
tv0 = 0;
for (i = 1; i < nsamples; i++) {
tv0 += tv[i] - tv[i-1];
}
end_of_test_group();
overhead = tv0 / (nsamples-1);
diag_printf("Reading the hardware clock takes %d 'ticks' overhead\n", overhead);
diag_printf("... this value will be factored out of all other measurements\n");
// Try and measure how long the clock interrupt handling takes
for (i = 0; i < nsamples; i++) {
tick0 = cyg_current_time();
while (true) {
tick1 = cyg_current_time();
if (tick0 != tick1) break;
}
HAL_CLOCK_READ(&tv[i]);
}
tv1 = 0;
for (i = 0; i < nsamples; i++) {
tv1 += tv[i] * 1000;
}
tv1 = tv1 / nsamples;
tv1 -= overhead; // Adjust out the cost of getting the timer value
diag_printf("Clock interrupt took");
show_ticks_in_us(tv1);
diag_printf(" microseconds (%d raw clock ticks)\n", tv1/1000);
enable_clock_latency_measurement();
ticks = cyg_current_time();
show_test_parameters();
show_times_hdr();
reset_clock_latency_measurement();
run_thread_tests();
#ifdef CYGPKG_POSIX_PTHREAD_MUTEX
run_mutex_tests();
// run_mbox_tests();
#endif
run_semaphore_tests();
run_timer_tests();
#ifdef CYG_SCHEDULER_LOCK_TIMINGS
Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max);
diag_printf("\nMax lock:");
show_ticks_in_us(lock_max);
diag_printf(", Ave lock:");
show_ticks_in_us(lock_ave);
diag_printf("\n");
#endif
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY)
// Display latency figures in same format as all other numbers
disable_clock_latency_measurement();
clock_ave = (total_clock_latency*1000) / total_clock_interrupts;
show_ticks_in_us(clock_ave);
show_ticks_in_us(min_clock_latency*1000);
show_ticks_in_us(max_clock_latency*1000);
show_ticks_in_us(0);
diag_printf(" Clock/interrupt latency\n\n");
enable_clock_latency_measurement();
#endif
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY)
disable_clock_latency_measurement();
clock_ave = (total_clock_dsr_latency*1000) / total_clock_dsr_calls;
show_ticks_in_us(clock_ave);
show_ticks_in_us(min_clock_dsr_latency*1000);
show_ticks_in_us(max_clock_dsr_latency*1000);
show_ticks_in_us(0);
diag_printf(" Clock DSR latency\n\n");
enable_clock_latency_measurement();
#endif
#if 0
disable_clock_latency_measurement();
min_stack = STACK_SIZE;
max_stack = 0;
total_stack = 0;
for (i = 0; i < (int)NTEST_THREADS; i++) {
for (j = 0; j < STACK_SIZE; j++) {
if (stacks[i][j]) break;
}
actual_stack = STACK_SIZE-j;
if (actual_stack < min_stack) min_stack = actual_stack;
if (actual_stack > max_stack) max_stack = actual_stack;
total_stack += actual_stack;
}
for (j = 0; j < STACKSIZE; j++) {
if (((char *)stack[0])[j]) break;
}
diag_printf("%5d %5d %5d (main stack: %5d) Thread stack used (%d total)\n",
total_stack/NTEST_THREADS, min_stack, max_stack,
STACKSIZE - j, STACK_SIZE);
#endif
// cyg_test_dump_thread_stack_stats( "All done, main stack", thread[0] );
cyg_test_dump_interrupt_stack_stats( "All done" );
cyg_test_dump_idlethread_stack_stats( "All done" );
enable_clock_latency_measurement();
ticks = cyg_current_time();
diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000));
CYG_TEST_PASS_FINISH("Basic timing OK");
}
int main( int argc, char **argv )
{
CYG_TEST_INIT();
if (cyg_test_is_simulator) {
nsamples = NSAMPLES_SIM;
ntest_threads = NTEST_THREADS_SIM;
nthread_switches = NTHREAD_SWITCHES_SIM;
#ifdef CYGPKG_POSIX_PTHREAD_MUTEX
nmutexes = NMUTEXES_SIM;
#endif
nmboxes = NMBOXES_SIM;
nsemaphores = NSEMAPHORES_SIM;
nscheds = NSCHEDS_SIM;
ntimers = NTIMERS_SIM;
} else {
nsamples = NSAMPLES;
ntest_threads = NTEST_THREADS;
nthread_switches = NTHREAD_SWITCHES;
#ifdef CYGPKG_POSIX_PTHREAD_MUTEX
nmutexes = NMUTEXES;
#endif
nmboxes = NMBOXES;
nsemaphores = NSEMAPHORES;
nscheds = NSCHEDS;
ntimers = NTIMERS;
}
// Sanity
#ifdef WORKHORSE_TEST
ntest_threads = max(512, ntest_threads);
#ifdef CYGPKG_POSIX_PTHREAD_MUTEX
nmutexes = max(1024, nmutexes);
#endif
nsemaphores = max(1024, nsemaphores);
nmboxes = max(1024, nmboxes);
ncounters = max(1024, ncounters);
ntimers = max(1024, ntimers);
#else
ntest_threads = max(64, ntest_threads);
#ifdef CYGPKG_POSIX_PTHREAD_MUTEX
nmutexes = max(32, nmutexes);
#endif
nsemaphores = max(32, nsemaphores);
nmboxes = max(32, nmboxes);
ntimers = max(32, ntimers);
#endif
run_all_tests();
}
#endif // CYGFUN_KERNEL_API_C, etc.
// EOF tm_basic.cxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -