From: telleriam Date: Fri, 30 Nov 2007 10:00:26 +0000 (+0000) Subject: Reworking fosa_long_jump_calibrate to work with timespec instead of float X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/fosa.git/commitdiff_plain/b4d5934826147d91ca6831f599cdff2031b05efb Reworking fosa_long_jump_calibrate to work with timespec instead of float git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@915 35b4ef3e-fd22-0410-ab77-dab3279adceb --- 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 index e703496..e905db9 100644 --- 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 @@ -30,6 +30,9 @@ #include #include #include // For clock_nanosleep +#include + +#include #include "frsh_error.h" #include "fosa.h" @@ -42,28 +45,35 @@ /* D E F I N I T I O N S */ /*************************/ #define NUMBER_OF_TESTS 100 -#define MINIMUM_BUDGET_FOR_TIMER_USECS 100 + +static struct timespec minimum_budget_for_timer = {0, 100000}; // 100 us + +#define NUMBER_OF_BYTES_TO_SIMULATE 10000 // Stack limit 40k in + // current MaRTE configuration #define CALIBRATE_THREAD_PRIORITY (fosa_get_priority_min() + 4) #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3) - +#define MINIMUM_BUDGET_FOR_TIMER_USECS 100 #define SIGNAL_CALIBRATE_FINISHED (FRSH_SIGNAL_MIN + 6) typedef struct _individual_results_t { - double first_interval_usec; + int first_time_passed; + int second_time_passed; + + struct timespec first_interval; /* The rest of min, max and average are taken over the REST of the tests */ - double average_interval_usec; - double min_interval_usec; + struct timespec average_interval; + struct timespec min_interval; int iteration_min_interval; - double max_interval_usec; + struct timespec max_interval; int iteration_max_interval; - double total_interval_usec; - int number_of_tries; + struct timespec total_interval; + long int number_of_tries; } individual_results_t; @@ -86,10 +96,20 @@ typedef struct _measurements /*************************/ static void work_under_a_interruptible_budget(); -static int frsh_sharedobj_calibrate(measurements_t *measurements); +static int frsh_sharedobj_calibrate(individual_results_t *fixed_abort_ovhd, + individual_results_t *fixed_memory_copy_ovhd, + individual_results_t *memory_copy_per_byte_ovhd); + + static void *calibrate_thread_code(void *thread_arg); +static void process_result(individual_results_t *results, struct timespec interval); static void print_results(individual_results_t results); +static struct timespec timespec_divide_by_int(struct timespec numerator, long int denominator); + + + + int main() { @@ -100,11 +120,18 @@ int main() /* We set the signal mask */ - PRW( frsh_sharedobj_calibrate(&measurements) ); + PRW( frsh_sharedobj_calibrate(&measurements.fixed_abort_ovhd, + &measurements.fixed_memory_copy_ovhd, + &measurements.memory_copy_per_byte_ovhd) ); /* Print info here */ printf("FIXED ABORT OVHD:\n"); print_results(measurements.fixed_abort_ovhd); + printf("\n\nFIXED MEMORY COPY OVHD: \n"); + print_results(measurements.fixed_memory_copy_ovhd); + printf("\n\nMEMORY COPY PER BYTE OVHD: \n"); + print_results(measurements.memory_copy_per_byte_ovhd); + printf("End of test\n"); return 0; @@ -112,7 +139,9 @@ int main() // ----------------------------------------------------------------- -static int frsh_sharedobj_calibrate(measurements_t *measurements) +static int frsh_sharedobj_calibrate(individual_results_t *fixed_abort_ovhd, + individual_results_t *fixed_memory_copy_ovhd, + individual_results_t *memory_copy_per_byte_ovhd) { int terror = -1; @@ -124,7 +153,14 @@ static int frsh_sharedobj_calibrate(measurements_t *measurements) frsh_signal_t signal_received; frsh_signal_info_t signal_info_received; - + + fosa_clock_id_t cpu_clock; + struct timespec initial_time = {-1, -1}; + struct timespec final_time = {-1, -1}; + + char memory_region_source[NUMBER_OF_BYTES_TO_SIMULATE]; + char memory_region_destination[NUMBER_OF_BYTES_TO_SIMULATE]; + int i = 0; memset(&signal_set, 0, sizeof(signal_set) ); memset(&thread_data, 0, sizeof(thread_data) ); @@ -134,6 +170,7 @@ static int frsh_sharedobj_calibrate(measurements_t *measurements) memset(&signal_received, 0, sizeof(signal_received) ); memset(&signal_info_received, 0, sizeof(signal_info_received) ); + memset(&cpu_clock, 0, sizeof(cpu_clock) ); /* We set the signal mask and adjust our priority */ @@ -144,7 +181,7 @@ static int frsh_sharedobj_calibrate(measurements_t *measurements) /* We measure the fixed_abort_ovhd */ /***********************************/ - thread_data.results = &measurements->fixed_abort_ovhd; + thread_data.results = fixed_abort_ovhd; thread_data.parent_tid = pthread_self(); PRW( frsh_thread_attr_init(&calibrate_thread_attr) ); @@ -155,6 +192,45 @@ static int frsh_sharedobj_calibrate(measurements_t *measurements) printf("Main waits for the calibrate code to finish...\n"); PRW( fosa_signal_wait(signal_set, 1, &signal_received, &signal_info_received) ); + + /* We measure fixed_memory_copy_ovhd */ + /*************************************/ + PRW( fosa_thread_get_cputime_clock( fosa_thread_self(), &cpu_clock) ); + + + for(i = 0 ; i < NUMBER_OF_TESTS ; i++) + { + fosa_clock_get_time(FOSA_CLOCK_REALTIME, &initial_time); + memcpy(memory_region_destination, memory_region_source, 0); + fosa_clock_get_time(FOSA_CLOCK_REALTIME, &final_time); + + decr_timespec(&final_time, &initial_time); + + process_result(fixed_memory_copy_ovhd, final_time); + } + + fixed_memory_copy_ovhd->average_interval = + timespec_divide_by_int(fixed_memory_copy_ovhd->total_interval, + fixed_memory_copy_ovhd->number_of_tries - 1); + + /* We measure memory_copy_per_byte_ovhd */ + /****************************************/ + for(i = 0 ; i < NUMBER_OF_TESTS ; i++) + { + fosa_clock_get_time(cpu_clock, &initial_time); // Start measurement + memcpy(memory_region_destination, memory_region_source, NUMBER_OF_BYTES_TO_SIMULATE); + fosa_clock_get_time(cpu_clock, &final_time); // End measurement + + decr_timespec(&final_time, &initial_time); + final_time = timespec_divide_by_int(final_time, NUMBER_OF_BYTES_TO_SIMULATE / 1024); + + process_result(memory_copy_per_byte_ovhd, final_time); + } + + memory_copy_per_byte_ovhd->average_interval = + timespec_divide_by_int(memory_copy_per_byte_ovhd->total_interval, + memory_copy_per_byte_ovhd->number_of_tries - 1); + return 0; } @@ -180,8 +256,6 @@ static void *calibrate_thread_code(void *thread_arg) 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; @@ -196,8 +270,6 @@ static void *calibrate_thread_code(void *thread_arg) /* Periodic loop */ /*****************/ - first_time = true; - stats_initialised = false; // For the second time onwards protection_parameters.initialised = false; results->number_of_tries = 0; @@ -209,7 +281,6 @@ static void *calibrate_thread_code(void *thread_arg) struct timespec before_timestamp = {-1, -1 }; struct timespec after_timestamp = {-1, -1 }; - double interval_usec = 0.0; /* We initialise variables */ @@ -265,47 +336,15 @@ static void *calibrate_thread_code(void *thread_arg) 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; + decr_timespec(&after_timestamp, &minimum_budget_for_timer); - 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; + process_result(results, after_timestamp); - 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); - + results->average_interval = timespec_divide_by_int(results->total_interval, results->number_of_tries - 1); + PXW( fosa_signal_queue(SIGNAL_CALIBRATE_FINISHED, signal_info_to_send, thread_data->parent_tid) ); return NULL; @@ -323,15 +362,80 @@ static void work_under_a_interruptible_budget() // ------------------------------------------------------------------------------ +static void process_result(individual_results_t *results, struct timespec interval) +{ + results->number_of_tries++; + + if (results->first_time_passed == 0) + { + results->first_interval = interval; + results->first_time_passed = 1; + } + else if (results->second_time_passed == 0) + { + results->max_interval = interval; + results->iteration_max_interval = results->number_of_tries; + + results->min_interval = interval; + results->iteration_min_interval = results->number_of_tries; + + results->second_time_passed = 1; + + incr_timespec(&results->total_interval, &interval); + } + else + { + if (smaller_timespec(&results->max_interval, &interval) ) + { + results->max_interval = interval; + results->iteration_max_interval = results->number_of_tries; + } + + if (smaller_timespec(&interval, &results->min_interval) ) + { + results->min_interval = interval; + results->iteration_min_interval = results->number_of_tries; + } + + incr_timespec(&results->total_interval, &interval); + } +} + +// ------------------------------------------------------------------------------ + static void print_results(individual_results_t results) { - - printf("FIRST interval time: %6.3f usecs. All other stats apply to other invocations\n", - results.first_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); + assert(results.first_interval.tv_sec == 0); + assert(results.max_interval.tv_sec == 0); + assert(results.min_interval.tv_sec == 0); + assert(results.average_interval.tv_sec == 0); + + printf("FIRST interval time: %d ns. All other stats apply to other invocations\n", + results.first_interval.tv_nsec); + + printf("MAX interval time: %d ns at %d try, MIN interval time: %d ns at %d try\n", + results.max_interval.tv_nsec, results.iteration_max_interval, + results.min_interval.tv_nsec, results.iteration_min_interval); + + printf("AVERAGE interval time: %d ns, Number of tries %ld\n", + results.average_interval.tv_nsec, results.number_of_tries); +} + + +// ------------------------------------------------------------------------------ + +static struct timespec timespec_divide_by_int(struct timespec numerator, long int denominator) +{ + struct timespec result = {-1, -1}; + long int reminder = -1; + + assert(denominator < 1000000000); // For simplicity + + result.tv_sec = numerator.tv_sec/denominator; + + reminder = numerator.tv_sec % denominator; + + result.tv_nsec = (reminder * 1000000000 + numerator.tv_nsec)/denominator; + + return result; }