From: telleriam Date: Mon, 3 Dec 2007 08:01:31 +0000 (+0000) Subject: Transfering long_jump_calibrate.c from FOSA to FRSH X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/fosa.git/commitdiff_plain/a3fc45dd837468d08ad255ed67177cddcc98195f Transfering long_jump_calibrate.c from FOSA to FRSH git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@918 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 deleted file mode 100644 index bd900a8..0000000 --- a/src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c +++ /dev/null @@ -1,451 +0,0 @@ -/* -** testbench_long_jump.c -** -** Made by (Miguel marciano) -** Login -** -** 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 -#include -#include -#include -#include // For clock_nanosleep -#include - -#include - -#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 1000 - -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 MUTEX_CEILING (fosa_get_priority_min() + 10) - -#define MINIMUM_BUDGET_FOR_TIMER_USECS 100 - -#define SIGNAL_CALIBRATE_FINISHED (FRSH_SIGNAL_MIN + 6) - - -typedef struct _individual_results_t -{ - 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 */ - struct timespec average_interval; - struct timespec min_interval; - int iteration_min_interval; - struct timespec max_interval; - int iteration_max_interval; - struct timespec total_interval; - long 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(individual_results_t *fixed_abort_ovhd, - individual_results_t *fixed_memory_copy_ovhd, - individual_results_t *memory_copy_per_byte_ovhd); - -static void *fixed_abort_ovhd_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() -{ - int terror = -1; - measurements_t measurements; - - memset(&measurements, 0, sizeof(measurements) ); - - /* We set the signal mask */ - - 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; -} - -// ----------------------------------------------------------------- - -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; - - 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; - - 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) ); - - 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) ); - memset(&cpu_clock, 0, sizeof(cpu_clock) ); - - - /* 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 get our CPU clock */ - PRW( fosa_thread_get_cputime_clock( fosa_thread_self(), &cpu_clock) ); - - /* We measure the fixed_abort_ovhd */ - /***********************************/ - thread_data.results = 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, fixed_abort_ovhd_thread_code, - &thread_data ) ); - - /* We wait for the signal to arrive */ - PRW( fosa_signal_wait(signal_set, 1, &signal_received, &signal_info_received) ); - - - /* We measure fixed_memory_copy_ovhd */ - /*************************************/ - for(i = 0 ; i < NUMBER_OF_TESTS ; i++) - { - fosa_clock_get_time(FOSA_CLOCK_REALTIME, &initial_time); // Start measurement - memcpy(memory_region_destination, memory_region_source, 0); - fosa_clock_get_time(FOSA_CLOCK_REALTIME, &final_time); // End measurement - - 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; -} - - -// ------------------------------------------------------------------------ - -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 *fixed_abort_ovhd_thread_code(void *thread_arg) -{ - int terror = -1; - - thread_data_t *thread_data = NULL; - individual_results_t *results = NULL; - - protection_parameters_t protection_parameters; - - frsh_signal_info_t signal_info_to_send; - frsh_mutex_t mutex; - - memset(&protection_parameters, 0, sizeof(protection_parameters) ); - memset(&signal_info_to_send, 0, sizeof(signal_info_to_send) ); - memset(&mutex, 0, sizeof(mutex) ); - - thread_data = (thread_data_t *) thread_arg; - results = thread_data->results; - - PXW( fosa_mutex_init(&mutex, MUTEX_CEILING) ); - - - /* Periodic loop */ - /*****************/ - 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 }; - - - /* 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; - } - - PXW( fosa_mutex_lock(&mutex) ); - - /* We arm the jump_timer */ - PXW( 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(); - PXW( fosa_timer_disarm(protection_parameters.jump_timer, NULL) ); - PXW( fosa_mutex_unlock(&mutex) ); - PERROR_AND_EXIT(FRSH_ERR_INTERNAL_ERROR, "The jump should always prevent us from arriving here\n"); - } - - PXW( fosa_mutex_unlock(&mutex) ); - - - /* 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); - - decr_timespec(&after_timestamp, &before_timestamp); - - decr_timespec(&after_timestamp, &minimum_budget_for_timer); - - process_result(results, after_timestamp); - - } - - 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; -} - - -// ------------------------------------------------------------------------------ - -static void work_under_a_interruptible_budget() -{ - struct timespec upper_execution_limit = {1, 0}; - - frsh_eat(&upper_execution_limit); -} - -// ------------------------------------------------------------------------------ - -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) -{ - 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; -}