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 #include <time.h> // For clock_nanosleep
16 #include "frsh_error.h"
18 #include "frsh_fosa.h"
19 #include "timespec_operations.h"
21 /*************************/
22 /* D E F I N I T I O N S */
23 /*************************/
24 #define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 3)
25 #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 5)
28 /*************************/
29 /* P R O T O T Y P E S */
30 /*************************/
31 static void *periodic_code(void *thread_arg);
33 /**********************************/
34 /* S T A T I C V A R I A B L E S */
35 /**********************************/
36 static fosa_long_jump_context_t context;
37 static void work_under_a_interruptible_budget();
43 frsh_thread_attr_t periodic_attr;
44 frsh_signal_t signal_set[1];
45 frsh_thread_id_t periodic_tid;
47 memset(&context, 0, sizeof(context) );
49 memset(&periodic_attr, 0, sizeof(periodic_attr) );
50 memset(&signal_set, 0, sizeof(signal_set) );
51 memset(&periodic_tid, 0, sizeof(periodic_tid) );
54 /* We set the signal mask */
55 signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
56 PRW( fosa_set_accepted_signals(signal_set, 1) );
58 /* We create a new thread with a given priority */
59 PRW( frsh_thread_attr_init(&periodic_attr) );
60 PRW( fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY) );
61 PRW( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, NULL) );
63 printf("Main goes to sleep...\n");
70 // ------------------------------------------------------------------------
73 static void *periodic_code(void *thread_arg)
77 struct timespec period = {2, 500000000}; // 2.5 secs
78 frsh_thread_id_t jump_handler_thread;
80 frsh_signal_t jump_signal;
81 frsh_signal_info_t jump_signal_info;
83 fosa_clock_id_t clock_id;
84 fosa_timer_id_t jump_timer;
86 memset(&jump_signal, 0, sizeof(jump_signal) );
87 memset(&jump_signal_info, 0, sizeof(jump_signal_info) );
88 memset(&jump_handler_thread, 0, sizeof(jump_handler_thread) );
89 memset(&clock_id, 0, sizeof(clock_id) );
90 memset(&jump_timer, 0, sizeof(jump_timer) );
93 /* We install a long jump handler */
94 /* - This creates the thread that will wait for */
95 /* FOSA_JUMP_SIGNAL */
96 /************************************************/
97 PXW( fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
99 /* We create a budget timer using the thread's CPU clock */
101 /* When the timer expires: */
102 /* - Triggers the signal corresponding to signal jump */
103 /* - Provides a pointer to the context in siginfo. */
105 /* This signal is delivered to the handler thread. */
106 /*********************************************************/
107 PXW( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
108 jump_signal_info.sival_ptr = &context;
109 PXW( fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info,
110 &jump_timer, jump_handler_thread) );
118 struct timespec budget = {1, 400000000}; // 1.4 secs
119 struct timespec activation_time = {-1, -1};
120 struct timespec old_activation_time = {-1, -1};
126 /* For statistical purposes we read the activation time */
127 PXW( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
131 /* Start of the interruptible block */
132 /************************************/
134 /* We arm the jump_timer */
135 PXW( fosa_timer_arm(jump_timer, false, &budget) );
137 /* This is the point where the jump returns */
138 PXW( fosa_long_jump_save_context(&context) );
140 /* Query if we come from a jump */
141 PXW( fosa_long_jump_was_performed(&context, &jumped) );
144 /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
145 work_under_a_interruptible_budget();
146 printf("NOT JUMPPED\n");
150 printf("JUMPPPPPEEED\n");
154 /* End of interruptible work */
155 /*****************************/
157 printf("After interruptible block\n");
159 /* Now we measure the time duration of the block */
160 /*************************************************/
161 PXW( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &old_activation_time) );
162 decr_timespec(&old_activation_time, &activation_time);
163 printf("Execution time: %6.3f\n", t2d(old_activation_time) );
165 /* And we program the next loop */
166 incr_timespec(&activation_time, &period);
167 clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_time,
168 &old_activation_time);
175 // ------------------------------------------------------------------------------
177 static void work_under_a_interruptible_budget()
180 struct timespec exec_time = {1, 0}; // 1 seg
183 printf("Start regular work\n");
185 frsh_eat(&exec_time);
187 /* Once in every 5 executions we work over the budget */
190 frsh_eat(&exec_time);
191 frsh_eat(&exec_time);
192 frsh_eat(&exec_time);
193 frsh_eat(&exec_time);
194 frsh_eat(&exec_time);
195 frsh_eat(&exec_time);
198 printf("End regular work\n");