]> rtime.felk.cvut.cz Git - frescor/fosa.git/commitdiff
Adding fosa_long_jump_calibrate
authortelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Wed, 28 Nov 2007 19:19:41 +0000 (19:19 +0000)
committertelleriam <telleriam@35b4ef3e-fd22-0410-ab77-dab3279adceb>
Wed, 28 Nov 2007 19:19:41 +0000 (19:19 +0000)
git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@912 35b4ef3e-fd22-0410-ab77-dab3279adceb

src_marte/tests/test_non_local_jump/Makefile
src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c [new file with mode: 0644]

index d2539bfe2e576f6ac26d8e187650ec704d0f448a..da7fd9d0557afe42984c1c371534cb1f37d90a9e 100644 (file)
@@ -11,6 +11,7 @@ testbench_long_jump.exe:  testbench_long_jump.c frsh_error.o libfosa
 
 test_fosa_long_jump.exe:  test_fosa_long_jump.c frsh_error.o libfosa
 
+fosa_long_jump_calibrate.exe:  fosa_long_jump_calibrate.c frsh_error.o libfosa
 
 
 
diff --git a/src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c b/src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c
new file mode 100644 (file)
index 0000000..c120370
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+** testbench_long_jump.c
+** 
+** Made by (Miguel marciano)
+** Login   <miguel@namir.ctr.unican.es>
+** 
+** Started on  Fri Nov 23 11:42:09 2007 Miguel marciano
+** Last update Sun May 12 01:17:25 2002 Speed Blue
+*/
+
+/*
+  TO DO:
+
+  Objective:  To get the following overhead:
+
+  -  fixed_abort_ovhd:  install handler (only for worst case)
+                        save context
+                        jumped return
+                        fosa_long_jump_was_performed
+
+  -  fixed_memory_copy_ovhd:  Copying memory areas of 0 bytes
+  -  memory_copy_per_byte_ovhd:  Variable copying memory areas per byte.
+
+  NOTES:  I don't take the mutex
+
+*/
+
+#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"
+
+
+
+/*************************/
+/* D E F I N I T I O N S */
+/*************************/
+#define NUMBER_OF_TESTS 100
+#define MINIMUM_BUDGET_FOR_TIMER_USECS 100
+
+#define CALIBRATE_THREAD_PRIORITY (fosa_get_priority_min() + 4)
+#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
+
+
+
+#define SIGNAL_CALIBRATE_FINISHED (FRSH_SIGNAL_MIN + 6)
+
+typedef struct _individual_results_t
+{
+    double first_interval_usec;
+    
+    /* The rest of min, max and average are taken over the REST of the
+       tests */
+    double average_interval_usec;
+    double min_interval_usec;
+    int iteration_min_interval;
+    double max_interval_usec;
+    int iteration_max_interval;
+    double total_interval_usec;
+    int  number_of_tries;
+
+} individual_results_t;
+
+typedef struct _thread_data_t
+{
+    individual_results_t *results;
+    frsh_thread_id_t parent_tid;
+} thread_data_t;
+
+typedef struct _measurements
+{
+    individual_results_t fixed_abort_ovhd;
+    individual_results_t fixed_memory_copy_ovhd;
+    individual_results_t memory_copy_per_byte_ovhd;
+} measurements_t;
+
+
+/*************************/
+/*  P R O T O T Y P E S  */
+/*************************/
+static void work_under_a_interruptible_budget();
+
+static int frsh_sharedobj_calibrate(measurements_t *measurements);
+static void *calibrate_thread_code(void *thread_arg);
+static void print_results(individual_results_t results);
+
+
+int main()
+{
+    int terror = -1;
+    measurements_t measurements;
+    
+    memset(&measurements, 0, sizeof(measurements) );
+
+    /* We set the signal mask */
+
+    PRW(  frsh_sharedobj_calibrate(&measurements) );
+
+    /* Print info here */
+    printf("FIXED ABORT OVHD:\n");
+    print_results(measurements.fixed_abort_ovhd);
+
+    printf("End of test\n");
+    return 0;
+}
+
+// -----------------------------------------------------------------
+    
+static int frsh_sharedobj_calibrate(measurements_t *measurements)
+{
+    int terror = -1;
+
+    frsh_signal_t signal_set[1];
+    thread_data_t thread_data;
+
+    frsh_thread_attr_t calibrate_thread_attr;
+    frsh_thread_id_t calibrate_tid;
+
+    frsh_signal_t signal_received;
+    frsh_signal_info_t signal_info_received;
+    
+
+    memset(&signal_set, 0, sizeof(signal_set) );
+    memset(&thread_data, 0, sizeof(thread_data) );
+
+    memset(&calibrate_thread_attr, 0, sizeof(calibrate_thread_attr) );
+    memset(&calibrate_tid, 0, sizeof(calibrate_tid) );
+
+    memset(&signal_received, 0, sizeof(signal_received) );
+    memset(&signal_info_received, 0, sizeof(signal_info_received) );
+
+    
+    /* We set the signal mask and adjust our priority */
+    /**************************************************/
+    signal_set[0] = SIGNAL_CALIBRATE_FINISHED;
+    PRW(  fosa_set_accepted_signals(signal_set, 1) );
+    PRW(  fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY)  );
+
+    /* We measure the fixed_abort_ovhd */
+    /***********************************/
+    thread_data.results = &measurements->fixed_abort_ovhd;
+    thread_data.parent_tid = pthread_self();
+
+    PRW(  frsh_thread_attr_init(&calibrate_thread_attr) );
+    PRW(  fosa_thread_attr_set_prio(&calibrate_thread_attr, CALIBRATE_THREAD_PRIORITY)  );
+    PRW(  fosa_thread_create(&calibrate_tid, &calibrate_thread_attr, calibrate_thread_code, 
+                             &thread_data ) );
+
+    printf("Main waits for the calibrate code to finish...\n");
+    PRW(  fosa_signal_wait(signal_set, 1, &signal_received, &signal_info_received) );
+    
+    return 0;
+}
+
+
+// ------------------------------------------------------------------------
+
+typedef struct _protection_parameters
+{
+    bool initialised;
+    fosa_clock_id_t cpu_clock;
+    frsh_thread_id_t jump_handler_thread;
+    frsh_signal_t jump_signal;
+    frsh_signal_info_t jump_signal_info;
+    fosa_timer_id_t jump_timer;
+} protection_parameters_t;
+
+// ------------------------------------------------------------------------
+
+static void *calibrate_thread_code(void *thread_arg)
+{
+    int terror = -1;
+
+    thread_data_t *thread_data = NULL;
+    individual_results_t *results = NULL;
+
+    bool first_time = false;
+    bool stats_initialised = false;
+    protection_parameters_t protection_parameters;
+
+    frsh_signal_info_t signal_info_to_send;
+
+    memset(&protection_parameters, 0, sizeof(protection_parameters) );
+    memset(&signal_info_to_send, 0, sizeof(signal_info_to_send) );
+    
+
+    thread_data = (thread_data_t *) thread_arg;
+    results = thread_data->results;
+    
+
+    /* Periodic loop */
+    /*****************/
+    first_time = true;
+    stats_initialised = false;  // For the second time onwards
+    protection_parameters.initialised = false;
+
+    results->number_of_tries = 0;
+    while (results->number_of_tries < NUMBER_OF_TESTS)
+    {
+        int jumped = -1;
+        struct timespec budget = {-1, -1};
+        static fosa_long_jump_context_t context;
+
+        struct timespec before_timestamp = {-1, -1 };
+        struct timespec after_timestamp = {-1, -1 };
+        double interval_usec = 0.0;
+
+        
+        /* We initialise variables */
+        jumped = 0;
+        memset(&before_timestamp, 0, sizeof(before_timestamp) );
+        memset(&after_timestamp, 0, sizeof(after_timestamp) );
+
+        budget.tv_sec = 0;
+        budget.tv_nsec = MINIMUM_BUDGET_FOR_TIMER_USECS * 1000;
+        
+
+        /*  S T A R T   M E A S U R I N G   H E R E  */
+        /*********************************************/
+        fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_timestamp);
+        
+
+        /* This is only executed once per thread */
+        if (protection_parameters.initialised == false)
+        {
+            PXW(  fosa_long_jump_install_handler(&protection_parameters.jump_signal, 
+                                           &protection_parameters.jump_handler_thread) );
+
+            PXW(  fosa_thread_get_cputime_clock( fosa_thread_self(), &protection_parameters.cpu_clock) );
+            protection_parameters.jump_signal_info.sival_ptr = &context;
+            
+            PXW(  fosa_timer_create_with_receiver(protection_parameters.cpu_clock, 
+                                                  protection_parameters.jump_signal, 
+                                                  protection_parameters.jump_signal_info,
+                                                  &protection_parameters.jump_timer,
+                                                  protection_parameters.jump_handler_thread)  );
+
+            protection_parameters.initialised = true;
+        }
+
+        /* We arm the jump_timer */
+        fosa_timer_arm(protection_parameters.jump_timer, false, &budget);
+        
+        /* This is the point where the jump returns */
+        fosa_long_jump_save_context(&context);
+
+        /* Query if we come from a jump */
+        fosa_long_jump_was_performed(&context, &jumped);
+        if (!jumped)
+        {
+            /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
+            work_under_a_interruptible_budget();
+            PERROR_AND_EXIT(FRSH_ERR_INTERNAL_ERROR, "The jump should always prevent us from arriving here\n");
+        }
+
+        /*  E N D    O F    M E A S U R I N G     H E R E  */
+        /***************************************************/
+        fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_timestamp);
+
+        results->number_of_tries++;
+        decr_timespec(&after_timestamp, &before_timestamp);
+        interval_usec = t2d(after_timestamp) * 1000000;
+
+        /* We remove the 20 ms that we made it wait for */
+        interval_usec -= MINIMUM_BUDGET_FOR_TIMER_USECS;
+
+        if (first_time)
+        {
+            results->first_interval_usec = interval_usec;
+            first_time = false;
+        }
+        else
+        {
+            if (stats_initialised == false)
+            {
+                results->max_interval_usec = interval_usec;
+                results->iteration_max_interval = results->number_of_tries;
+            
+                results->min_interval_usec = interval_usec;
+                results->iteration_min_interval = results->number_of_tries;
+            
+                stats_initialised = true;
+            }
+        
+            results->total_interval_usec += interval_usec;
+
+            if (interval_usec > results->max_interval_usec)
+            {
+                results->max_interval_usec = interval_usec;
+                results->iteration_max_interval = results->number_of_tries;
+            }
+            
+            if (interval_usec < results->min_interval_usec)
+            {
+                results->min_interval_usec = interval_usec;
+                results->iteration_min_interval = results->number_of_tries;
+            }
+        }
+    }
+
+    results->average_interval_usec = results->total_interval_usec / (results->number_of_tries - 1);
+
+    PXW(  fosa_signal_queue(SIGNAL_CALIBRATE_FINISHED, signal_info_to_send, thread_data->parent_tid) );
+
+    return NULL;
+}
+
+
+// ------------------------------------------------------------------------------
+
+static void work_under_a_interruptible_budget()
+{
+    struct timespec upper_execution_limit = {1, 0};
+
+    frsh_eat(&upper_execution_limit);
+}
+
+// ------------------------------------------------------------------------------
+
+static void print_results(individual_results_t results)
+{
+    
+    printf("FIRST interval time:  %6.3f usecs.  All other stats apply to other invocations\n",
+           results.average_interval_usec);
+    printf("MAX interval time: %6.3f usecs at %d try,     MIN interval time: %6.3f usecs at %d try\n",
+           results.max_interval_usec, results.iteration_max_interval,
+           results.min_interval_usec, results.iteration_min_interval);
+
+    printf("AVERAGE interval time:  %6.3f usecs, Number of tries: %d\n",
+           results.average_interval_usec, results.number_of_tries);
+}