From: telleriam Date: Mon, 26 Nov 2007 12:38:20 +0000 (+0000) Subject: First running version of FOSA long_jump testbench X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/fosa.git/commitdiff_plain/16822939869987177101c991580d333ed230f06a First running version of FOSA long_jump testbench git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@890 35b4ef3e-fd22-0410-ab77-dab3279adceb --- diff --git a/src_marte/tests/test_non_local_jump/Makefile b/src_marte/tests/test_non_local_jump/Makefile index a6c1153..f450c2f 100644 --- a/src_marte/tests/test_non_local_jump/Makefile +++ b/src_marte/tests/test_non_local_jump/Makefile @@ -7,5 +7,9 @@ CFLAGS += -I$(FRSH_PATH)/src_ads # Quick hack for frsh_error frsh_error.o: frsh_error.c +testbench_long_jump.exe: testbench_long_jump.c frsh_error.o + +test_fosa_long_jump.exe: test_fosa_long_jump.c frsh_error.o + diff --git a/src_marte/tests/test_non_local_jump/test_fosa_long_jump.c b/src_marte/tests/test_non_local_jump/test_fosa_long_jump.c index 59552ec..3fb9e67 100644 --- a/src_marte/tests/test_non_local_jump/test_fosa_long_jump.c +++ b/src_marte/tests/test_non_local_jump/test_fosa_long_jump.c @@ -1,267 +1,200 @@ -//---------------------------------------------------------------------- -// Copyright (C) 2006 - 2007 by the FRESCOR consortium: -// -// Universidad de Cantabria, SPAIN -// University of York, UK -// Scuola Superiore Sant'Anna, ITALY -// Kaiserslautern University, GERMANY -// Univ. Politecnica Valencia, SPAIN -// Czech Technical University in Prague, CZECH REPUBLIC -// ENEA SWEDEN -// Thales Communication S.A. FRANCE -// Visual Tools S.A. SPAIN -// Rapita Systems Ltd UK -// Evidence ITALY -// -// See http://www.frescor.org -// -// The FRESCOR project (FP6/2005/IST/5-034026) is funded -// in part by the European Union Sixth Framework Programme -// The European Union is not liable of any use that may be -// made of this code. -// -// -// based on previous work (FSF) done in the FIRST project -// -// Copyright (C) 2005 Mälardalen University, SWEDEN -// Scuola Superiore S.Anna, ITALY -// Universidad de Cantabria, SPAIN -// University of York, UK -// -// This file is part of FRSH (FRescor ScHeduler) -// -// FRSH is free software; you can redistribute it and/or modify it -// under terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2, or (at your option) any -// later version. FRSH is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. You should have received a -// copy of the GNU General Public License along with FRSH; see file -// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, -// Cambridge, MA 02139, USA. -// -// As a special exception, including FRSH header files in a file, -// instantiating FRSH generics or templates, or linking other files -// with FRSH objects to produce an executable application, does not -// by itself cause the resulting executable application to be covered -// by the GNU General Public License. This exception does not -// however invalidate any other reasons why the executable file might be -// covered by the GNU Public License. -// ----------------------------------------------------------------------- +/* +** 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 +*/ #include +#include #include #include -#include - -//#include -//#include -//#include -//#include -//#include -//#include +#include // For clock_nanosleep +#include "frsh_error.h" +#include "fosa.h" #include "frsh_fosa.h" -#include "fosa_threads_and_signals.h" -#include "fosa_clocks_and_timers.h" -#include "fosa_configuration_parameters.h" - #include "timespec_operations.h" -#include "fosa_long_jump.h" - -/************************/ -/** Constants and types */ -/************************/ +/*************************/ +/* 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 RT_ERROR_SIGWAIT -2 -#define RT_ERROR_TIMER -3 -#define RT_ERROR_HANDLER -4 +/*************************/ +/* P R O T O T Y P E S */ +/*************************/ +static void *periodic_code(void *thread_arg); -/************************/ -/** Global Variables */ -/************************/ - +/**********************************/ +/* S T A T I C V A R I A B L E S */ +/**********************************/ static fosa_long_jump_context_t context; -static int error_status = 0; - - -/************************/ -/** Prototypes */ -/************************/ +static void work_under_a_interruptible_budget(); -static void * thread_body(void *arg); -static void work(); - - -/************************************************************************/ -/* Main program */ -/************************************************************************/ int main() { - //frsh_signal_t set[1]; - frsh_thread_attr_t attr; - - frsh_thread_id_t tid_periodic_thread; - int terror = 0; + int terror = -1; + frsh_thread_attr_t periodic_attr; frsh_signal_t signal_set[1]; + frsh_thread_id_t periodic_tid; - - memset(&attr, 0, sizeof(attr) ); - memset(&tid_periodic_thread, 0, sizeof(tid_periodic_thread) ); 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) ); - /* Create the thread attributes object and assign the new thread a - priority lower than the main */ - if (frsh_thread_attr_init (&attr) != 0) { - printf("Error while initializing the attributes\n"); - exit(1); - } - - // set priority of periodic thread - if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) { - printf("Error while setting schedparam\n"); - exit(1); - } - /* We set the priority of this main thread to a lever higher */ - /* than the future periodic thread. */ - /*************************************************************/ - if (fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + 4) ) - { - printf("Error while changing main's priority\n"); - exit(1); - } + /* We set the signal mask */ + signal_set[0] = FOSA_LONG_JUMP_SIGNAL; + PRW( fosa_set_accepted_signals(signal_set, 1) ); - /* create the periodic thread */ - /******************************/ - terror = fosa_thread_create(&tid_periodic_thread, &attr, thread_body, NULL); - if (terror) { - printf("pthread_create periodic thread\n"); - exit(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) ); printf("Main goes to sleep...\n"); - sleep(20000); + + sleep(2000); return 0; } +// ------------------------------------------------------------------------ +static void *periodic_code(void *thread_arg) +{ + int terror = -1; -/* ------------------------------------------------------------ */ -/** Body of periodic thread that consumes budget */ + struct timespec period = {2, 500000000}; // 2.5 secs + frsh_thread_id_t jump_handler_thread; -static void * thread_body(void *thread_arg) -{ - struct timespec period={2,500000000}; // 2.5 seconds - struct timespec activation_time, old_activation_time; - struct timespec budget ={1,400000000}; // 1.4 seconds - fosa_timer_id_t timerid; - fosa_clock_id_t clockid; - frsh_signal_info_t siginfo; - frsh_signal_t signal; - frsh_thread_id_t handler; - int jumped; - int err; - - - fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time); - - if (fosa_thread_get_cputime_clock(pthread_self(),&clockid) !=0) { - error_status=RT_ERROR_TIMER; - pthread_exit ( (void*)&error_status); - } + frsh_signal_t jump_signal; + frsh_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) ); - // install long jump handler - if (fosa_long_jump_install_handler(&signal,&handler)!=0) - { - error_status=RT_ERROR_HANDLER; - pthread_exit ( (void*)&error_status); - } - - // create budget timer - siginfo.sival_ptr=(void *)(&context); - if (fosa_timer_create_with_receiver - (clockid,signal,siginfo,&timerid,handler) != 0) + + /* 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) ); + + /* We create a budget timer using the thread's CPU clock */ + /* */ + /* When the timer expires: */ + /* - Triggers the signal corresponding to signal jump */ + /* - Provides a pointer to the context in siginfo. */ + /* */ + /* This signal is delivered to the handler thread. */ + /*********************************************************/ + PXW( 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, + &jump_timer, jump_handler_thread) ); + + + /* Periodic loop */ + /*****************/ + while (1) { - error_status=RT_ERROR_TIMER; - pthread_exit ( (void*)&error_status); - } + int jumped = -1; + struct timespec budget = {1, 400000000}; // 1.4 secs + struct timespec activation_time = {-1, -1}; + struct timespec old_activation_time = {-1, -1}; + - printf("Start periodic thread body\n"); - - // main loop - while(1) { jumped = 0; - - // set the budget timer - if (fosa_timer_arm(timerid, false, &budget) != 0) { - error_status=RT_ERROR_TIMER; - pthread_exit ( (void*)&error_status); + + /* For statistical purposes we read the activation time */ + PXW( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) ); + + + + /* Start of the interruptible block */ + /************************************/ + + /* We arm the jump_timer */ + PXW( fosa_timer_arm(jump_timer, false, &budget) ); + + /* This is the point where the jump returns */ + PXW( fosa_long_jump_save_context(&context) ); + + /* Query if we come from a jump */ + PXW( 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("Begin thread main loop at %d,%d\n",(int)activation_time.tv_sec, - (int)(activation_time.tv_nsec/1000000)); - - // save context - - err=fosa_long_jump_save_context(&context); - if (err!=0) { - error_status=RT_ERROR_HANDLER; - pthread_exit ( (void*)&error_status); + else + { + printf("JUMPPPPPEEED\n"); } - err=fosa_long_jump_was_performed(&context,&jumped); - if (err!=0) { - error_status=RT_ERROR_HANDLER; - pthread_exit ( (void*)&error_status); - } - if (!jumped) { - work(); - } else { - // code executed if asynchronous jump instruction invoked */ - printf("Aborted thread\n"); - } - - printf("after abortable block\n"); - fosa_clock_get_time(FOSA_CLOCK_REALTIME,&old_activation_time); - decr_timespec(&old_activation_time,&activation_time); - printf("End thread %6.3f\n",old_activation_time.tv_sec+(float) - (float)old_activation_time.tv_nsec/1000000000.0); - // sleep for a while - incr_timespec(&activation_time,&period); - clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME, - &activation_time,&old_activation_time); - } // while + + /* 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; } +// ------------------------------------------------------------------------------ -// --------------------------------------------------------------------- - -// work to be aborted if too long -static void work() +static void work_under_a_interruptible_budget() { - static int i=0; - struct timespec exec_time={1,0}; // 1 second + static int i = 0; + struct timespec exec_time = {1, 0}; // 1 seg i++; - printf("start regular code %d\n",i); - // regular code - // eat one second of budget - frsh_eat(&exec_time); - // every five cycles eat an additional one second of budget */ - if (i%5==0) { - frsh_eat(&exec_time); - frsh_eat(&exec_time); - frsh_eat(&exec_time); - frsh_eat(&exec_time); - frsh_eat(&exec_time); - } + printf("Start regular work\n"); + + frsh_eat(&exec_time); + + /* Once in every 5 executions we work over the budget */ + if (i % 5 == 0) + { + frsh_eat(&exec_time); + frsh_eat(&exec_time); + frsh_eat(&exec_time); + frsh_eat(&exec_time); + frsh_eat(&exec_time); + frsh_eat(&exec_time); + } + + printf("End regular work\n"); + } diff --git a/src_marte/tests/test_non_local_jump/testbench_long_jump.c b/src_marte/tests/test_non_local_jump/testbench_long_jump.c index 3fb9e67..8b8199a 100644 --- a/src_marte/tests/test_non_local_jump/testbench_long_jump.c +++ b/src_marte/tests/test_non_local_jump/testbench_long_jump.c @@ -7,6 +7,16 @@ ** 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 #include #include @@ -18,12 +28,25 @@ #include "frsh_fosa.h" #include "timespec_operations.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 5 +typedef struct _results_t +{ + double first_jump_interval_ms; + double average_jump_interval_ms; + double min_jump_interval_ms; + double max_jump_interval_ms; + double total_jump_interval_ms; + int number_of_jumps; +} results_t; /*************************/ /* P R O T O T Y P E S */ @@ -36,6 +59,8 @@ static void *periodic_code(void *thread_arg); static fosa_long_jump_context_t context; static void work_under_a_interruptible_budget(); +struct timespec before_jump_timestamp = {-1, -1}; + int main() { @@ -43,27 +68,37 @@ int main() frsh_thread_attr_t periodic_attr; frsh_signal_t signal_set[1]; frsh_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) ); - + memset(&results, 0, sizeof(results) ); /* We set the signal mask */ signal_set[0] = FOSA_LONG_JUMP_SIGNAL; PRW( fosa_set_accepted_signals(signal_set, 1) ); /* We create a new thread with a given priority */ + PRW( fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_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) ); + PRW( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, &results) ); - printf("Main goes to sleep...\n"); + 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; - sleep(2000); + printf("------------ RESULTS -------------\n"); + printf("First Time: %6.3f ms Max Time: %6.3f ms Min Time: %6.3f ms\n", + results.first_jump_interval_ms, results.max_jump_interval_ms, results.min_jump_interval_ms); + 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; } @@ -83,12 +118,18 @@ static void *periodic_code(void *thread_arg) fosa_clock_id_t clock_id; fosa_timer_id_t jump_timer; + /* testbench data */ + results_t *results; + int first_time = 1; + + 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) ); + results = (results_t *) thread_arg; /* We install a long jump handler */ /* - This creates the thread that will wait for */ @@ -109,64 +150,96 @@ static void *periodic_code(void *thread_arg) PXW( 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}; + struct timespec old_activation_timestamp = {-1, -1}; + struct timespec activation_timestamp = {-1, -1}; + struct timespec after_jump_timestamp = {-1, -1 }; + double jump_interval_ms = 0.0; + + /* We initialise variables */ jumped = 0; + memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) ); /* For statistical purposes we read the activation time */ - PXW( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) ); - - + fosa_clock_get_time(FOSA_CLOCK_REALTIME, &old_activation_timestamp); /* Start of the interruptible block */ /************************************/ /* We arm the jump_timer */ - PXW( fosa_timer_arm(jump_timer, false, &budget) ); + fosa_timer_arm(jump_timer, false, &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++; + decr_timespec(&after_jump_timestamp, &before_jump_timestamp); + jump_interval_ms = t2d(after_jump_timestamp) * 1000; + + if (first_time) + { + results->first_jump_interval_ms = jump_interval_ms; + results->max_jump_interval_ms = jump_interval_ms; + results->min_jump_interval_ms = jump_interval_ms; + + 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; + } + + if (jump_interval_ms < results->min_jump_interval_ms) + { + results->min_jump_interval_ms = jump_interval_ms; + } + + printf("Jump Iteration: %d\n", 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) ); + fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_timestamp); + decr_timespec(&activation_timestamp, &old_activation_timestamp); + printf("Execution time: %6.3f\n", t2d(activation_timestamp) ); /* And we program the next loop */ - incr_timespec(&activation_time, &period); - clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_time, - &old_activation_time); + incr_timespec(&old_activation_timestamp, &period); + clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_timestamp, + &old_activation_timestamp); } + + return NULL; } @@ -176,25 +249,16 @@ 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"); - }