]> rtime.felk.cvut.cz Git - frescor/fosa.git/blobdiff - src_marte/tests/test_non_local_jump/testbench_long_jump.c
Time abstraction added to FOSA to replace timespec_operations
[frescor/fosa.git] / src_marte / tests / test_non_local_jump / testbench_long_jump.c
index 3fb9e6763be647badb8d78ff12889afa217d79f6..ddae7ab83522782de375e7de5d47bfbe6c25e6ba 100644 (file)
@@ -7,23 +7,46 @@
 ** Started on  Fri Nov 23 11:42:09 2007 Miguel marciano
 ** Last update Sun May 12 01:17:25 2002 Speed Blue
 */
+
+/*
+  TO DO:
+
+  -  Define a pthread_join equivalent in FOSA (and also the detachable
+     argument).
+  -  Define a clock_nanosleep equivalent in FOSA.
+
+*/
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h> // For clock_nanosleep
 
-#include "frsh_error.h"
 #include "fosa.h"
-#include "frsh_fosa.h"
-#include "timespec_operations.h"
+
+#include <misc/error_checks.h>
+
 
 /*************************/
 /* D E F I N I T I O N S */
 /*************************/
-#define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 3)
-#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 5)
+#define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 5)
+#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
 
+#define NUMBER_OF_JUMPS 100
+
+typedef struct _results_t
+{
+    double first_jump_interval_ms;
+    double average_jump_interval_ms;
+    double min_jump_interval_ms;
+    int iteration_min_jump_interval;
+    double max_jump_interval_ms;
+    int iteration_max_jump_interval;
+    double total_jump_interval_ms;
+    int  number_of_jumps;
+} results_t;
 
 /*************************/
 /*  P R O T O T Y P E S  */
@@ -36,34 +59,42 @@ static void *periodic_code(void *thread_arg);
 static fosa_long_jump_context_t context;
 static void work_under_a_interruptible_budget();
 
+fosa_abs_time_t before_jump_timestamp;
+
 
 int main()
 {
-    int terror = -1;
-    frsh_thread_attr_t periodic_attr;
-    frsh_signal_t signal_set[1];
-    frsh_thread_id_t periodic_tid;
+    fosa_thread_attr_t periodic_attr;
+    fosa_signal_t signal_set[1];
+    fosa_thread_id_t periodic_tid;
+    results_t results;
 
     memset(&context, 0, sizeof(context) );
 
-    memset(&periodic_attr, 0, sizeof(periodic_attr) );
-    memset(&signal_set, 0, sizeof(signal_set) );
-    memset(&periodic_tid, 0, sizeof(periodic_tid) );
-
 
     /* We set the signal mask */
     signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
-    PRW(  fosa_set_accepted_signals(signal_set, 1) );
+    CHK(  fosa_set_accepted_signals(signal_set, 1) );
 
     /* We create a new thread with a given priority */
-    PRW(  frsh_thread_attr_init(&periodic_attr) );
-    PRW(  fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY)  );
-    PRW(  fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, NULL) );
+    CHK(  fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY) );
 
-    printf("Main goes to sleep...\n");
+    CHK(  fosa_thread_attr_init(&periodic_attr) );
+    CHK(  fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY)  );
+    CHK(  fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, &results) );
 
-    sleep(2000);
+    printf("Main waits for the periodic code to finish...\n");
+    pthread_join(periodic_tid, NULL);
+    
+    results.average_jump_interval_ms = results.total_jump_interval_ms/results.number_of_jumps;
+
+    printf("------------  RESULTS -------------\n");
+    printf("First Time:  %6.3f ms\n  Max Time: %6.3f ms   Iteration %d  Min Time: %6.3f ms Iteration %d\n",
+           results.first_jump_interval_ms, results.max_jump_interval_ms, results.iteration_max_jump_interval,
+           results.min_jump_interval_ms, results.iteration_min_jump_interval);
+    printf("Average_time: %6.3f ms   Total jumps: %d\n", results.average_jump_interval_ms, results.number_of_jumps);
 
+    printf("End of test\n");
     return 0;
 }
 
