]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte/tests/test_non_local_jump/testbench_long_jump.c
ddae7ab83522782de375e7de5d47bfbe6c25e6ba
[frescor/fosa.git] / src_marte / tests / test_non_local_jump / testbench_long_jump.c
1 /*
2 ** testbench_long_jump.c
3 ** 
4 ** Made by (Miguel marciano)
5 ** Login   <miguel@namir.ctr.unican.es>
6 ** 
7 ** Started on  Fri Nov 23 11:42:09 2007 Miguel marciano
8 ** Last update Sun May 12 01:17:25 2002 Speed Blue
9 */
10
11 /*
12   TO DO:
13
14   -  Define a pthread_join equivalent in FOSA (and also the detachable
15      argument).
16   -  Define a clock_nanosleep equivalent in FOSA.
17
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <time.h> // For clock_nanosleep
25
26 #include "fosa.h"
27
28 #include <misc/error_checks.h>
29
30
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)
36
37 #define NUMBER_OF_JUMPS 100
38
39 typedef struct _results_t
40 {
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;
48     int  number_of_jumps;
49 } results_t;
50
51 /*************************/
52 /*  P R O T O T Y P E S  */
53 /*************************/
54 static void *periodic_code(void *thread_arg);
55
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();
61
62 fosa_abs_time_t before_jump_timestamp;
63
64
65 int main()
66 {
67     fosa_thread_attr_t periodic_attr;
68     fosa_signal_t signal_set[1];
69     fosa_thread_id_t periodic_tid;
70     results_t results;
71
72     memset(&context, 0, sizeof(context) );
73
74
75     /* We set the signal mask */
76     signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
77     CHK(  fosa_set_accepted_signals(signal_set, 1) );
78
79     /* We create a new thread with a given priority */
80     CHK(  fosa_thread_set_prio(fosa_thread_self(), MAIN_THREAD_PRIORITY) );
81
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) );
85
86     printf("Main waits for the periodic code to finish...\n");
87     pthread_join(periodic_tid, NULL);
88     
89     results.average_jump_interval_ms = results.total_jump_interval_ms/results.number_of_jumps;
90
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);
96
97     printf("End of test\n");
98     return 0;
99 }
100
101 // ------------------------------------------------------------------------
102
103
104 static void *periodic_code(void *thread_arg)
105 {
106     fosa_thread_id_t jump_handler_thread;
107
108     fosa_signal_t jump_signal;
109     fosa_signal_info_t jump_signal_info;
110
111     fosa_clock_id_t clock_id;
112     fosa_timer_id_t jump_timer;
113
114     /* testbench data */
115     results_t *results;
116     int first_time = 1;
117
118
119     results = (results_t *) thread_arg;
120     
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) );
126     
127     /* We create a budget timer using the thread's CPU clock */
128     /*                                                       */
129     /* When the timer expires:                               */
130     /* -  Triggers the signal corresponding to signal jump   */
131     /* -  Provides a pointer to the context in siginfo.      */
132     /*                                                       */
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)  );
139
140     results->number_of_jumps = 0;
141
142     /* Periodic loop */
143     /*****************/
144     while (results->number_of_jumps < NUMBER_OF_JUMPS)
145     {
146         int jumped = -1;
147         fosa_rel_time_t budget = fosa_msec_to_rel_time(20);  // 20 ms
148
149         fosa_abs_time_t after_jump_timestamp;
150         fosa_rel_time_t jump_interval;
151         double jump_interval_ms = 0.0;
152
153         
154
155         /* We initialise variables */
156         jumped = 0;
157         memset(&before_jump_timestamp, 0, sizeof(before_jump_timestamp) );
158
159
160         /* Start of the interruptible block */
161         /************************************/
162
163         /* We arm the jump_timer */
164         fosa_rel_timer_arm(jump_timer, &budget);
165
166         
167         /* This is the point where the jump returns */
168         fosa_long_jump_save_context(&context);
169
170         /* Query if we come from a jump */
171         fosa_long_jump_was_performed(&context, &jumped);
172         if (!jumped)
173         {
174             /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
175             work_under_a_interruptible_budget();
176             printf("We should not arrive here \n");
177             exit(1);
178         }
179         else
180         {
181             fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_jump_timestamp);
182
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);
186
187             if (first_time)
188             {
189                 results->first_jump_interval_ms = jump_interval_ms;
190
191                 results->max_jump_interval_ms = jump_interval_ms;
192                 results->iteration_max_jump_interval = results->number_of_jumps;
193
194                 results->min_jump_interval_ms = jump_interval_ms;
195                 results->iteration_min_jump_interval = results->number_of_jumps;
196
197                 first_time = 0;
198             }
199             results->total_jump_interval_ms += jump_interval_ms;
200
201             if (jump_interval_ms > results->max_jump_interval_ms)
202             {
203                 results->max_jump_interval_ms = jump_interval_ms;
204                 results->iteration_max_jump_interval = results->number_of_jumps;
205             }
206
207             if (jump_interval_ms < results->min_jump_interval_ms)
208             {
209                 results->min_jump_interval_ms = jump_interval_ms;
210                 results->iteration_min_jump_interval = results->number_of_jumps;
211             }
212        
213             printf("Jump Iteration: %d\r", results->number_of_jumps);
214         }
215
216         /* End of interruptible work */
217         /*****************************/
218     }
219
220     
221         
222     return NULL;
223 }
224
225
226 // ------------------------------------------------------------------------------
227
228 static void work_under_a_interruptible_budget()
229 {
230     /* This must be measured */
231     while(1)
232     {
233         fosa_clock_get_time(FOSA_CLOCK_REALTIME, &before_jump_timestamp);
234     }
235
236 }