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
28 #include <misc/error_checks.h>
31 /*************************/
32 /* D E F I N I T I O N S */
33 /*************************/
34 #define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 5)
35 #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 3)
37 #define NUMBER_OF_JUMPS 100
39 typedef struct _results_t
41 double first_jump_interval_ms;
42 double average_jump_interval_ms;
43 double min_jump_interval_ms;
44 int iteration_min_jump_interval;
45 double max_jump_interval_ms;
46 int iteration_max_jump_interval;
47 double total_jump_interval_ms;
51 /*************************/
52 /* P R O T O T Y P E S */
53 /*************************/
54 static void *periodic_code(void *thread_arg);
56 /**********************************/
57 /* S T A T I C V A R I A B L E S */
58 /**********************************/
59 static fosa_long_jump_context_t context;
60 static void work_under_a_interruptible_budget();
62 fosa_abs_time_t before_jump_timestamp;
67 fosa_thread_attr_t periodic_attr;
68 fosa_signal_t signal_set[1];
69 fosa_thread_id_t periodic_tid;
72 memset(&context, 0, sizeof(context) );
75 /* We set the signal mask */
76 signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
77 CHK( fosa_set_accepted_signals(signal_set, 1) );
79 /* We create a new thread with a given priority */
80 CHK( fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY) );
82 CHK( fosa_thread_attr_init(&periodic_attr) );
83 CHK( fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY) );
84 CHK( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, &results) );
86 printf("Main waits for the periodic code to finish...\n");
87 pthread_join(periodic_tid, NULL);
89 results.average_jump_interval_ms = results.total_jump_interval_ms/results.number_of_jumps;
91 printf("------------ RESULTS -------------\n");
92 printf("First Time: %6.3f ms\n Max Time: %6.3f ms Iteration %d Min Time: %6.3f ms Iteration %d\n",
93 results.first_jump_interval_ms, results.max_jump_interval_ms, results.iteration_max_jump_interval,
94 results.min_jump_interval_ms, results.iteration_min_jump_interval);
95 printf("Average_time: %6.3f ms Total jumps: %d\n", results.average_jump_interval_ms, results.number_of_jumps);
97 printf("End of test\n");
101 // ------------------------------------------------------------------------
104 static void *periodic_code(void *thread_arg)
106 fosa_thread_id_t jump_handler_thread;
108 fosa_signal_t jump_signal;
109 fosa_signal_info_t jump_signal_info;
111 fosa_clock_id_t clock_id;
112 fosa_timer_id_t jump_timer;
119 results = (results_t *) thread_arg;
121 /* We install a long jump handler */
122 /* - This creates the thread that will wait for */
123 /* FOSA_JUMP_SIGNAL */
124 /************************************************/
125 CHK( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
127 /* We create a budget timer using the thread's CPU clock */
129 /* When the timer expires: */
130 /* - Triggers the signal corresponding to signal jump */
131 /* - Provides a pointer to the context in siginfo. */
133 /* This signal is delivered to the handler thread. */
134 /*********************************************************/
135 CHK( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
136 jump_signal_info.sival_ptr = &context;
137 CHK( fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info,
138 &jump_timer, jump_handler_thread) );
140 results->number_of_jumps = 0;
144 while (results->number_of_jumps < NUMBER_OF_JUMPS)
147 fosa_rel_time_t budget = fosa_msec_to_rel_time(20); // 20 ms
149 fosa_abs_time_t after_jump_timestamp;
150 fosa_rel_time_t jump_interval;
151 double jump_interval_ms = 0.0;
155 /* We initialise variables */
157 memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
160 /* Start of the interruptible block */
161 /************************************/
163 /* We arm the jump_timer */
164 fosa_rel_timer_arm(jump_timer, &budget);
167 /* This is the point where the jump returns */
168 fosa_long_jump_save_context(&context);
170 /* Query if we come from a jump */
171 fosa_long_jump_was_performed(&context, &jumped);
174 /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
175 work_under_a_interruptible_budget();
176 printf("We should not arrive here \n");
181 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_jump_timestamp);
183 results->number_of_jumps++;
184 jump_interval = fosa_abs_time_extract_interval(before_jump_timestamp, after_jump_timestamp);
185 jump_interval_ms = fosa_rel_time_to_msec(jump_interval);
189 results->first_jump_interval_ms = jump_interval_ms;
191 results->max_jump_interval_ms = jump_interval_ms;
192 results->iteration_max_jump_interval = results->number_of_jumps;
194 results->min_jump_interval_ms = jump_interval_ms;
195 results->iteration_min_jump_interval = results->number_of_jumps;
199 results->total_jump_interval_ms += jump_interval_ms;
201 if (jump_interval_ms > results->max_jump_interval_ms)
203 results->max_jump_interval_ms = jump_interval_ms;
204 results->iteration_max_jump_interval = results->number_of_jumps;
207 if (jump_interval_ms < results->min_jump_interval_ms)
209 results->min_jump_interval_ms = jump_interval_ms;
210 results->iteration_min_jump_interval = results->number_of_jumps;
213 printf("Jump Iteration: %d\r", results->number_of_jumps);
216 /* End of interruptible work */
217 /*****************************/
226 // ------------------------------------------------------------------------------
228 static void work_under_a_interruptible_budget()
230 /* This must be measured */
233 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_jump_timestamp);