From 94694f9d29c7a4be5b7dd43243591ff7eb356e72 Mon Sep 17 00:00:00 2001 From: telleriam Date: Wed, 28 Nov 2007 19:19:41 +0000 Subject: [PATCH] Adding fosa_long_jump_calibrate 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 | 1 + .../fosa_long_jump_calibrate.c | 337 ++++++++++++++++++ 2 files changed, 338 insertions(+) create mode 100644 src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c diff --git a/src_marte/tests/test_non_local_jump/Makefile b/src_marte/tests/test_non_local_jump/Makefile index d2539bf..da7fd9d 100644 --- a/src_marte/tests/test_non_local_jump/Makefile +++ b/src_marte/tests/test_non_local_jump/Makefile @@ -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 index 0000000..c120370 --- /dev/null +++ b/src_marte/tests/test_non_local_jump/fosa_long_jump_calibrate.c @@ -0,0 +1,337 @@ +/* +** 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 "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); +} -- 2.39.2