Mercurial > ecos
diff packages/kernel/current/tests/tm_basic.cxx @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | 3111d98ba7b3 |
| children | 1d7f19c9e4d1 |
line wrap: on
line diff
--- a/packages/kernel/current/tests/tm_basic.cxx +++ b/packages/kernel/current/tests/tm_basic.cxx @@ -22,7 +22,7 @@ // September 30, 1998. // // The Initial Developer of the Original Code is Cygnus. Portions created -// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### @@ -32,7 +32,7 @@ // Author(s): gthomas // Contributors: gthomas // Date: 1998-10-19 -// Description: Very simple timing test setup +// Description: Very simple kernel timing test //####DESCRIPTIONEND#### #include <pkgconf/kernel.h> @@ -48,6 +48,17 @@ #include <cyg/kernel/kapi.h> #include <cyg/infra/testcase.h> + +// Define this to see the statistics with the first sample datum removed. +// This can expose the effects of caches on the speed of operations. +#undef STATS_WITHOUT_FIRST_SAMPLE + +#if defined(CYGFUN_KERNEL_API_C) && \ + defined(CYGSEM_KERNEL_SCHED_MLQUEUE) && \ + defined(CYGVAR_KERNEL_COUNTERS_CLOCK) && \ + !defined(CYGPKG_HAL_I386_LINUX) && \ + (CYGNUM_KERNEL_SCHED_PRIORITIES > 12) + #define NTHREADS 1 #include "testaux.hxx" @@ -57,8 +68,8 @@ typedef struct fun_times { cyg_uint32 end; } fun_times; -#define NSAMPLES 10 -#define NTEST_THREADS 32 +#define NSAMPLES 32 +#define NTEST_THREADS 24 #define NTHREAD_SWITCHES 128 #define NMUTEXES 32 #define NMBOXES 32 @@ -67,7 +78,28 @@ typedef struct fun_times { #define NCOUNTERS 32 #define NALARMS 32 -#define STACK_SIZE 2048 // Is this large enough? +#define NSAMPLES_SIM 2 +#define NTEST_THREADS_SIM 2 +#define NTHREAD_SWITCHES_SIM 4 +#define NMUTEXES_SIM 2 +#define NMBOXES_SIM 2 +#define NSEMAPHORES_SIM 2 +#define NSCHEDS_SIM 4 +#define NCOUNTERS_SIM 2 +#define NALARMS_SIM 2 + +static int nsamples; +static int ntest_threads; +static int nthread_switches; +static int nmutexes; +static int nmboxes; +static int nsemaphores; +static int nscheds; +static int ncounters; +static int nalarms; + +#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM + static char stacks[NTEST_THREADS][STACK_SIZE]; static cyg_thread test_threads[NTEST_THREADS]; static cyg_handle_t threads[NTEST_THREADS]; @@ -103,8 +135,17 @@ static cyg_alarm test_alarms[NALARMS]; static cyg_handle_t alarms[NALARMS]; static fun_times alarm_ft[NALARMS]; +static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION; +static long ns_per_system_clock; + +#ifdef HAL_CLOCK_LATENCY +// Data kept by kernel real time clock measuring clock interrupt latency +extern cyg_tick_count total_clock_latency, total_clock_interrupts; +extern cyg_int32 min_clock_latency, max_clock_latency; +extern bool measure_clock_latency; +#endif + externC void diag_printf(const char *, ...); -externC void sprintf(char *, const char *, ...); void run_sched_tests(void); void run_thread_tests(void); @@ -118,32 +159,195 @@ void run_semaphore_circuit_test(void); void run_counter_tests(void); void run_alarm_tests(void); -#ifdef HAL_CLOCK_LATENCY -extern cyg_tick_count total_clock_latency, total_clock_interrupts; -extern cyg_int32 min_clock_latency, max_clock_latency; -#endif - -cyg_uint32 -ticks_to_us(cyg_uint32 ticks) -{ - int us; - // Assumes that the clock is set up for 10ms ticks - us = (10000 * ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; - return (us); -} - // Wait until a clock tick [real time clock] has passed. This should keep it // from happening again during a measurement, thus minimizing any fluctuations void wait_for_tick(void) { - cyg_uint32 tv0, tv1; - HAL_CLOCK_READ(&tv0); + cyg_tick_count_t tv0, tv1; + tv0 = cyg_current_time(); while (true) { - HAL_CLOCK_READ(&tv1); - if (tv1 < tv0) break; - tv0 = tv1; + tv1 = cyg_current_time(); + if (tv1 != tv0) break; + } +} + +// Display a number of ticks as microseconds +// Note: for improved calculation significance, values are kept in ticks*1000 +void +show_ticks_in_us(cyg_uint32 ticks) +{ + long long ns; + ns = (ns_per_system_clock * (long long)ticks) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; + ns += 5; // for rounding to .01us + diag_printf("%5d.%02d", (int)(ns/1000), (int)((ns%1000)/10)); +} + +// +// If the kernel is instrumented to measure clock interrupt latency, these +// measurements can be drastically perturbed by printing via "diag_printf()" +// since that code may run with interrupts disabled for long periods. +// +// In order to get accurate/reasonable latency figures _for the kernel +// primitive functions beint tested_, the kernel's latency measurements +// are suspended while the printing actually takes place. +// +// The measurements are reenabled after the printing, thus allowing for +// fair measurements of the kernel primitives, which are not distorted +// by the printing mechanisms. + +#ifdef HAL_CLOCK_LATENCY +void +disable_clock_latency_measurement(void) +{ + wait_for_tick(); + measure_clock_latency = false; +} + +void +enable_clock_latency_measurement(void) +{ + wait_for_tick(); + measure_clock_latency = true; +} + +// Ensure that the measurements are reasonable (no startup anomalies) +void +reset_clock_latency_measurement(void) +{ + disable_clock_latency_measurement(); + total_clock_latency = 0; + total_clock_interrupts = 0; + min_clock_latency = 0x7FFFFFFF; + max_clock_latency = 0; + enable_clock_latency_measurement(); +} +#else +#define disable_clock_latency_measurement() +#define enable_clock_latency_measurement() +#define reset_clock_latency_measurement() +#endif + +void +show_times_hdr(void) +{ + disable_clock_latency_measurement(); + diag_printf("\n"); + diag_printf(" Confidence\n"); + diag_printf(" Ave Min Max Var Ave Min Function\n"); + diag_printf(" ====== ====== ====== ====== ========== ========\n"); + enable_clock_latency_measurement(); +} + +void +show_times_detail(fun_times ft[], int nsamples, char *title, bool ignore_first) +{ + int i, delta, min, max, con_ave, con_min, ave_dev; + int start_sample, total_samples; + cyg_int32 total, ave; + + if (ignore_first) { + start_sample = 1; + total_samples = nsamples-1; + } else { + start_sample = 0; + total_samples = nsamples; } + total = 0; + min = 0x7FFFFFFF; + max = 0; + for (i = start_sample; i < nsamples; i++) { + if (ft[i].end < ft[i].start) { + // Clock wrapped around (timer tick) + delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; + } else { + delta = ft[i].end - ft[i].start; + } + delta -= overhead; + if (delta < 0) delta = 0; + delta *= 1000; + total += delta; + if (delta < min) min = delta; + if (delta > max) max = delta; + } + ave = total / total_samples; + total = 0; + ave_dev = 0; + for (i = start_sample; i < nsamples; i++) { + if (ft[i].end < ft[i].start) { + // Clock wrapped around (timer tick) + delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; + } else { + delta = ft[i].end - ft[i].start; + } + delta -= overhead; + if (delta < 0) delta = 0; + delta *= 1000; + delta = delta - ave; + if (delta < 0) delta = -delta; + ave_dev += delta; + } + ave_dev /= total_samples; + con_ave = 0; + con_min = 0; + for (i = start_sample; i < nsamples; i++) { + if (ft[i].end < ft[i].start) { + // Clock wrapped around (timer tick) + delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; + } else { + delta = ft[i].end - ft[i].start; + } + delta -= overhead; + if (delta < 0) delta = 0; + delta *= 1000; + if ((delta <= (ave+ave_dev)) && (delta >= (ave-ave_dev))) con_ave++; + if ((delta <= (min+ave_dev)) && (delta >= (min-ave_dev))) con_min++; + } + con_ave = (con_ave * 100) / total_samples; + con_min = (con_min * 100) / total_samples; + show_ticks_in_us(ave); + show_ticks_in_us(min); + show_ticks_in_us(max); + show_ticks_in_us(ave_dev); + disable_clock_latency_measurement(); + diag_printf(" %3d%% %3d%%", con_ave, con_min); + diag_printf(" %s\n", title); + enable_clock_latency_measurement(); +} + +void +show_times(fun_times ft[], int nsamples, char *title) +{ + show_times_detail(ft, nsamples, title, false); +#ifdef STATS_WITHOUT_FIRST_SAMPLE + show_times_detail(ft, nsamples, "", true); +#endif +} + +void +show_test_parameters(void) +{ + disable_clock_latency_measurement(); + diag_printf("\nTesting parameters:\n"); + diag_printf(" Clock samples: %3d\n", nsamples); + diag_printf(" Threads: %3d\n", ntest_threads); + diag_printf(" Thread switches: %3d\n", nthread_switches); + diag_printf(" Mutexes: %3d\n", nmutexes); + diag_printf(" Mailboxes: %3d\n", nmboxes); + diag_printf(" Semaphores: %3d\n", nsemaphores); + diag_printf(" Scheduler operations: %3d\n", nscheds); + diag_printf(" Counters: %3d\n", ncounters); + diag_printf(" Alarms: %3d\n", nalarms); + diag_printf("\n"); + enable_clock_latency_measurement(); +} + +void +end_of_test_group(void) +{ + disable_clock_latency_measurement(); + diag_printf("\n"); + enable_clock_latency_measurement(); } // Compute a name for a thread @@ -164,7 +368,7 @@ test0(cyg_uint32 indx) void test1(cyg_uint32 indx) { - if (indx == (NTEST_THREADS-1)) { + if (indx == (cyg_uint32)(ntest_threads-1)) { cyg_semaphore_post(&synchro); // Signal that last thread is dying } cyg_thread_exit(); @@ -175,7 +379,7 @@ void test2(cyg_uint32 indx) { int i; - for (i = 0; i < NTHREAD_SWITCHES; i++) { + for (i = 0; i < nthread_switches; i++) { if (indx == 0) { HAL_CLOCK_READ(&test2_ft[i].start); } else { @@ -195,7 +399,7 @@ mutex_test(cyg_uint32 indx) { int i; cyg_mutex_lock(&test_mutexes[0]); - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { cyg_semaphore_wait(&synchro); wait_for_tick(); // Wait until the next clock tick to minimize aberations HAL_CLOCK_READ(&mutex_ft[i].start); @@ -215,7 +419,7 @@ mbox_test(cyg_uint32 indx) item = cyg_mbox_get(test_mbox_handles[0]); HAL_CLOCK_READ(&mbox_ft[(int)item].end); cyg_semaphore_post(&synchro); - } while ((int)item != (NMBOXES-1)); + } while ((int)item != (nmboxes-1)); cyg_thread_exit(); } @@ -224,7 +428,7 @@ void semaphore_test(cyg_uint32 indx) { int i; - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { cyg_semaphore_wait(&test_semaphores[0]); HAL_CLOCK_READ(&semaphore_ft[i].end); cyg_semaphore_post(&synchro); @@ -232,69 +436,9 @@ semaphore_test(cyg_uint32 indx) cyg_thread_exit(); } -void -show_times_hdr(void) -{ - diag_printf("\n"); - diag_printf(" Ave Min Max Variance Function\n"); - diag_printf("====== ====== ====== ======== ========\n"); -} - -void -show_times(fun_times ft[], int nsamples, char *title) -{ - int i, delta, min, max; - cyg_uint32 total, ave, var; - total = 0; - min = 0x7FFFFFFF; - max = 0; - for (i = 0; i < nsamples; i++) { - if (ft[i].end < ft[i].start) { - // Clock wrapped around (timer tick) - delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; - } else { - delta = ft[i].end - ft[i].start; - } - delta -= 2*overhead; - if (delta < 0) delta = 0; - total += delta; - if (delta < min) min = delta; - if (delta > max) max = delta; - } - ave = total / nsamples; - total = 0; - for (i = 0; i < nsamples; i++) { - if (ft[i].end < ft[i].start) { - // Clock wrapped around (timer tick) - delta = (ft[i].end+CYGNUM_KERNEL_COUNTERS_RTC_PERIOD) - ft[i].start; - } else { - delta = ft[i].end - ft[i].start; - } - delta -= 2*overhead; - if (delta < 0) delta = 0; - total = (delta - ave) * (delta - ave); - } - var = total / (nsamples - 1); - diag_printf("%6d %6d %6d %6d %s\n", - ticks_to_us(ave), ticks_to_us(min), ticks_to_us(max), ticks_to_us(var), title); -} - -void -show_test_parameters(void) -{ - diag_printf("\nTesting parameters:\n"); - diag_printf(" Clock samples: %3d\n", NSAMPLES); - diag_printf(" Threads: %3d\n", NTEST_THREADS); - diag_printf(" Thread switches: %3d\n", NTHREAD_SWITCHES); - diag_printf(" Mutexes: %3d\n", NMUTEXES); - diag_printf(" Mailboxes: %3d\n", NMBOXES); - diag_printf(" Semaphores: %3d\n", NSEMAPHORES); - diag_printf(" Scheduler operations: %3d\n", NSCHEDS); - diag_printf(" Counters: %3d\n", NCOUNTERS); - diag_printf(" Alarms: %3d\n", NALARMS); - diag_printf("\n"); -} - +// +// This set of tests is used to measure kernel primitives that deal with threads +// void run_thread_tests(void) { @@ -305,7 +449,7 @@ run_thread_tests(void) cyg_thread_set_priority(cyg_thread_self(), 2); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_create(10, // Priority - just a number test0, // entry @@ -318,69 +462,69 @@ run_thread_tests(void) ); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Create thread"); + show_times(thread_ft, ntest_threads, "Create thread"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_yield(); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Yield thread [all suspended]"); + show_times(thread_ft, ntest_threads, "Yield thread [all suspended]"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_suspend(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Suspend [suspended] thread"); + show_times(thread_ft, ntest_threads, "Suspend [suspended] thread"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_resume(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Resume thread"); + show_times(thread_ft, ntest_threads, "Resume thread"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_set_priority(threads[i], 11); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Set priority"); + show_times(thread_ft, ntest_threads, "Set priority"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); prio = cyg_thread_get_priority(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Get priority"); + show_times(thread_ft, ntest_threads, "Get priority"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_kill(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Kill [suspended] thread"); + show_times(thread_ft, ntest_threads, "Kill [suspended] thread"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_yield(); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Yield [no other] thread"); + show_times(thread_ft, ntest_threads, "Yield [no other] thread"); // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); // Recreate the test set - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { cyg_thread_create(10, // Priority - just a number test0, // entry i, // index @@ -393,56 +537,87 @@ run_thread_tests(void) } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { + HAL_CLOCK_READ(&thread_ft[i].start); + cyg_thread_resume(threads[i]); + HAL_CLOCK_READ(&thread_ft[i].end); + } + show_times(thread_ft, ntest_threads, "Resume [suspended low prio] thread"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_resume(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Resume [suspended low priority] thread"); + show_times(thread_ft, ntest_threads, "Resume [runnable low prio] thread"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); - cyg_thread_resume(threads[i]); + cyg_thread_suspend(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Resume [runnable low priority] thread"); + show_times(thread_ft, ntest_threads, "Suspend [runnable] thread"); + wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { + HAL_CLOCK_READ(&thread_ft[i].start); + cyg_thread_yield(); + HAL_CLOCK_READ(&thread_ft[i].end); + } + show_times(thread_ft, ntest_threads, "Yield [only low prio] thread"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_suspend(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Suspend [runnable] thread"); - - - wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { - HAL_CLOCK_READ(&thread_ft[i].start); - cyg_thread_yield(); - HAL_CLOCK_READ(&thread_ft[i].end); - } - show_times(thread_ft, NTEST_THREADS, "Yield [only low prio] thread"); - - wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { - HAL_CLOCK_READ(&thread_ft[i].start); - cyg_thread_suspend(threads[i]); - HAL_CLOCK_READ(&thread_ft[i].end); - } - show_times(thread_ft, NTEST_THREADS, "Suspend [runnable->not runnable] thread"); - for (i = 0; i < NTEST_THREADS; i++) { + show_times(thread_ft, ntest_threads, "Suspend [runnable->not runnable]"); + for (i = 0; i < ntest_threads; i++) { cyg_thread_resume(threads[i]); } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_kill(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Kill [runnable] thread"); + show_times(thread_ft, ntest_threads, "Kill [runnable] thread"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < ntest_threads; i++) { + HAL_CLOCK_READ(&thread_ft[i].start); + cyg_thread_delete(threads[i]); + HAL_CLOCK_READ(&thread_ft[i].end); + } + show_times(thread_ft, ntest_threads, "Destroy [dead] thread"); + + // Recreate the test set + for (i = 0; i < ntest_threads; i++) { + cyg_thread_create(10, // Priority - just a number + test0, // entry + i, // index + thread_name("thread", i), // Name + &stacks[i][0], // Stack + STACK_SIZE, // Size + &threads[i], // Handle + &test_threads[i] // Thread data structure + ); + cyg_thread_resume(threads[i]); + } + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < ntest_threads; i++) { + HAL_CLOCK_READ(&thread_ft[i].start); + cyg_thread_delete(threads[i]); + HAL_CLOCK_READ(&thread_ft[i].end); + } + show_times(thread_ft, ntest_threads, "Destroy [runnable] thread"); + // Set my priority lower than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 3); @@ -450,7 +625,7 @@ run_thread_tests(void) cyg_semaphore_init(&synchro, 0); // Recreate the test set - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { cyg_thread_create(2, // Priority - just a number test1, // entry i, // index @@ -463,19 +638,20 @@ run_thread_tests(void) } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { HAL_CLOCK_READ(&thread_ft[i].start); cyg_thread_resume(threads[i]); HAL_CLOCK_READ(&thread_ft[i].end); } - show_times(thread_ft, NTEST_THREADS, "Resume [high priority] thread"); + show_times(thread_ft, ntest_threads, "Resume [high priority] thread"); cyg_semaphore_wait(&synchro); // Wait for all threads to finish // Make sure they are all dead - for (i = 0; i < NTEST_THREADS; i++) { - cyg_thread_kill(threads[i]); + for (i = 0; i < ntest_threads; i++) { + cyg_thread_delete(threads[i]); } run_thread_switch_test(); + end_of_test_group(); } void @@ -500,10 +676,10 @@ run_thread_switch_test(void) cyg_semaphore_init(&synchro, 0); cyg_semaphore_wait(&synchro); wait_for_tick(); // Wait until the next clock tick to minimize aberations - show_times(test2_ft, NTHREAD_SWITCHES, "Thread switch"); + show_times(test2_ft, nthread_switches, "Thread switch"); // Clean up for (i = 0; i < 2; i++) { - cyg_thread_kill(threads[i]); + cyg_thread_delete(threads[i]); } } @@ -514,53 +690,54 @@ run_mutex_tests(void) // Mutex primitives wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_init(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Init mutex"); + show_times(mutex_ft, nmutexes, "Init mutex"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_lock(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Lock [unlocked] mutex"); + show_times(mutex_ft, nmutexes, "Lock [unlocked] mutex"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_unlock(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Unlock [locked] mutex"); + show_times(mutex_ft, nmutexes, "Unlock [locked] mutex"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_trylock(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Trylock [unlocked] mutex"); + show_times(mutex_ft, nmutexes, "Trylock [unlocked] mutex"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_trylock(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Trylock [locked] mutex"); + show_times(mutex_ft, nmutexes, "Trylock [locked] mutex"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { HAL_CLOCK_READ(&mutex_ft[i].start); cyg_mutex_destroy(&test_mutexes[i]); HAL_CLOCK_READ(&mutex_ft[i].end); } - show_times(mutex_ft, NMUTEXES, "Destroy mutex"); + show_times(mutex_ft, nmutexes, "Destroy mutex"); run_mutex_circuit_test(); + end_of_test_group(); } void @@ -584,14 +761,15 @@ run_mutex_circuit_test(void) cyg_thread_resume(mutex_test_thread_handle); // Need to raise priority so that this thread will block on the "lock" cyg_thread_set_priority(cyg_thread_self(), 2); - for (i = 0; i < NMUTEXES; i++) { + for (i = 0; i < nmutexes; i++) { cyg_semaphore_post(&synchro); cyg_mutex_lock(&test_mutexes[0]); HAL_CLOCK_READ(&mutex_ft[i].end); cyg_mutex_unlock(&test_mutexes[0]); cyg_semaphore_wait(&synchro); } - show_times(mutex_ft, NMUTEXES, "Unlock/Lock mutex"); + cyg_thread_delete(mutex_test_thread_handle); + show_times(mutex_ft, nmutexes, "Unlock/Lock mutex"); } void @@ -601,139 +779,143 @@ run_mbox_tests(void) void *item; // Mailbox primitives wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_create(&test_mbox_handles[i], &test_mboxes[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Create mbox"); + show_times(mbox_ft, nmboxes, "Create mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { - HAL_CLOCK_READ(&mbox_ft[i].start); - cnt = cyg_mbox_peek(test_mbox_handles[i]); - HAL_CLOCK_READ(&mbox_ft[i].end); - } - show_times(mbox_ft, NMBOXES, "Peek [empty] mbox"); - - wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { - HAL_CLOCK_READ(&mbox_ft[i].start); - cyg_mbox_put(test_mbox_handles[i], (void *)i); - HAL_CLOCK_READ(&mbox_ft[i].end); - } - show_times(mbox_ft, NMBOXES, "Put [first] mbox"); - - wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cnt = cyg_mbox_peek(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Peek [1 msg] mbox"); + show_times(mbox_ft, nmboxes, "Peek [empty] mbox"); +#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_put(test_mbox_handles[i], (void *)i); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Put [second] mbox"); + show_times(mbox_ft, nmboxes, "Put [first] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cnt = cyg_mbox_peek(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Peek [2 msgs] mbox"); + show_times(mbox_ft, nmboxes, "Peek [1 msg] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { + HAL_CLOCK_READ(&mbox_ft[i].start); + cyg_mbox_put(test_mbox_handles[i], (void *)i); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + show_times(mbox_ft, nmboxes, "Put [second] mbox"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < nmboxes; i++) { + HAL_CLOCK_READ(&mbox_ft[i].start); + cnt = cyg_mbox_peek(test_mbox_handles[i]); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + show_times(mbox_ft, nmboxes, "Peek [2 msgs] mbox"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_get(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Get [first] mbox"); + show_times(mbox_ft, nmboxes, "Get [first] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_get(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Get [second] mbox"); + show_times(mbox_ft, nmboxes, "Get [second] mbox"); +#endif // ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_tryput(test_mbox_handles[i], (void *)i); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Tryput [first] mbox"); + show_times(mbox_ft, nmboxes, "Tryput [first] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_peek_item(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Peek item [non-empty] mbox"); + show_times(mbox_ft, nmboxes, "Peek item [non-empty] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_tryget(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Tryget [non-empty] mbox"); + show_times(mbox_ft, nmboxes, "Tryget [non-empty] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_peek_item(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Peek item [empty] mbox"); + show_times(mbox_ft, nmboxes, "Peek item [empty] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); item = cyg_mbox_tryget(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Tryget [empty] mbox"); + show_times(mbox_ft, nmboxes, "Tryget [empty] mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_waiting_to_get(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Waiting to get mbox"); + show_times(mbox_ft, nmboxes, "Waiting to get mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_waiting_to_put(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Waiting to put mbox"); + show_times(mbox_ft, nmboxes, "Waiting to put mbox"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_delete(test_mbox_handles[i]); HAL_CLOCK_READ(&mbox_ft[i].end); } - show_times(mbox_ft, NMBOXES, "Delete mbox"); + show_times(mbox_ft, nmboxes, "Delete mbox"); run_mbox_circuit_test(); + end_of_test_group(); } void run_mbox_circuit_test(void) { +#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT int i; // Set my priority lower than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 3); @@ -750,79 +932,82 @@ run_mbox_circuit_test(void) &mbox_test_thread // Thread data structure ); cyg_thread_resume(mbox_test_thread_handle); - for (i = 0; i < NMBOXES; i++) { + for (i = 0; i < nmboxes; i++) { wait_for_tick(); // Wait until the next clock tick to minimize aberations HAL_CLOCK_READ(&mbox_ft[i].start); cyg_mbox_put(test_mbox_handles[0], (void *)i); cyg_semaphore_wait(&synchro); } - show_times(mbox_ft, NMBOXES, "Put/Get mbox"); + cyg_thread_delete(mbox_test_thread_handle); + show_times(mbox_ft, nmboxes, "Put/Get mbox"); +#endif } void run_semaphore_tests(void) { int i; - cyg_ucount32 sem_val; + cyg_count32 sem_val; // Semaphore primitives wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_init(&test_semaphores[i], 0); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Init semaphore"); + show_times(semaphore_ft, nsemaphores, "Init semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_post(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Post [0] semaphore"); + show_times(semaphore_ft, nsemaphores, "Post [0] semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_wait(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Wait [1] semaphore"); + show_times(semaphore_ft, nsemaphores, "Wait [1] semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_trywait(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Trywait [0] semaphore"); + show_times(semaphore_ft, nsemaphores, "Trywait [0] semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { cyg_semaphore_post(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_trywait(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Trywait [1] semaphore"); + show_times(semaphore_ft, nsemaphores, "Trywait [1] semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_peek(&test_semaphores[i], &sem_val); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Peek semaphore"); + show_times(semaphore_ft, nsemaphores, "Peek semaphore"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_destroy(&test_semaphores[i]); HAL_CLOCK_READ(&semaphore_ft[i].end); } - show_times(semaphore_ft, NSEMAPHORES, "Destroy semaphore"); + show_times(semaphore_ft, nsemaphores, "Destroy semaphore"); run_semaphore_circuit_test(); + end_of_test_group(); } void @@ -844,60 +1029,62 @@ run_semaphore_circuit_test(void) &semaphore_test_thread // Thread data structure ); cyg_thread_resume(semaphore_test_thread_handle); - for (i = 0; i < NSEMAPHORES; i++) { + for (i = 0; i < nsemaphores; i++) { wait_for_tick(); // Wait until the next clock tick to minimize aberations HAL_CLOCK_READ(&semaphore_ft[i].start); cyg_semaphore_post(&test_semaphores[0]); cyg_semaphore_wait(&synchro); } - show_times(semaphore_ft, NSEMAPHORES, "Post/Wait semaphore"); + cyg_thread_delete(semaphore_test_thread_handle); + show_times(semaphore_ft, nsemaphores, "Post/Wait semaphore"); } void run_counter_tests(void) { int i; - cyg_tick_count_t val; + cyg_tick_count_t val=0; wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_create(&counters[i], &test_counters[i]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Create counter"); + show_times(counter_ft, ncounters, "Create counter"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); val = cyg_counter_current_value(counters[i]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Get counter value"); + show_times(counter_ft, ncounters, "Get counter value"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_set_value(counters[i], val); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Set counter value"); + show_times(counter_ft, ncounters, "Set counter value"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_tick(counters[i]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Tick counter"); + show_times(counter_ft, ncounters, "Tick counter"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_delete(counters[i]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Delete counter"); + show_times(counter_ft, ncounters, "Delete counter"); + end_of_test_group(); } // Alarm callback function @@ -912,10 +1099,10 @@ static volatile int alarm_cnt; void alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx) { - if (alarm_cnt == NSCHEDS) return; + if (alarm_cnt == nscheds) return; sched_ft[alarm_cnt].start = 0; HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end); - if (alarm_cnt == NSCHEDS) { + if (alarm_cnt == nscheds) { cyg_semaphore_post(&synchro); } } @@ -937,50 +1124,50 @@ run_alarm_tests(void) cyg_handle_t rtc_handle; wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { cyg_counter_create(&counters[i], &test_counters[i]); } - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { HAL_CLOCK_READ(&alarm_ft[i].start); cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); HAL_CLOCK_READ(&alarm_ft[i].end); } - show_times(alarm_ft, NALARMS, "Create alarm"); + show_times(alarm_ft, nalarms, "Create alarm"); wait_for_tick(); // Wait until the next clock tick to minimize aberations init_val = 0; step_val = 0; - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { HAL_CLOCK_READ(&alarm_ft[i].start); cyg_alarm_initialize(alarms[i], init_val, step_val); HAL_CLOCK_READ(&alarm_ft[i].end); } - show_times(alarm_ft, NALARMS, "Initialize alarm"); + show_times(alarm_ft, nalarms, "Initialize alarm"); wait_for_tick(); // Wait until the next clock tick to minimize aberations init_val = 0; step_val = 0; - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { HAL_CLOCK_READ(&alarm_ft[i].start); cyg_alarm_disable(alarms[i]); HAL_CLOCK_READ(&alarm_ft[i].end); } - show_times(alarm_ft, NALARMS, "Disable alarm"); + show_times(alarm_ft, nalarms, "Disable alarm"); wait_for_tick(); // Wait until the next clock tick to minimize aberations init_val = 0; step_val = 0; - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { HAL_CLOCK_READ(&alarm_ft[i].start); cyg_alarm_enable(alarms[i]); HAL_CLOCK_READ(&alarm_ft[i].end); } - show_times(alarm_ft, NALARMS, "Enable alarm"); + show_times(alarm_ft, nalarms, "Enable alarm"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { HAL_CLOCK_READ(&alarm_ft[i].start); cyg_alarm_delete(alarms[i]); HAL_CLOCK_READ(&alarm_ft[i].end); } - show_times(alarm_ft, NALARMS, "Delete alarm"); + show_times(alarm_ft, nalarms, "Delete alarm"); wait_for_tick(); // Wait until the next clock tick to minimize aberations cyg_counter_create(&counters[0], &test_counters[0]); @@ -988,27 +1175,27 @@ run_alarm_tests(void) init_val = 9999; step_val = 9999; cyg_alarm_initialize(alarms[0], init_val, step_val); cyg_alarm_enable(alarms[0]); - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_tick(counters[0]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Tick counter [1 alarm]"); + show_times(counter_ft, ncounters, "Tick counter [1 alarm]"); wait_for_tick(); // Wait until the next clock tick to minimize aberations cyg_counter_create(&counters[0], &test_counters[0]); - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[i], &test_alarms[i]); init_val = 9999; step_val = 9999; cyg_alarm_initialize(alarms[i], init_val, step_val); cyg_alarm_enable(alarms[i]); } - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_tick(counters[0]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Tick counter [many alarms]"); + show_times(counter_ft, ncounters, "Tick counter [many alarms]"); wait_for_tick(); // Wait until the next clock tick to minimize aberations cyg_counter_create(&counters[0], &test_counters[0]); @@ -1016,30 +1203,48 @@ run_alarm_tests(void) init_val = 1; step_val = 1; cyg_alarm_initialize(alarms[0], init_val, step_val); cyg_alarm_enable(alarms[0]); - for (i = 0; i < NCOUNTERS; i++) { + for (i = 0; i < ncounters; i++) { HAL_CLOCK_READ(&counter_ft[i].start); cyg_counter_tick(counters[0]); HAL_CLOCK_READ(&counter_ft[i].end); } - show_times(counter_ft, NCOUNTERS, "Tick & fire counter [1 alarm]"); + show_times(counter_ft, ncounters, "Tick & fire counter [1 alarm]"); wait_for_tick(); // Wait until the next clock tick to minimize aberations cyg_counter_create(&counters[0], &test_counters[0]); - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]); init_val = 1; step_val = 1; cyg_alarm_initialize(alarms[i], init_val, step_val); cyg_alarm_enable(alarms[i]); } - for (i = 0; i < NCOUNTERS; i++) { - HAL_CLOCK_READ(&counter_ft[i].start); + for (i = 0; i < nalarms; i++) { + HAL_CLOCK_READ(&alarm_ft[i].start); cyg_counter_tick(counters[0]); - HAL_CLOCK_READ(&counter_ft[i].end); + HAL_CLOCK_READ(&alarm_ft[i].end); } - for (i = 0; i < NALARMS; i++) { + for (i = 0; i < nalarms; i++) { cyg_alarm_delete(alarms[i]); } - show_times(counter_ft, NCOUNTERS, "Tick & fire counter [many alarms]"); + show_times(alarm_ft, nalarms, "Tick & fire counters [>1 together]"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + cyg_counter_create(&counters[0], &test_counters[0]); + for (i = 0; i < nalarms; i++) { + cyg_alarm_create(counters[0], alarm_cb, i, &alarms[i], &test_alarms[i]); + init_val = i+1; step_val = nalarms+1; + cyg_alarm_initialize(alarms[i], init_val, step_val); + cyg_alarm_enable(alarms[i]); + } + for (i = 0; i < nalarms; i++) { + HAL_CLOCK_READ(&alarm_ft[i].start); + cyg_counter_tick(counters[0]); + HAL_CLOCK_READ(&alarm_ft[i].end); + } + for (i = 0; i < nalarms; i++) { + cyg_alarm_delete(alarms[i]); + } + show_times(alarm_ft, nalarms, "Tick & fire counters [>1 separately]"); wait_for_tick(); // Wait until the next clock tick to minimize aberations cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); @@ -1051,7 +1256,7 @@ run_alarm_tests(void) cyg_semaphore_wait(&synchro); cyg_alarm_disable(alarms[0]); cyg_alarm_delete(alarms[0]); - show_times(sched_ft, NSCHEDS, "Alarm latency [0 threads]"); + show_times(sched_ft, nscheds, "Alarm latency [0 threads]"); // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); @@ -1077,15 +1282,15 @@ run_alarm_tests(void) cyg_semaphore_wait(&synchro); cyg_alarm_disable(alarms[0]); cyg_alarm_delete(alarms[0]); - show_times(sched_ft, NSCHEDS, "Alarm latency [2 threads]"); + show_times(sched_ft, nscheds, "Alarm latency [2 threads]"); for (i = 0; i < 2; i++) { cyg_thread_suspend(threads[i]); - cyg_thread_kill(threads[i]); + cyg_thread_delete(threads[i]); } // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { cyg_thread_create(10, // Priority - just a number alarm_test, // entry i, // index @@ -1107,11 +1312,12 @@ run_alarm_tests(void) cyg_semaphore_wait(&synchro); cyg_alarm_disable(alarms[0]); cyg_alarm_delete(alarms[0]); - show_times(sched_ft, NSCHEDS, "Alarm latency [many threads]"); - for (i = 0; i < NTEST_THREADS; i++) { + show_times(sched_ft, nscheds, "Alarm latency [many threads]"); + for (i = 0; i < ntest_threads; i++) { cyg_thread_suspend(threads[i]); - cyg_thread_kill(threads[i]); + cyg_thread_delete(threads[i]); } + end_of_test_group(); } void @@ -1120,22 +1326,22 @@ run_sched_tests(void) int i; wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSCHEDS; i++) { + for (i = 0; i < nscheds; i++) { HAL_CLOCK_READ(&sched_ft[i].start); cyg_scheduler_lock(); HAL_CLOCK_READ(&sched_ft[i].end); cyg_scheduler_unlock(); } - show_times(sched_ft, NSCHEDS, "Scheduler lock"); + show_times(sched_ft, nscheds, "Scheduler lock"); wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSCHEDS; i++) { + for (i = 0; i < nscheds; i++) { cyg_scheduler_lock(); HAL_CLOCK_READ(&sched_ft[i].start); cyg_scheduler_unlock(); HAL_CLOCK_READ(&sched_ft[i].end); } - show_times(sched_ft, NSCHEDS, "Scheduler unlock [0 threads]"); + show_times(sched_ft, nscheds, "Scheduler unlock [0 threads]"); // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); @@ -1151,20 +1357,20 @@ run_sched_tests(void) ); } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSCHEDS; i++) { + for (i = 0; i < nscheds; i++) { cyg_scheduler_lock(); HAL_CLOCK_READ(&sched_ft[i].start); cyg_scheduler_unlock(); HAL_CLOCK_READ(&sched_ft[i].end); } - show_times(sched_ft, NSCHEDS, "Scheduler unlock [1 suspended thread]"); + show_times(sched_ft, nscheds, "Scheduler unlock [1 suspended]"); for (i = 0; i < 1; i++) { - cyg_thread_kill(threads[i]); + cyg_thread_delete(threads[i]); } // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { cyg_thread_create(10, // Priority - just a number test0, // entry i, // index @@ -1176,20 +1382,20 @@ run_sched_tests(void) ); } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSCHEDS; i++) { + for (i = 0; i < nscheds; i++) { cyg_scheduler_lock(); HAL_CLOCK_READ(&sched_ft[i].start); cyg_scheduler_unlock(); HAL_CLOCK_READ(&sched_ft[i].end); } - show_times(sched_ft, NSCHEDS, "Scheduler unlock [many suspended threads]"); - for (i = 0; i < NTEST_THREADS; i++) { - cyg_thread_kill(threads[i]); + show_times(sched_ft, nscheds, "Scheduler unlock [many suspended]"); + for (i = 0; i < ntest_threads; i++) { + cyg_thread_delete(threads[i]); } // Set my priority higher than any I plan to create cyg_thread_set_priority(cyg_thread_self(), 2); - for (i = 0; i < NTEST_THREADS; i++) { + for (i = 0; i < ntest_threads; i++) { cyg_thread_create(10, // Priority - just a number test0, // entry i, // index @@ -1202,24 +1408,26 @@ run_sched_tests(void) cyg_thread_resume(threads[i]); } wait_for_tick(); // Wait until the next clock tick to minimize aberations - for (i = 0; i < NSCHEDS; i++) { + for (i = 0; i < nscheds; i++) { cyg_scheduler_lock(); HAL_CLOCK_READ(&sched_ft[i].start); cyg_scheduler_unlock(); HAL_CLOCK_READ(&sched_ft[i].end); } - show_times(sched_ft, NSCHEDS, "Scheduler unlock [many low prio threads]"); - for (i = 0; i < NTEST_THREADS; i++) { - cyg_thread_kill(threads[i]); + show_times(sched_ft, nscheds, "Scheduler unlock [many low prio]"); + for (i = 0; i < ntest_threads; i++) { + cyg_thread_delete(threads[i]); } + end_of_test_group(); } void run_all_tests(CYG_ADDRESS id) { - int i; - cyg_uint32 tv[NSAMPLES], tv0, tv1, us; - cyg_tick_count_t ticks; + int i, j; + cyg_uint32 tv[nsamples], tv0, tv1; + cyg_uint32 min_stack, max_stack, total_stack, actual_stack; + cyg_tick_count_t ticks, tick0, tick1; #ifdef CYG_SCHEDULER_LOCK_TIMINGS cyg_uint32 lock_ave, lock_max; #endif @@ -1227,39 +1435,57 @@ run_all_tests(CYG_ADDRESS id) cyg_int32 clock_ave; #endif - for (i = 0; i < NSAMPLES; i++) { + disable_clock_latency_measurement(); + 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]); } - diag_printf("Clock: "); tv0 = 0; - for (i = 0; i < NSAMPLES; i++) { - diag_printf("%x ", tv[i]); - if (i > 0) { - tv0 += tv[i] - tv[i-1]; - } + for (i = 1; i < nsamples; i++) { + tv0 += tv[i] - tv[i-1]; } - diag_printf("\n"); + end_of_test_group(); - overhead = tv0 / (NSAMPLES-1); - diag_printf("Average %d clock ticks overhead\n", overhead); + 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 - HAL_CLOCK_READ(&tv0); - while (true) { - HAL_CLOCK_READ(&tv1); - if (tv1 < tv0) break; - tv0 = tv1; + 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 - us = ticks_to_us(tv1); - diag_printf("Clock interrupt took %d microseconds (%d clock ticks)\n", us, tv1); + 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(); - diag_printf("Ticks: %x\n", (int)ticks); show_test_parameters(); show_times_hdr(); + reset_clock_latency_measurement(); + run_thread_tests(); run_sched_tests(); run_mutex_tests(); @@ -1270,17 +1496,48 @@ run_all_tests(CYG_ADDRESS id) #ifdef CYG_SCHEDULER_LOCK_TIMINGS Cyg_Scheduler::get_lock_times(&lock_ave, &lock_max); - diag_printf("\nMax lock: %d, Ave lock: %d\n", ticks_to_us(lock_max), ticks_to_us(lock_ave)); + diag_printf("\nMax lock:"); + show_ticks_in_us(lock_max); + diag_printf(", Ave lock:"); + show_ticks_in_us(lock_ave); + diag_printf("\n"); #endif #ifdef HAL_CLOCK_LATENCY - clock_ave = total_clock_latency / total_clock_interrupts; - diag_printf("\nClock/interrupt latency - ave: %d, min: %d, max: %d\n", - ticks_to_us(clock_ave), ticks_to_us(min_clock_latency), ticks_to_us(max_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 + disable_clock_latency_measurement(); + min_stack = STACK_SIZE; + max_stack = 0; + total_stack = 0; + for (i = 0; i < 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 (stack[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); + enable_clock_latency_measurement(); + ticks = cyg_current_time(); - diag_printf("\nTiming complete - %d ms total\n", (int)ticks*10); + diag_printf("\nTiming complete - %d ms total\n\n", (int)((ticks*ns_per_system_clock)/1000)); CYG_TEST_PASS_FINISH("Basic timing OK"); } @@ -1289,6 +1546,28 @@ void tm_basic_main( void ) { CYG_TEST_INIT(); + if (cyg_test_is_simulator) { + nsamples = NSAMPLES_SIM; + ntest_threads = NTEST_THREADS_SIM; + nthread_switches = NTHREAD_SWITCHES_SIM; + nmutexes = NMUTEXES_SIM; + nmboxes = NMBOXES_SIM; + nsemaphores = NSEMAPHORES_SIM; + nscheds = NSCHEDS_SIM; + ncounters = NCOUNTERS_SIM; + nalarms = NALARMS_SIM; + } else { + nsamples = NSAMPLES; + ntest_threads = NTEST_THREADS; + nthread_switches = NTHREAD_SWITCHES; + nmutexes = NMUTEXES; + nmboxes = NMBOXES; + nsemaphores = NSEMAPHORES; + nscheds = NSCHEDS; + ncounters = NCOUNTERS; + nalarms = NALARMS; + } + new_thread(run_all_tests, 0); Cyg_Scheduler::scheduler.start(); @@ -1299,4 +1578,20 @@ cyg_start( void ) { tm_basic_main(); } + +#else // CYGFUN_KERNEL_API_C + +externC void +cyg_start( void ) +{ + CYG_TEST_INIT(); + CYG_TEST_PASS_FINISH("Timing tests require:\n" + "CYGFUN_KERNEL_API_C && \n" + "CYGSEM_KERNEL_SCHED_MLQUEUE &&\n" + "CYGVAR_KERNEL_COUNTERS_CLOCK &&\n" + "!CYGPKG_HAL_I386_LINUX &&\n" + "(CYGNUM_KERNEL_SCHED_PRIORITIES > 12)\n"); +} +#endif // CYGFUN_KERNEL_API_C, etc. + // EOF tm_basic.cxx
