changeset 738:d3ad681c97ba

* tests/fptest.c: Changed to run for a constant time rather than a constant number of iterations, with a shorter run time for simulated targets.
author nickg
date Mon, 24 Feb 2003 18:08:53 +0000
parents d571f3d1ade0
children 71fb65782f32
files packages/kernel/current/ChangeLog packages/kernel/current/tests/fptest.c
diffstat 2 files changed, 113 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,9 @@
+2003-02-19  Nick Garnett  <nickg@calivar.com>
+
+	* tests/fptest.c: Changed to run for a constant time rather than a
+	constant number of iterations, with a shorter run time for
+	simulated targets.
+
 2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* cdl/kernel.cdl: Update doc links.
--- a/packages/kernel/current/tests/fptest.c
+++ b/packages/kernel/current/tests/fptest.c
@@ -33,8 +33,6 @@
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
 //
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
@@ -72,22 +70,44 @@
     (CYGNUM_KERNEL_SCHED_PRIORITIES > 12)
 
 //==========================================================================
-// Multiplier for loop counter. This allows us to tune the runtime of
-// the whole program easily. The current value gives a runtime of
-// about 90s on an 800Mz Pentium III.
+// Base priority for all threads.
+
+#define BASE_PRI        5
 
-#define MULTIPLIER 100
+//==========================================================================
+// Runtime
+//
+// This is the number of ticks that the program will run for. 3000
+// ticks is equal to 30 seconds in the default configuration. For
+// simulators we reduce the run time to 3 simulated seconds.
+
+#define RUN_TICKS       3000
+#define RUN_TICKS_SIM   300
 
 //==========================================================================
 // Thread parameters
 
-#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM+4096)
+#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM)
 
 cyg_uint8 stacks[3][STACK_SIZE];
 cyg_handle_t thread[3];
 cyg_thread thread_struct[3];
 
 //==========================================================================
+// Alarm parameters.
+
+cyg_alarm alarm_struct;
+cyg_handle_t alarm;
+
+cyg_count8 cur_thread = 0;
+cyg_count32 alarm_ticks = 0;
+cyg_count32 run_ticks = RUN_TICKS;
+
+//==========================================================================
+
+static int errors = 0;
+
+//==========================================================================
 // Random number generator. Ripped out of the C library.
 
 static int rand( unsigned int *seed )
