This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[APPROVAL REQUIRED] fptest.c updated


Approval needed for v2.0 branch, already committed to the trunk.


Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/ChangeLog,v
retrieving revision 1.94
diff -u -5 -r1.94 ChangeLog
--- ChangeLog	10 Feb 2003 22:02:15 -0000	1.94
+++ ChangeLog	19 Feb 2003 19:09:46 -0000
@@ -1,5 +1,11 @@
+2003-02-19  Nick Garnett  <nickg at calivar dot 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-10  Gary Thomas  <gary at mlbassoc dot com>
 
 	* include/thread.inl: Add more debug info to thread stack checking.
 
 	* tests/clocktruth.cxx: 
Index: tests/fptest.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/kernel/current/tests/fptest.c,v
retrieving revision 1.1
diff -u -5 -r1.1 fptest.c
--- tests/fptest.c	31 Jan 2003 11:44:03 -0000	1.1
+++ tests/fptest.c	19 Feb 2003 19:09:46 -0000
@@ -31,12 +31,10 @@
 // in accordance with section (3) of the GNU General Public License.
 //
 // 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####
 //==========================================================================
 //#####DESCRIPTIONBEGIN####
 //
@@ -70,26 +68,48 @@
 #if defined(CYGFUN_KERNEL_API_C) &&             \
     defined(CYGSEM_KERNEL_SCHED_MLQUEUE) &&     \
     (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 MULTIPLIER 100
+#define BASE_PRI        5
+
+//==========================================================================
+// 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 )
 {
 // This is the code supplied in Knuth Vol 2 section 3.6 p.185 bottom
@@ -116,23 +136,26 @@
 // maximum use of the FPU registers. However, the i386 compiler
 // doesn't let this expression get very complex before it starts
 // spilling values out to memory.
 
 static void do_test( double *values,
-                    int count,
-                    int loops,
-                    char *name)
-{
-    int i, j;
-    double sum = 1.0;
-    double last_sum;
+                     int count,
+                     int loops,
+                     int test,
+                     const char *name)
+{
+    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++ )
         values[i] = (double)rand( &seed )/(double)0x7fffffff;
 
@@ -140,150 +163,156 @@
     for( i = 0; i < count; i++ )
         sum += CALC;
     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.
+
+static void alarm_fn(cyg_handle_t alarm, cyg_addrword_t data)
+{
+    alarm_ticks++;
+
+    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 );
 
-volatile int done[4];
+        cur_thread = (cur_thread+1)%3;
+
+        cyg_thread_set_priority( thread[cur_thread], BASE_PRI-1 );
+    }
+}
 
-volatile cyg_tick_count_t start, end;
 
 //==========================================================================
 
 #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" );
 }
 
 //==========================================================================
 
 void fptest_main( void )
 {
     
     CYG_TEST_INIT();
 
-    start = cyg_current_time();
-    
-    diag_printf("Run fptest1 in cyg_start\n");
-    fptest1( 0 );
+    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");
     
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI-1,
                        fptest1,
-                       1,
+                       0,
                        "fptest1",
                        &stacks[0][0],
                        STACK_SIZE,
                        &thread[0],
                        &thread_struct[0]);
 
     cyg_thread_resume( thread[0] );
 
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI,
                        fptest2,
-                       2,
+                       1,
                        "fptest2",
                        &stacks[1][0],
                        STACK_SIZE,
                        &thread[1],
                        &thread_struct[1]);
 
     cyg_thread_resume( thread[1] );
 
-    cyg_thread_create( 5,
+    cyg_thread_create( BASE_PRI,
                        fptest3,
-                       3,
+                       2,
                        "fptest3",
                        &stacks[2][0],
                        STACK_SIZE,
                        &thread[2],
                        &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();
 
 }
 



-- 
Nick Garnett                    eCos Kernel Architect
http://www.ecoscentric.com/     The eCos and RedBoot experts


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]