2 ** testbench_long_jump.c
4 ** Made by (Miguel marciano)
5 ** Login <miguel@namir.ctr.unican.es>
7 ** Started on Fri Nov 23 11:42:09 2007 Miguel marciano
8 ** Last update Sun May 12 01:17:25 2002 Speed Blue
14 - Define a pthread_join equivalent in FOSA (and also the detachable
16 - Define a clock_nanosleep equivalent in FOSA.
24 #include <time.h> // For clock_nanosleep
26 #include "frsh_error.h"
28 #include "frsh_fosa.h"
29 #include "timespec_operations.h"
33 /*************************/
34 /* D E F I N I T I O N S */
35 /*************************/
36 #define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 5)
37 #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
39 #define NUMBER_OF_JUMPS 100
41 typedef struct _results_t
43 double first_jump_interval_ms;
44 double average_jump_interval_ms;
45 double min_jump_interval_ms;
46 int iteration_min_jump_interval;
47 double max_jump_interval_ms;
48 int iteration_max_jump_interval;
49 double total_jump_interval_ms;
53 /*************************/
54 /* P R O T O T Y P E S */
55 /*************************/
56 static void *periodic_code(void *thread_arg);
58 /**********************************/
59 /* S T A T I C V A R I A B L E S */
60 /**********************************/
61 static fosa_long_jump_context_t context;
62 static void work_under_a_interruptible_budget();
64 struct timespec before_jump_timestamp = {-1, -1};
70 frsh_thread_attr_t periodic_attr;
71 frsh_signal_t signal_set[1];
72 frsh_thread_id_t periodic_tid;
75 memset(&context, 0, sizeof(context) );
77 memset(&periodic_attr, 0, sizeof(periodic_attr) );
78 memset(&signal_set, 0, sizeof(signal_set) );
79 memset(&periodic_tid, 0, sizeof(periodic_tid) );
80 memset(&results, 0, sizeof(results) );
82 /* We set the signal mask */
83 signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
84 PRW( fosa_set_accepted_signals(signal_set, 1) );
86 /* We create a new thread with a given priority */
87 PRW( fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY) );
89 PRW( frsh_thread_attr_init(&periodic_attr) );
90 PRW( fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY) );
91 PRW( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, &results) );
93 printf("Main waits for the periodic code to finish...\n");
94 pthread_join(periodic_tid, NULL);
96 results.average_jump_interval_ms = results.total_jump_interval_ms/results.number_of_jumps;
98 printf("------------ RESULTS -------------\n");
99 printf("First Time: %6.3f ms\n Max Time: %6.3f ms Iteration %d Min Time: %6.3f ms Iteration %d\n",
100 results.first_jump_interval_ms, results.max_jump_interval_ms, results.iteration_max_jump_interval,
101 results.min_jump_interval_ms, results.iteration_min_jump_interval);
102 printf("Average_time: %6.3f ms Total jumps: %d\n", results.average_jump_interval_ms, results.number_of_jumps);
104 printf("End of test\n");
108 // ------------------------------------------------------------------------
111 static void *periodic_code(void *thread_arg)
115 struct timespec period = {2, 500000000}; // 2.5 secs
116 frsh_thread_id_t jump_handler_thread;
118 frsh_signal_t jump_signal;
119 frsh_signal_info_t jump_signal_info;
121 fosa_clock_id_t clock_id;
122 fosa_timer_id_t jump_timer;
129 memset(&jump_signal, 0, sizeof(jump_signal) );
130 memset(&jump_signal_info, 0, sizeof(jump_signal_info) );
131 memset(&jump_handler_thread, 0, sizeof(jump_handler_thread) );
132 memset(&clock_id, 0, sizeof(clock_id) );
133 memset(&jump_timer, 0, sizeof(jump_timer) );
135 results = (results_t *) thread_arg;
137 /* We install a long jump handler */
138 /* - This creates the thread that will wait for */
139 /* FOSA_JUMP_SIGNAL */
140 /************************************************/
141 PXW( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
143 /* We create a budget timer using the thread's CPU clock */
145 /* When the timer expires: */
146 /* - Triggers the signal corresponding to signal jump */
147 /* - Provides a pointer to the context in siginfo. */
149 /* This signal is delivered to the handler thread. */
150 /*********************************************************/
151 PXW( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
152 jump_signal_info.sival_ptr = &context;
153 PXW( fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info,
154 &jump_timer, jump_handler_thread) );
156 results->number_of_jumps = 0;
160 while (results->number_of_jumps < NUMBER_OF_JUMPS)
163 struct timespec budget = {0, 20000000}; // 20 ms
165 struct timespec after_jump_timestamp = {-1, -1 };
166 double jump_interval_ms = 0.0;
170 /* We initialise variables */
172 memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
175 /* Start of the interruptible block */
176 /************************************/
178 /* We arm the jump_timer */
179 fosa_timer_arm(jump_timer, false, &budget);
182 /* This is the point where the jump returns */
183 fosa_long_jump_save_context(&context);
185 /* Query if we come from a jump */
186 fosa_long_jump_was_performed(&context, &jumped);
189 /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
190 work_under_a_interruptible_budget();
191 printf("We should not arrive here \n");
196 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_jump_timestamp);
198 results->number_of_jumps++;
199 decr_timespec(&after_jump_timestamp, &before_jump_timestamp);
200 jump_interval_ms = t2d(after_jump_timestamp) * 1000;
204 results->first_jump_interval_ms = jump_interval_ms;
206 results->max_jump_interval_ms = jump_interval_ms;
207 results->iteration_max_jump_interval = results->number_of_jumps;
209 results->min_jump_interval_ms = jump_interval_ms;
210 results->iteration_min_jump_interval = results->number_of_jumps;
214 results->total_jump_interval_ms += jump_interval_ms;
216 if (jump_interval_ms > results->max_jump_interval_ms)
218 results->max_jump_interval_ms = jump_interval_ms;
219 results->iteration_max_jump_interval = results->number_of_jumps;
222 if (jump_interval_ms < results->min_jump_interval_ms)
224 results->min_jump_interval_ms = jump_interval_ms;
225 results->iteration_min_jump_interval = results->number_of_jumps;
228 printf("Jump Iteration: %d\r", results->number_of_jumps);
231 /* End of interruptible work */
232 /*****************************/
241 // ------------------------------------------------------------------------------
243 static void work_under_a_interruptible_budget()
245 /* This must be measured */
248 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_jump_timestamp);