#include <unistd.h>
#include <time.h> // For clock_nanosleep
-#include "frsh_error.h"
#include "fosa.h"
-#include "frsh_fosa.h"
-#include "timespec_operations.h"
+#include <misc/error_checks.h>
/*************************/
#define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 5)
#define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
-#define NUMBER_OF_JUMPS 5
+#define NUMBER_OF_JUMPS 100
typedef struct _results_t
{
double first_jump_interval_ms;
double average_jump_interval_ms;
double min_jump_interval_ms;
+ int iteration_min_jump_interval;
double max_jump_interval_ms;
+ int iteration_max_jump_interval;
double total_jump_interval_ms;
int number_of_jumps;
} results_t;
static fosa_long_jump_context_t context;
static void work_under_a_interruptible_budget();
-struct timespec before_jump_timestamp = {-1, -1};
+fosa_abs_time_t before_jump_timestamp;
int main()
{
- int terror = -1;
- frsh_thread_attr_t periodic_attr;
- frsh_signal_t signal_set[1];
- frsh_thread_id_t periodic_tid;
+ fosa_thread_attr_t periodic_attr;
+ fosa_signal_t signal_set[1];
+ fosa_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) );
+ CHK( 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) );
+ CHK( 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, &results) );
+ CHK( fosa_thread_attr_init(&periodic_attr) );
+ CHK( fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY) );
+ CHK( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, &results) );
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;
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("First Time: %6.3f ms\n Max Time: %6.3f ms Iteration %d Min Time: %6.3f ms Iteration %d\n",
+ results.first_jump_interval_ms, results.max_jump_interval_ms, results.iteration_max_jump_interval,
+ results.min_jump_interval_ms, results.iteration_min_jump_interval);
printf("Average_time: %6.3f ms Total jumps: %d\n", results.average_jump_interval_ms, results.number_of_jumps);
printf("End of test\n");
static void *periodic_code(void *thread_arg)
{
- int terror = -1;
+ fosa_thread_id_t jump_handler_thread;
- struct timespec period = {2, 500000000}; // 2.5 secs
- frsh_thread_id_t jump_handler_thread;
-
- frsh_signal_t jump_signal;
- frsh_signal_info_t jump_signal_info;
+ fosa_signal_t jump_signal;
+ fosa_signal_info_t jump_signal_info;
fosa_clock_id_t clock_id;
fosa_timer_id_t jump_timer;
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 */
/* FOSA_JUMP_SIGNAL */
/************************************************/
- PXW( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
+ CHK( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
/* We create a budget timer using the thread's CPU clock */
/* */
/* */
/* This signal is delivered to the handler thread. */
/*********************************************************/
- PXW( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
+ CHK( 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,
+ CHK( fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info,
&jump_timer, jump_handler_thread) );
results->number_of_jumps = 0;
while (results->number_of_jumps < NUMBER_OF_JUMPS)
{
int jumped = -1;
- struct timespec budget = {1, 400000000}; // 1.4 secs
+ fosa_rel_time_t budget = fosa_msec_to_rel_time(20); // 20 ms
- struct timespec old_activation_timestamp = {-1, -1};
- struct timespec activation_timestamp = {-1, -1};
- struct timespec after_jump_timestamp = {-1, -1 };
+ fosa_abs_time_t after_jump_timestamp;
+ fosa_rel_time_t jump_interval;
double jump_interval_ms = 0.0;
jumped = 0;
memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
- /* For statistical purposes we read the activation time */
- fosa_clock_get_time(FOSA_CLOCK_REALTIME, &old_activation_timestamp);
/* Start of the interruptible block */
/************************************/
/* We arm the jump_timer */
- fosa_timer_arm(jump_timer, false, &budget);
+ fosa_rel_timer_arm(jump_timer, &budget);
+
/* This is the point where the jump returns */
fosa_long_jump_save_context(&context);
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;
+ jump_interval = fosa_abs_time_extract_interval(before_jump_timestamp, after_jump_timestamp);
+ jump_interval_ms = fosa_rel_time_to_msec(jump_interval);
if (first_time)
{
results->first_jump_interval_ms = jump_interval_ms;
+
results->max_jump_interval_ms = jump_interval_ms;
+ results->iteration_max_jump_interval = results->number_of_jumps;
+
results->min_jump_interval_ms = jump_interval_ms;
+ results->iteration_min_jump_interval = results->number_of_jumps;
first_time = 0;
}
if (jump_interval_ms > results->max_jump_interval_ms)
{
results->max_jump_interval_ms = jump_interval_ms;
+ results->iteration_max_jump_interval = results->number_of_jumps;
}
if (jump_interval_ms < results->min_jump_interval_ms)
{
results->min_jump_interval_ms = jump_interval_ms;
+ results->iteration_min_jump_interval = results->number_of_jumps;
}
- printf("Jump Iteration: %d\n", results->number_of_jumps);
+ printf("Jump Iteration: %d\r", results->number_of_jumps);
}
-
/* End of interruptible work */
/*****************************/
- printf("After interruptible block\n");
-
- /* Now we measure the time duration of the block */
- /*************************************************/
- 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(&old_activation_timestamp, &period);
- clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_timestamp,
- &old_activation_timestamp);
}
static void work_under_a_interruptible_budget()
{
- struct timespec exec_time = {1, 0}; // 1 seg
-
- printf("Start regular work\n");
-
- frsh_eat(&exec_time);
-
/* This must be measured */
while(1)
{