]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte_os/tests/test_non_local_jump/test_fosa_long_jump.c
Added a header that is printed at the start of the test
[frescor/fosa.git] / src_marte_os / tests / test_non_local_jump / test_fosa_long_jump.c
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politécnica  Valencia,           SPAIN
9 //    Czech Technical University in Prague,  CZECH REPUBLIC
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
18 //           FRESCOR project (FP6/2005/IST/5-034026) is funded
19 //        in part by the European Union Sixth Framework Programme
20 //        The European Union is not liable of any use that may be
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //   This file is part of FOSA (Frsh Operating System Adaption)
35 //
36 //  FOSA is free software; you can redistribute it and/or modify it
37 //  under terms of the GNU General Public License as published by the
38 //  Free Software Foundation; either version 2, or (at your option) any
39 //  later version.  FOSA is distributed in the hope that it will be
40 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 //  General Public License for more details. You should have received a
43 //  copy of the GNU General Public License along with FOSA; see file
44 //  COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 //  Cambridge, MA 02139, USA.
46 //
47 //  As a special exception, including FOSA header files in a file,
48 //  instantiating FOSA generics or templates, or linking other files
49 //  with FOSA objects to produce an executable application, does not
50 //  by itself cause the resulting executable application to be covered
51 //  by the GNU General Public License. This exception does not
52 //  however invalidate any other reasons why the executable file might be
53 //  covered by the GNU Public License.
54 // -----------------------------------------------------------------------
55
56 #include <stdio.h>
57 #include <string.h>
58 #include <stdlib.h>
59 #include <unistd.h>
60 #include <time.h> // For clock_nanosleep
61
62 #include "fosa.h"
63
64 #include <misc/error_checks.h>
65
66
67
68 /*************************/
69 /* D E F I N I T I O N S */
70 /*************************/
71 #define PERIODIC_THREAD_PRIORITY (fosa_get_priority_min() + 3)
72 #define MAIN_THREAD_PRIORITY (fosa_get_priority_min() + 5)
73
74
75 /*************************/
76 /*  P R O T O T Y P E S  */
77 /*************************/
78 static void *periodic_code(void *thread_arg);
79
80 /**********************************/
81 /* S T A T I C  V A R I A B L E S */
82 /**********************************/
83 static fosa_long_jump_context_t context;
84 static void work_under_an_interruptible_budget();
85
86
87 int main()
88 {
89     fosa_thread_attr_t periodic_attr;
90     fosa_signal_t signal_set[1];
91     fosa_thread_id_t periodic_tid;
92
93     // Print test header
94     printf("\n");
95     printf("This test checks the ability to make long jumps in FOSA\n");
96     printf("A periodic workload consumes 1ms or 7ms (every 5 iterations)\n");
97     printf("The budget is set to 1.4ms; when exceeded, the operation is aborted\n");
98     printf("\n");
99
100     memset(&context, 0, sizeof(context) );
101
102     memset(&periodic_attr, 0, sizeof(periodic_attr) );
103     memset(&signal_set, 0, sizeof(signal_set) );
104     memset(&periodic_tid, 0, sizeof(periodic_tid) );
105
106
107     /* We set the signal mask */
108     signal_set[0] = FOSA_LONG_JUMP_SIGNAL;
109
110     CHK(  fosa_set_accepted_signals(signal_set, 1) );
111
112     /* We create a new thread with a given priority */
113     CHK(  fosa_thread_attr_init(&periodic_attr) );
114     CHK(  fosa_thread_attr_set_prio
115           (&periodic_attr, PERIODIC_THREAD_PRIORITY)  );
116     CHK(  fosa_thread_create
117           (&periodic_tid, &periodic_attr, periodic_code, NULL) );
118
119     printf("Main goes to sleep...\n");
120
121     sleep(2000);
122
123     return 0;
124 }
125
126 // ------------------------------------------------------------------------
127
128
129 static void *periodic_code(void *thread_arg)
130 {
131     fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
132
133     fosa_thread_id_t jump_handler_thread;
134
135     fosa_signal_t jump_signal;
136     fosa_signal_info_t jump_signal_info;
137
138     fosa_clock_id_t clock_id;
139     fosa_timer_id_t jump_timer;
140
141     memset(&jump_signal, 0, sizeof(jump_signal) );
142     memset(&jump_signal_info, 0, sizeof(jump_signal_info) );
143     memset(&jump_handler_thread, 0, sizeof(jump_handler_thread) );
144     memset(&clock_id, 0, sizeof(clock_id) );
145     memset(&jump_timer, 0, sizeof(jump_timer) );
146
147
148     /* We install a long jump handler               */
149     /* - This creates the thread that will wait for */
150     /*   FOSA_JUMP_SIGNAL                           */
151     /************************************************/
152     CHK(  fosa_long_jump_install_handler(&jump_signal, &jump_handler_thread) );
153
154     /* We create a budget timer using the thread's CPU clock */
155     /*                                                       */
156     /* When the timer expires:                               */
157     /* -  Triggers the signal corresponding to signal jump   */
158     /* -  Provides a pointer to the context in siginfo.      */
159     /*                                                       */
160     /* This signal is delivered to the handler thread.       */
161     /*********************************************************/
162     CHK(  fosa_thread_get_cputime_clock( fosa_thread_self(), &clock_id) );
163     jump_signal_info.sival_ptr = &context;
164     CHK(  fosa_timer_create_with_receiver
165           (clock_id, jump_signal, jump_signal_info,
166            &jump_timer, jump_handler_thread)  );
167
168
169     printf("Start periodic work with budget=1400ms\n");
170
171     /* Periodic loop */
172     /*****************/
173     while (1)
174     {
175         int jumped = -1;
176         fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
177         fosa_abs_time_t activation_time;
178         struct timespec activation_time_tspec;
179         fosa_abs_time_t after_activation_time;
180         fosa_rel_time_t elapsed_time;
181
182         jumped = 0;
183
184         /* For statistical purposes we read the activation time */
185         CHK(  fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time) );
186
187
188
189         /* Start of the interruptible block */
190         /************************************/
191
192         /* We arm the jump_timer */
193         CHK(  fosa_rel_timer_arm(jump_timer, &budget) );
194
195         /* This is the point where the jump returns */
196         CHK(  fosa_long_jump_save_context(&context) );
197
198         /* Query if we come from a jump */
199         CHK(  fosa_long_jump_was_performed(&context, &jumped) );
200         if (!jumped)
201         {
202             /* HERE COMES THE WORK THAT CAN BE INTERRUPTED */
203             work_under_an_interruptible_budget();
204             CHK(  fosa_timer_disarm(jump_timer, NULL) );
205             printf("NOT JUMPPED\n");
206         }
207         else
208         {
209             printf("JUMPPPPPEEED\n");
210         }
211
212
213         /* End of interruptible work */
214         /*****************************/
215
216         printf("After interruptible block\n");
217
218         /* Now we measure the time duration of the block */
219         /*************************************************/
220         CHK( fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time) );
221         elapsed_time = fosa_abs_time_extract_interval
222           (activation_time, after_activation_time);
223         printf("Execution time: %ld msec\n", 
224                fosa_rel_time_to_msec(elapsed_time) );
225
226         /* And we program the next loop */
227         activation_time = fosa_abs_time_incr(activation_time, period);
228         activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
229         clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, 
230                         &activation_time_tspec,NULL);
231     }
232
233     return NULL;
234 }
235
236
237 // ------------------------------------------------------------------------------
238
239 static void work_under_an_interruptible_budget()
240 {
241     static int i = 0;
242     fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 sec
243
244     i++;
245     printf("Start regular work (eat 1s)\n");
246
247     fosa_eat(&exec_time);
248
249     /* Once in every 5 executions we work over the budget */
250     if (i % 5 == 0)
251     {
252       printf("Eat additional time (6s more) \n");
253       fosa_eat(&exec_time);
254       fosa_eat(&exec_time);
255       fosa_eat(&exec_time);
256       fosa_eat(&exec_time);
257       fosa_eat(&exec_time);
258       fosa_eat(&exec_time);
259     }
260
261     printf("End regular work\n");
262
263 }