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