@@ -72,29 +103,26 @@ int main()
 
 static void *periodic_code(void *thread_arg)
 {
-    int terror = -1;
-
-    struct timespec period = {2, 500000000};  // 2.5 secs
-    frsh_thread_id_t jump_handler_thread;
+    fosa_thread_id_t jump_handler_thread;
 
-    frsh_signal_t jump_signal;
-    frsh_signal_info_t jump_signal_info;
+    fosa_signal_t jump_signal;
+    fosa_signal_info_t jump_signal_info;
 
     fosa_clock_id_t clock_id;
     fosa_timer_id_t jump_timer;
 
-    memset(&jump_signal, 0, sizeof(jump_signal) );
-    memset(&jump_signal_info, 0, sizeof(jump_signal_info) );
-    memset(&jump_handler_thread, 0, sizeof(jump_handler_thread) );
-    memset(&clock_id, 0, sizeof(clock_id) );
-    memset(&jump_timer, 0, sizeof(jump_timer) );
+    /* testbench data */
+    results_t *results;
+    int first_time = 1;
 
+
+    results = (results_t *) thread_arg;
     
     /* We install a long jump handler               */
     /* - This creates the thread that will wait for */
     /*   FOSA_JUMP_SIGNAL                           */
     /************************************************/
-    PXW(  fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
+    CHK(  fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
     
     /* We create a budget timer using the thread's CPU clock */
     /*                                                       */
@@ -104,69 +132,92 @@ static void *periodic_code(void *thread_arg)
     /*                                                       */
     /* This signal is delivered to the handler thread.       */
     /*********************************************************/
-    PXW(  fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
+    CHK(  fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
     jump_signal_info.sival_ptr = &context;
-    PXW(  fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info, 
+    CHK(  fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info, 
                                           &jump_timer, jump_handler_thread)  );
 
-    
+    results->number_of_jumps = 0;
+
     /* Periodic loop */
     /*****************/
-    while (1)
+    while (results->number_of_jumps < NUMBER_OF_JUMPS)
     {
         int jumped = -1;
-        struct timespec budget = {1, 400000000};  // 1.4 secs
-        struct timespec activation_time = {-1, -1};
-        struct timespec old_activation_time = {-1, -1};
+        fosa_rel_time_t budget = fosa_msec_to_rel_time(20);  // 20 ms
 
+        fosa_abs_time_t after_jump_timestamp;
+        fosa_rel_time_t jump_interval;
+        double jump_interval_ms = 0.0;
 
+        
 
+        /* We initialise variables */
         jumped = 0;
-
-        /* For statistical purposes we read the activation time */
-        PXW(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
-
+        memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
 
 
         /* Start of the interruptible block */
         /************************************/
 
         /* We arm the jump_timer */
-        PXW(  fosa_timer_arm(jump_timer, false, &budget) );
+        fosa_rel_timer_arm(jump_timer, &budget);
 
+        
         /* This is the point where the jump returns */
-        PXW(  fosa_long_jump_save_context(&context) );
+        fosa_long_jump_save_context(&context);
 
         /* Query if we come from a jump */
-        PXW(  fosa_long_jump_was_performed(&context, &jumped) );
+        fosa_long_jump_was_performed(&context, &jumped);
         if (!jumped)
         {
             /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
             work_under_a_interruptible_budget();
-            printf("NOT JUMPPED\n");
+            printf("We should not arrive here \n");
+            exit(1);
         }
         else
         {
-            printf("JUMPPPPPEEED\n");
+            fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_jump_timestamp);
+
+            results->number_of_jumps++;
+            jump_interval = fosa_abs_time_extract_interval(before_jump_timestamp, after_jump_timestamp);
+            jump_interval_ms = fosa_rel_time_to_msec(jump_interval);
+
+            if (first_time)
+            {
+                results->first_jump_interval_ms = jump_interval_ms;
+
+                results->max_jump_interval_ms = jump_interval_ms;
+                results->iteration_max_jump_interval = results->number_of_jumps;
+
+                results->min_jump_interval_ms = jump_interval_ms;
+                results->iteration_min_jump_interval = results->number_of_jumps;
+
+                first_time = 0;
+            }
+            results->total_jump_interval_ms += jump_interval_ms;
+
+            if (jump_interval_ms > results->max_jump_interval_ms)
+            {
+                results->max_jump_interval_ms = jump_interval_ms;
+                results->iteration_max_jump_interval = results->number_of_jumps;
+            }
+
+            if (jump_interval_ms < results->min_jump_interval_ms)
+            {
+                results->min_jump_interval_ms = jump_interval_ms;
+                results->iteration_min_jump_interval = results->number_of_jumps;
+            }
+       
+            printf("Jump Iteration: %d\r", results->number_of_jumps);
         }
 
-        
         /* End of interruptible work */
         /*****************************/
+    }
 
-        printf("After interruptible block\n");
-        
-        /* Now we measure the time duration of the block */
-        /*************************************************/
-        PXW(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &old_activation_time)  );
-        decr_timespec(&old_activation_time, &activation_time);
-        printf("Execution time: %6.3f\n", t2d(old_activation_time) );
     
-        /* And we program the next loop */
-        incr_timespec(&activation_time, &period);
-        clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_time,
-                        &old_activation_time);
-    }
         
     return NULL;
 }
@@ -176,25 +227,10 @@ static void *periodic_code(void *thread_arg)
 
 static void work_under_a_interruptible_budget()
 {
-    static int i = 0;
-    struct timespec exec_time = {1, 0};  // 1 seg
-
-    i++;
-    printf("Start regular work\n");
-
-    frsh_eat(&exec_time);
-
-    /* Once in every 5 executions we work over the budget */
-    if (i % 5 == 0)
+    /* This must be measured */
+    while(1)
     {
-        frsh_eat(&exec_time);
-        frsh_eat(&exec_time);
-        frsh_eat(&exec_time);
-        frsh_eat(&exec_time);
-        frsh_eat(&exec_time);
-        frsh_eat(&exec_time);
+        fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_jump_timestamp);
     }
 
-    printf("End regular work\n");
-    
 }