@@ -118,19 +138,22 @@ static int rand( unsigned int *seed )
 // spilling values out to memory.
 
 static void do_test( double *values,
-                    int count,
-                    int loops,
-                    char *name)
+                     int count,
+                     int loops,
+                     int test,
+                     const char *name)
 {
-    int i, j;
-    double sum = 1.0;
-    double last_sum;
+    unsigned int i, j;
+    // volatiles necessary to force
+    // values to 64 bits for comparison
+    volatile double sum = 1.0;
+    volatile double last_sum;
     unsigned int seed;
-
+    
 #define V(__i) (values[(__i)%count])
 #define CALC ((V(i-1)*V(i+1))*(V(i-2)*V(i+2))*(V(i-3)*sum))
 
-    seed = ((unsigned int)&i)*loops*count;
+    seed = ((unsigned int)&i)*count;
 
     // Set up an array of values...
     for( i = 0; i < count; i++ )
@@ -142,100 +165,94 @@ static void do_test( double *values,
     last_sum = sum;
     
     // Now recalculate the sum in a loop and look for errors
-    for( j = 0; j < loops; j++ )
+    for( j = 0; j < loops ; j++ )
     {
         sum = 1.0;
         for( i = 0; i < count; i++ )
             sum += CALC;
 
         if( sum != last_sum )
-            diag_printf("%s: Sum mismatch! %d\n",name,j);
-
-        last_sum = sum;
+        {
+            errors++;
+            diag_printf("%s: Sum mismatch! %d sum=[%08x:%08x] last_sum=[%08x:%08x]\n",
+                        name,j,
+                        ((cyg_uint32 *)&sum)[0],((cyg_uint32 *)&sum)[1],
+                        ((cyg_uint32 *)&last_sum)[0],((cyg_uint32 *)&last_sum)[1]
+                        );
+        }
+        
+#if 0
+        if( ((j*count)%1000000) == 0 )
+            diag_printf("INFO:<%s: %2d calculations done>\n",name,j*count);
+#endif
     }
 
 }
 
 //==========================================================================
+// Alarm handler
+//
+// This is called every tick. It lowers the priority of the currently
+// running thread and raises the priority of the next. Thus we
+// implement a form of timelslicing between the threads at one tick
+// granularity.
 
-volatile int done[4];
+static void alarm_fn(cyg_handle_t alarm, cyg_addrword_t data)
+{
+    alarm_ticks++;
 
-volatile cyg_tick_count_t start, end;
+    if( alarm_ticks >= run_ticks )
+    {
+        if( errors )
+            CYG_TEST_FAIL("Errors detected");
+        
+        CYG_TEST_FINISH("FP Test done");
+    }
+    else
+    {
+        cyg_thread_set_priority( thread[cur_thread], BASE_PRI );
+
+        cur_thread = (cur_thread+1)%3;
+
+        cyg_thread_set_priority( thread[cur_thread], BASE_PRI-1 );
+    }
+}
+
 
 //==========================================================================
 
 #define FP1_COUNT 1000
-#define FP1_LOOPS 1000*MULTIPLIER
 
 static double fpt1_values[FP1_COUNT];
 
 void fptest1( CYG_ADDRWORD id )
 {
-    diag_printf("fptest1: start\n");
-    
-    do_test( &fpt1_values, FP1_COUNT, FP1_LOOPS, "fptest1" );
-
-    done[id] = 1;
-    
-    diag_printf("fptest1: done\n");
+    while(1)
+        do_test( fpt1_values, FP1_COUNT, 2000000000, id, "fptest1" );
 }
 
 //==========================================================================
 
 #define FP2_COUNT 10000
-#define FP2_LOOPS 100*MULTIPLIER
 
 static double fpt2_values[FP2_COUNT];
 
 void fptest2( CYG_ADDRWORD id )
 {
-    diag_printf("fptest2: start\n");
-    
-    do_test( &fpt2_values, FP2_COUNT, FP2_LOOPS, "fptest2" );
-
-    done[id] = 1;
-    
-    diag_printf("fptest2: done\n");
+    while(1)
+        do_test( fpt2_values, FP2_COUNT, 2000000000, id, "fptest2" );
 }
 
 //==========================================================================
 
-#define FP3_COUNT 10000
-#define FP3_LOOPS 100*MULTIPLIER
+#define FP3_COUNT 100
 
 static double fpt3_values[FP3_COUNT];
 
 void fptest3( CYG_ADDRWORD id )
 {
-    int all_done;
-    
-    diag_printf("fptest3: start\n");
-    
-    do_test( &fpt3_values, FP3_COUNT, FP3_LOOPS, "fptest3" );
-
-    done[id] = 1;
-    
-    diag_printf("fptest3: done\n");
-
-    // Spin here waiting for the other threads to finish. We should
-    // only wake up and test every third or second timeslice.
-    do {
-        int i;
-
-        cyg_thread_yield();
-        
-        all_done = 0;
-        for( i = 0; i < 4; i++ )
-            all_done += done[i];
-        
-    } while(all_done != 4 );
-
-    end = cyg_current_time();
-
-    diag_printf("Elapsed time %d ticks\n",end-start);
-    
-    CYG_TEST_PASS_FINISH("FP Test OK");
-    
+    while(1)
+        do_test( fpt3_values, FP3_COUNT, 2000000000, id, "fptest3" );
 }
 
 //==========================================================================
@@ -245,14 +262,18 @@ void fptest_main( void )
     
     CYG_TEST_INIT();
 
-    start = cyg_current_time();
+    if( cyg_test_is_simulator )
+    {
+        run_ticks = RUN_TICKS_SIM;
+    }
+
+    CYG_TEST_INFO("Run fptest in cyg_start");
+    do_test( fpt3_values, FP3_COUNT, 1000, 0, "start" );
+    CYG_TEST_INFO( "cyg_start run done");
     
-    diag_printf("Run fptest1 in cyg_start\n");
-    fptest1( 0 );
-    
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI-1,
                        fptest1,
-                       1,
+                       0,
                        "fptest1",
                        &stacks[0][0],
                        STACK_SIZE,
@@ -261,9 +282,9 @@ void fptest_main( void )
 
     cyg_thread_resume( thread[0] );
 
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI,
                        fptest2,
-                       2,
+                       1,
                        "fptest2",
                        &stacks[1][0],
                        STACK_SIZE,
@@ -272,9 +293,9 @@ void fptest_main( void )
 
     cyg_thread_resume( thread[1] );
 
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI,
                        fptest3,
-                       3,
+                       2,
                        "fptest3",
                        &stacks[2][0],
                        STACK_SIZE,
@@ -282,6 +303,14 @@ void fptest_main( void )
                        &thread_struct[2]);
 
     cyg_thread_resume( thread[2] );
+
+    cyg_alarm_create( cyg_real_time_clock(),
+                      alarm_fn,
+                      0,
+                      &alarm,
+                      &alarm_struct );
+
+    cyg_alarm_initialize( alarm, cyg_current_time()+1, 1 );
     
     cyg_scheduler_start();