Mercurial > ecos
diff packages/kernel/current/tests/tm_basic.cxx @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/kernel/current/tests/tm_basic.cxx @@ -0,0 +1,1302 @@ +//========================================================================== +// +// tm_basic.cxx +// +// Basic timing test / scaffolding +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// 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. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): gthomas +// Contributors: gthomas +// Date: 1998-10-19 +// Description: Very simple timing test setup +//####DESCRIPTIONEND#### + +#include <pkgconf/kernel.h> + +#include <cyg/kernel/sched.hxx> +#include <cyg/kernel/thread.hxx> +#include <cyg/kernel/thread.inl> +#include <cyg/kernel/mutex.hxx> +#include <cyg/kernel/sema.hxx> +#include <cyg/kernel/sched.inl> +#include <cyg/kernel/clock.hxx> +#include <cyg/kernel/clock.inl> +#include <cyg/kernel/kapi.h> + +#include <cyg/infra/testcase.h> +#define NTHREADS 1 +#include "testaux.hxx" + +// Structure used to keep track of times +typedef struct fun_times { + cyg_uint32 start; + cyg_uint32 end; +} fun_times; + +#define NSAMPLES 10 +#define NTEST_THREADS 32 +#define NTHREAD_SWITCHES 128 +#define NMUTEXES 32 +#define NMBOXES 32 +#define NSEMAPHORES 32 +#define NSCHEDS 128 +#define NCOUNTERS 32 +#define NALARMS 32 + +#define STACK_SIZE 2048 // Is this large enough? +static char stacks[NTEST_THREADS][STACK_SIZE]; +static cyg_thread test_threads[NTEST_THREADS]; +static cyg_handle_t threads[NTEST_THREADS]; +static int overhead; +static cyg_sem_t synchro; +static fun_times thread_ft[NTEST_THREADS]; + +static fun_times test2_ft[NTHREAD_SWITCHES]; + +static cyg_mutex_t test_mutexes[NMUTEXES]; +static fun_times mutex_ft[NMUTEXES]; +static cyg_thread mutex_test_thread; +static cyg_handle_t mutex_test_thread_handle; + +static cyg_mbox test_mboxes[NMBOXES]; +static cyg_handle_t test_mbox_handles[NMBOXES]; +static fun_times mbox_ft[NMBOXES]; +static cyg_thread mbox_test_thread; +static cyg_handle_t mbox_test_thread_handle; + +static cyg_sem_t test_semaphores[NSEMAPHORES]; +static fun_times semaphore_ft[NSEMAPHORES]; +static cyg_thread semaphore_test_thread; +static cyg_handle_t semaphore_test_thread_handle; + +static fun_times sched_ft[NSCHEDS]; + +static cyg_counter test_counters[NCOUNTERS]; +static cyg_handle_t counters[NCOUNTERS]; +static fun_times counter_ft[NCOUNTERS]; + +static cyg_alarm test_alarms[NALARMS]; +static cyg_handle_t alarms[NALARMS]; +static fun_times alarm_ft[NALARMS]; + +externC void diag_printf(const char *, ...); +externC void sprintf(char *, const char *, ...); + +void run_sched_tests(void); +void run_thread_tests(void); +void run_thread_switch_test(void); +void run_mutex_tests(void); +void run_mutex_circuit_test(void); +void run_mbox_tests(void); +void run_mbox_circuit_test(void); +void run_semaphore_tests(void); +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); + while (true) { + HAL_CLOCK_READ(&tv1); + if (tv1 < tv0) break; + tv0 = tv1; + } +} + +// Compute a name for a thread +char * +thread_name(char *basename, int indx) { + return "<<NULL>>"; // Not currently used +} + +// test0 - null test, never executed +void +test0(cyg_uint32 indx) +{ + diag_printf("test0.%d executed?\n", indx); + cyg_thread_exit(); +} + +// test1 - empty test, simply exit. Last thread signals parent. +void +test1(cyg_uint32 indx) +{ + if (indx == (NTEST_THREADS-1)) { + cyg_semaphore_post(&synchro); // Signal that last thread is dying + } + cyg_thread_exit(); +} + +// test2 - measure thread switch times +void +test2(cyg_uint32 indx) +{ + int i; + for (i = 0; i < NTHREAD_SWITCHES; i++) { + if (indx == 0) { + HAL_CLOCK_READ(&test2_ft[i].start); + } else { + HAL_CLOCK_READ(&test2_ft[i].end); + } + cyg_thread_yield(); + } + if (indx == 1) { + cyg_semaphore_post(&synchro); + } + cyg_thread_exit(); +} + +// Full-circuit mutex unlock/lock test +void +mutex_test(cyg_uint32 indx) +{ + int i; + cyg_mutex_lock(&test_mutexes[0]); + 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); + cyg_mutex_unlock(&test_mutexes[0]); + cyg_mutex_lock(&test_mutexes[0]); + cyg_semaphore_post(&synchro); + } + cyg_thread_exit(); +} + +// Full-circuit mbox put/get test +void +mbox_test(cyg_uint32 indx) +{ + void *item; + do { + 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)); + cyg_thread_exit(); +} + +// Full-circuit semaphore post/wait test +void +semaphore_test(cyg_uint32 indx) +{ + int i; + for (i = 0; i < NSEMAPHORES; i++) { + cyg_semaphore_wait(&test_semaphores[0]); + HAL_CLOCK_READ(&semaphore_ft[i].end); + cyg_semaphore_post(&synchro); + } + 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"); +} + +void +run_thread_tests(void) +{ + int i; + cyg_priority_t prio; + + // Set my priority higher than any I plan to create + 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++) { + HAL_CLOCK_READ(&thread_ft[i].start); + 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 + ); + HAL_CLOCK_READ(&thread_ft[i].end); + } + 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++) { + 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]"); + + 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 [suspended] 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 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_set_priority(threads[i], 11); + HAL_CLOCK_READ(&thread_ft[i].end); + } + 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++) { + 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"); + + 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_kill(threads[i]); + HAL_CLOCK_READ(&thread_ft[i].end); + } + 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++) { + 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"); + + // 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++) { + 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 + ); + } + + 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"); + + 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 [runnable low priority] 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++) { + 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_kill(threads[i]); + HAL_CLOCK_READ(&thread_ft[i].end); + } + show_times(thread_ft, NTEST_THREADS, "Kill [runnable] thread"); + // Set my priority lower than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 3); + + // Set up the end-of-threads synchronizer + cyg_semaphore_init(&synchro, 0); + + // Recreate the test set + for (i = 0; i < NTEST_THREADS; i++) { + cyg_thread_create(2, // Priority - just a number + test1, // entry + i, // index + thread_name("thread", i), // Name + &stacks[i][0], // Stack + STACK_SIZE, // Size + &threads[i], // Handle + &test_threads[i] // Thread data structure + ); + } + + 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 [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]); + } + + run_thread_switch_test(); +} + +void +run_thread_switch_test(void) +{ + int i; + + // Set up for thread context switch + for (i = 0; i < 2; i++) { + cyg_thread_create(10, // Priority - just a number + test2, // 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]); + } + // Set up the end-of-threads synchronizer + 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"); + // Clean up + for (i = 0; i < 2; i++) { + cyg_thread_kill(threads[i]); + } +} + +void +run_mutex_tests(void) +{ + int i; + + // Mutex primitives + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + run_mutex_circuit_test(); +} + +void +run_mutex_circuit_test(void) +{ + int i; + // Set my priority lower than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 4); + // Set up for full mutex unlock/lock test + cyg_mutex_init(&test_mutexes[0]); + cyg_semaphore_init(&synchro, 0); + cyg_thread_create(3, // Priority - just a number + mutex_test, // entry + 0, // index + thread_name("thread", 0), // Name + &stacks[0][0], // Stack + STACK_SIZE, // Size + &mutex_test_thread_handle, // Handle + &mutex_test_thread // Thread data structure + ); + 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++) { + 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"); +} + +void +run_mbox_tests(void) +{ + int i, cnt; + void *item; + // Mailbox primitives + 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_create(&test_mbox_handles[i], &test_mboxes[i]); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + 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++) { + 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"); + + 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 [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"); + + 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 [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); + cyg_mbox_tryput(test_mbox_handles[i], (void *)i); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + 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++) { + 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"); + + 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_tryget(test_mbox_handles[i]); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + 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++) { + 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"); + + 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_tryget(test_mbox_handles[i]); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + 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++) { + 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"); + + 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_waiting_to_put(test_mbox_handles[i]); + HAL_CLOCK_READ(&mbox_ft[i].end); + } + 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++) { + 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"); + + run_mbox_circuit_test(); +} + +void +run_mbox_circuit_test(void) +{ + int i; + // Set my priority lower than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 3); + // Set up for full mbox put/get test + cyg_mbox_create(&test_mbox_handles[0], &test_mboxes[0]); + cyg_semaphore_init(&synchro, 0); + cyg_thread_create(2, // Priority - just a number + mbox_test, // entry + 0, // index + thread_name("thread", 0), // Name + &stacks[0][0], // Stack + STACK_SIZE, // Size + &mbox_test_thread_handle, // Handle + &mbox_test_thread // Thread data structure + ); + cyg_thread_resume(mbox_test_thread_handle); + 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"); +} + +void +run_semaphore_tests(void) +{ + int i; + cyg_ucount32 sem_val; + // Semaphore primitives + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + run_semaphore_circuit_test(); +} + +void +run_semaphore_circuit_test(void) +{ + int i; + // Set my priority lower than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 3); + // Set up for full semaphore post/wait test + cyg_semaphore_init(&test_semaphores[0], 0); + cyg_semaphore_init(&synchro, 0); + cyg_thread_create(2, // Priority - just a number + semaphore_test, // entry + 0, // index + thread_name("thread", 0), // Name + &stacks[0][0], // Stack + STACK_SIZE, // Size + &semaphore_test_thread_handle, // Handle + &semaphore_test_thread // Thread data structure + ); + cyg_thread_resume(semaphore_test_thread_handle); + 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"); +} + +void +run_counter_tests(void) +{ + int i; + cyg_tick_count_t val; + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); +} + +// Alarm callback function +void +alarm_cb(cyg_handle_t alarm, cyg_addrword_t val) +{ + // empty call back +} + +// Callback used to test determinancy +static volatile int alarm_cnt; +void +alarm_cb2(cyg_handle_t alarm, cyg_addrword_t indx) +{ + if (alarm_cnt == NSCHEDS) return; + sched_ft[alarm_cnt].start = 0; + HAL_CLOCK_READ(&sched_ft[alarm_cnt++].end); + if (alarm_cnt == NSCHEDS) { + cyg_semaphore_post(&synchro); + } +} + +// Null thread, used to keep scheduler busy +void +alarm_test(cyg_uint32 id) +{ + while (true) { + cyg_thread_yield(); + } +} + +void +run_alarm_tests(void) +{ + int i; + cyg_tick_count_t init_val, step_val; + cyg_handle_t rtc_handle; + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + for (i = 0; i < NCOUNTERS; i++) { + cyg_counter_create(&counters[i], &test_counters[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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + init_val = 0; step_val = 0; + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + init_val = 0; step_val = 0; + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + init_val = 0; step_val = 0; + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + cyg_counter_create(&counters[0], &test_counters[0]); + cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); + 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++) { + 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]"); + + 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, 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++) { + 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]"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + cyg_counter_create(&counters[0], &test_counters[0]); + cyg_alarm_create(counters[0], alarm_cb, 0, &alarms[0], &test_alarms[0]); + 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++) { + 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]"); + + 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 = 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); + cyg_counter_tick(counters[0]); + HAL_CLOCK_READ(&counter_ft[i].end); + } + for (i = 0; i < NALARMS; i++) { + cyg_alarm_delete(alarms[i]); + } + show_times(counter_ft, NCOUNTERS, "Tick & fire counter [many alarms]"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); + cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); + init_val = 5; step_val = 5; alarm_cnt = 0; + cyg_alarm_initialize(alarms[0], init_val, step_val); + cyg_semaphore_init(&synchro, 0); + cyg_alarm_enable(alarms[0]); + cyg_semaphore_wait(&synchro); + cyg_alarm_disable(alarms[0]); + cyg_alarm_delete(alarms[0]); + 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); + for (i = 0; i < 2; i++) { + cyg_thread_create(10, // Priority - just a number + alarm_test, // 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 + cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); + cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); + init_val = 5; step_val = 5; alarm_cnt = 0; + cyg_alarm_initialize(alarms[0], init_val, step_val); + cyg_semaphore_init(&synchro, 0); + cyg_alarm_enable(alarms[0]); + cyg_semaphore_wait(&synchro); + cyg_alarm_disable(alarms[0]); + cyg_alarm_delete(alarms[0]); + 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]); + } + + // 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++) { + cyg_thread_create(10, // Priority - just a number + alarm_test, // 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 + cyg_clock_to_counter(cyg_real_time_clock(), &rtc_handle); + cyg_alarm_create(rtc_handle, alarm_cb2, 0, &alarms[0], &test_alarms[0]); + init_val = 5; step_val = 5; alarm_cnt = 0; + cyg_alarm_initialize(alarms[0], init_val, step_val); + cyg_semaphore_init(&synchro, 0); + cyg_alarm_enable(alarms[0]); + 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++) { + cyg_thread_suspend(threads[i]); + cyg_thread_kill(threads[i]); + } +} + +void +run_sched_tests(void) +{ + int i; + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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"); + + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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]"); + + // Set my priority higher than any I plan to create + cyg_thread_set_priority(cyg_thread_self(), 2); + for (i = 0; i < 1; 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 + ); + } + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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]"); + for (i = 0; i < 1; i++) { + cyg_thread_kill(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++) { + 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 + ); + } + wait_for_tick(); // Wait until the next clock tick to minimize aberations + 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]); + } + + // 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++) { + 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 < 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]); + } +} + +void +run_all_tests(CYG_ADDRESS id) +{ + int i; + cyg_uint32 tv[NSAMPLES], tv0, tv1, us; + cyg_tick_count_t ticks; +#ifdef CYG_SCHEDULER_LOCK_TIMINGS + cyg_uint32 lock_ave, lock_max; +#endif +#ifdef HAL_CLOCK_LATENCY + cyg_int32 clock_ave; +#endif + + 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]; + } + } + diag_printf("\n"); + + overhead = tv0 / (NSAMPLES-1); + diag_printf("Average %d clock ticks overhead\n", overhead); + + // 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; + } + 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); + + ticks = cyg_current_time(); + diag_printf("Ticks: %x\n", (int)ticks); + + show_test_parameters(); + show_times_hdr(); + + run_thread_tests(); + run_sched_tests(); + run_mutex_tests(); + run_mbox_tests(); + run_semaphore_tests(); + run_counter_tests(); + run_alarm_tests(); + +#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)); +#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)); +#endif + + ticks = cyg_current_time(); + diag_printf("\nTiming complete - %d ms total\n", (int)ticks*10); + + CYG_TEST_PASS_FINISH("Basic timing OK"); +} + +void tm_basic_main( void ) +{ + CYG_TEST_INIT(); + + new_thread(run_all_tests, 0); + + Cyg_Scheduler::scheduler.start(); +} + +externC void +cyg_start( void ) +{ + tm_basic_main(); +} +// EOF tm_basic.cxx
