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
18 #include <misc/error_checks.h>
22 /*************************/
23 /* D E F I N I T I O N S */
24 /*************************/
25 #define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 3)
26 #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 5)
29 /*************************/
30 /* P R O T O T Y P E S */
31 /*************************/
32 static void *periodic_code(void *thread_arg);
34 /**********************************/
35 /* S T A T I C V A R I A B L E S */
36 /**********************************/
37 static fosa_long_jump_context_t context;
38 static void work_under_a_interruptible_budget();
43 fosa_thread_attr_t periodic_attr;
44 fosa_signal_t signal_set[1];
45 fosa_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;
57 CHK( fosa_set_accepted_signals(signal_set, 1) );
59 /* We create a new thread with a given priority */
60 CHK( fosa_thread_attr_init(&periodic_attr) );
61 CHK( fosa_thread_attr_set_prio(&periodic_attr, PERIODIC_THREAD_PRIORITY) );
62 CHK( fosa_thread_create(&periodic_tid, &periodic_attr, periodic_code, NULL) );
64 printf("Main goes to sleep...\n");
71 // ------------------------------------------------------------------------
74 static void *periodic_code(void *thread_arg)
76 fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
78 fosa_thread_id_t jump_handler_thread;
80 fosa_signal_t jump_signal;
81 fosa_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 CHK( 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 CHK( fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
108 jump_signal_info.sival_ptr = &context;
109 CHK( fosa_timer_create_with_receiver(clock_id, jump_signal, jump_signal_info,
110 &jump_timer, jump_handler_thread) );
118 fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
119 fosa_abs_time_t activation_time;
120 struct timespec activation_time_tspec;
121 fosa_abs_time_t after_activation_time;
122 fosa_rel_time_t elapsed_time;
126 /* For statistical purposes we read the activation time */
127 CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
131 /* Start of the interruptible block */
132 /************************************/
134 /* We arm the jump_timer */
135 CHK( fosa_rel_timer_arm(jump_timer, &budget) );
137 /* This is the point where the jump returns */
138 CHK( fosa_long_jump_save_context(&context) );
140 /* Query if we come from a jump */
141 CHK( fosa_long_jump_was_performed(&context, &jumped) );
144 /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
145 work_under_a_interruptible_budget();
146 CHK( fosa_timer_disarm(jump_timer, NULL) );
147 printf("NOT JUMPPED\n");
151 printf("JUMPPPPPEEED\n");
155 /* End of interruptible work */
156 /*****************************/
158 printf("After interruptible block\n");
160 /* Now we measure the time duration of the block */
161 /*************************************************/
162 CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time) );
163 elapsed_time = fosa_abs_time_extract_interval(activation_time, after_activation_time);
164 printf("Execution time: %ld msec\n", fosa_rel_time_to_msec(after_activation_time) );
166 /* And we program the next loop */
167 activation_time = fosa_abs_time_incr(activation_time, period);
168 activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
169 clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, &activation_time_tspec,
177 // ------------------------------------------------------------------------------
179 static void work_under_a_interruptible_budget()
182 fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 sec
185 printf("Start regular work\n");
187 fosa_eat(&exec_time);
189 /* Once in every 5 executions we work over the budget */
192 fosa_eat(&exec_time);
193 fosa_eat(&exec_time);
194 fosa_eat(&exec_time);
195 fosa_eat(&exec_time);
196 fosa_eat(&exec_time);
197 fosa_eat(&exec_time);
200 printf("End regular work\n");