]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte/tests/test_non_local_jump/test_fosa_long_jump.c
87ae84df48bab6f44a6218d1aa440018ae25fd10
[frescor/fosa.git] / src_marte / tests / test_non_local_jump / test_fosa_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 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <time.h> // For clock_nanosleep
15
16 #include "fosa.h"
17
18 #include <misc/error_checks.h>
19
20
21
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)
27
28
29 /*************************/
30 /*  P R O T O T Y P E S  */
31 /*************************/
32 static void *periodic_code(void *thread_arg);
33
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();
39
40
41 int main()
42 {
43     fosa_thread_attr_t periodic_attr;
44     fosa_signal_t signal_set[1];
45     fosa_thread_id_t periodic_tid;
46
47     memset(&context, 0, sizeof(context) );
48
49     memset(&periodic_attr, 0, sizeof(periodic_attr) );
50     memset(&signal_set, 0, sizeof(signal_set) );
51     memset(&periodic_tid, 0, sizeof(periodic_tid) );
52
53
54     /* We set the signal mask */
55     signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
56
57     CHK(  fosa_set_accepted_signals(signal_set, 1) );
58
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) );
63
64     printf("Main goes to sleep...\n");
65
66     sleep(2000);
67
68     return 0;
69 }
70
71 // ------------------------------------------------------------------------
72
73
74 static void *periodic_code(void *thread_arg)
75 {
76     fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
77
78     fosa_thread_id_t jump_handler_thread;
79
80     fosa_signal_t jump_signal;
81     fosa_signal_info_t jump_signal_info;
82
83     fosa_clock_id_t clock_id;
84     fosa_timer_id_t jump_timer;
85
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) );
91
92     
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) );
98     
99     /* We create a budget timer using the thread's CPU clock */
100     /*                                                       */
101     /* When the timer expires:                               */
102     /* -  Triggers the signal corresponding to signal jump   */
103     /* -  Provides a pointer to the context in siginfo.      */
104     /*                                                       */
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)  );
111
112     
113     /* Periodic loop */
114     /*****************/
115     while (1)
116     {
117         int jumped = -1;
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;
123
124         jumped = 0;
125
126         /* For statistical purposes we read the activation time */
127         CHK(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
128
129
130
131         /* Start of the interruptible block */
132         /************************************/
133
134         /* We arm the jump_timer */
135         CHK(  fosa_rel_timer_arm(jump_timer, &budget) );
136
137         /* This is the point where the jump returns */
138         CHK(  fosa_long_jump_save_context(&context) );
139
140         /* Query if we come from a jump */
141         CHK(  fosa_long_jump_was_performed(&context, &jumped) );
142         if (!jumped)
143         {
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");
148         }
149         else
150         {
151             printf("JUMPPPPPEEED\n");
152         }
153
154         
155         /* End of interruptible work */
156         /*****************************/
157
158         printf("After interruptible block\n");
159         
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) );
165     
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,
170                         NULL);
171     }
172         
173     return NULL;
174 }
175
176
177 // ------------------------------------------------------------------------------
178
179 static void work_under_a_interruptible_budget()
180 {
181     static int i = 0;
182     fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 sec
183
184     i++;
185     printf("Start regular work\n");
186
187     fosa_eat(&exec_time);
188
189     /* Once in every 5 executions we work over the budget */
190     if (i % 5 == 0)
191     {
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);
198     }
199
200     printf("End regular work\n");
201     
202 }