]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte/tests/test_non_local_jump/simple_test_non_local_jump.c
44abc3b003de31fc2fe0915f41d4a3466aeacda4
[frescor/fosa.git] / src_marte / tests / test_non_local_jump / simple_test_non_local_jump.c
1 //----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
3 //
4 //    Universidad de Cantabria,              SPAIN
5 //    University of York,                    UK
6 //    Scuola Superiore Sant'Anna,            ITALY
7 //    Kaiserslautern University,             GERMANY
8 //    Univ. Politecnica  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
17 //
18 //        The 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 // This file is part of FRSH (FRescor ScHeduler)
32 //
33 // FRSH is free software; you can redistribute it and/or modify it
34 // under terms of the GNU General Public License as published by the
35 // Free Software Foundation; either version 2, or (at your option) any
36 // later version.  FRSH is distributed in the hope that it will be
37 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39 // General Public License for more details. You should have received a
40 // copy of the GNU General Public License along with FRSH; see file
41 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
42 // Cambridge, MA 02139, USA.
43 //
44 // As a special exception, including FRSH header files in a file,
45 // instantiating FRSH generics or templates, or linking other files
46 // with FRSH objects to produce an executable application, does not
47 // by itself cause the resulting executable application to be covered
48 // by the GNU General Public License. This exception does not
49 // however invalidate any other reasons why the executable file might be
50 // covered by the GNU Public License.
51 // -----------------------------------------------------------------------
52 // 11-Jul-2007 SANGORRIN change calibrate and eat because it didn't work for
53 // MaRTE OS linux_arch
54 // 13-Jul-2007 SANGORRIN substitute calibrate for a new eat that I have added
55 // -----------------------------------------------------------------------
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <unistd.h>
59 #include <time.h>
60
61 //#include <string.h>
62 //#include <errno.h>
63 //#include <pthread.h>
64 //#include <sched.h>
65 //#include <signal.h>
66 //#include <frsh.h>
67
68 #include "fosa.h"
69
70 #include "marte_non_local_jmp.h"
71
72 /************************/
73 /** Constants and types */
74 /************************/
75
76 #define BUDGET_OVERRUN_SIGNAL SIGRTMIN+3
77 #define RT_ERROR_SIGWAIT -2
78 #define RT_ERROR_TIMER   -3
79
80 typedef struct {
81   fosa_thread_id_t tid;
82   marte_nonlocaljmp_context_t *context_ptr;
83   int dummy;
84 } budget_timer_info_t;
85
86
87 /************************/
88 /** Global Variables    */
89 /************************/
90
91 static marte_nonlocaljmp_context_t context;
92 static int error_status;
93
94
95 /************************/
96 /** Prototypes          */
97 /************************/
98
99 static void * thread_body(void *arg);
100 static void * signal_handler_thread (void * arg);
101
102
103 /************************************************************************/
104 /*                             Main program                             */
105 /************************************************************************/
106
107 int main()
108 {
109     fosa_signal_t set[1];
110     fosa_thread_attr_t attr;
111
112     fosa_thread_id_t tid1, tid2;
113     int terror = 0;
114
115     // set signal mask
116     set[0]=BUDGET_OVERRUN_SIGNAL;
117     if (fosa_set_accepted_signals(set, 1) !=0) {
118       printf ("Error while setting the signal mask\n"); 
119       exit (1);
120     }
121
122     // Create the thread attributes object
123     if (fosa_thread_attr_init (&attr) != 0) {
124       printf("Error while initializing the attributes\n");
125       exit(1);
126     }
127     
128     if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_max()-2) != 0) {
129       printf("Error while setting schedparam\n");
130       exit(1);
131     }
132
133
134     /* create the signal handler thread */
135     terror = fosa_thread_create(&tid1, &attr, signal_handler_thread, NULL);
136     if (terror) {
137         printf("pthread_create signal handler\n");
138         exit(1);
139     }
140
141     // set priority of periodic thread
142     if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
143       printf("Error while setting schedparam\n");
144       exit(1);
145     }
146
147     /* create the periodic thread */
148     terror = fosa_thread_create(&tid2, &attr, thread_body, NULL);
149     if (terror) {
150         printf("pthread_create periodic thread\n");
151         exit(1);
152     }
153
154     printf("Main goes to sleep...\n");
155     sleep(20000);
156
157     return 0;
158 }
159
160 // work to be aborted if too long
161 void work() {
162   static int i=0;
163   fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 second
164
165   i++;
166   printf("start regular code %d\n",i); 
167   // regular code 
168   // eat one second of budget 
169   fosa_eat(&exec_time); 
170   // every five cycles eat an additional one second of budget */
171   if (i%5==0) { 
172     printf("aqui\n");
173     fosa_eat(&exec_time); 
174     printf("aqui tambien\n");
175   } 
176 }
177
178
179
180 /* ------------------------------------------------------------ */
181 /** Body of periodic thread that consumes budget */
182
183 static void * thread_body(void *thread_arg)
184 {
185     fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
186     fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
187     fosa_abs_time_t activation_time, after_activation_time;
188     fosa_rel_time_t elapsed_time;
189     struct timespec activation_time_tspec;
190
191     fosa_timer_id_t timerid;
192     fosa_clock_id_t clockid;
193     budget_timer_info_t timerinfo;
194     fosa_signal_info_t siginfo;
195     int i=0;
196
197     timerinfo.tid=pthread_self();
198     timerinfo.context_ptr=&context;
199
200     fosa_clock_get_time(FOSA_CLOCK_REALTIME,&activation_time);
201
202     if (fosa_thread_get_cputime_clock(timerinfo.tid,&clockid) !=0) {
203         error_status=RT_ERROR_TIMER;
204         pthread_exit ( (void*)&error_status);
205     }
206
207     // create budget timer
208     siginfo.sival_ptr=(void *)(&timerinfo);
209     if (fosa_timer_create (clockid,BUDGET_OVERRUN_SIGNAL,siginfo,&timerid)
210         != 0) 
211     {
212         error_status=RT_ERROR_TIMER;
213         pthread_exit ( (void*)&error_status);
214     }
215
216     printf("Start periodic thread body\n");
217    
218     // main loop
219     while(1) {
220       
221         // set the budget timer
222         if (fosa_rel_timer_arm(timerid, &budget) != 0) {
223             error_status=RT_ERROR_TIMER;
224             pthread_exit ( (void*)&error_status);
225         }
226  
227         printf("Begin thread %ld msec\n", fosa_abs_time_to_msec(activation_time) );
228         i++;
229         timerinfo.dummy=i;
230
231         // save context
232       
233         marte_nonlocaljmp_savecontext(&context);
234         printf ("salvado\n");
235
236         if (marte_nonlocaljmp_afterjmp(&context)==0) { 
237             printf("start regular code\n"); 
238             work();
239         } else { 
240             // code executed if asynchronous jump instruction invoked */
241             printf("Aborted thread\n"); 
242         } 
243
244         //printf("after block %d\n",marte_nonlocaljmp_afterjmp(&context));
245         printf("after block\n");
246         fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time);
247         elapsed_time = fosa_abs_time_extract_interval(activation_time, after_activation_time);
248         printf("End   thread %ld msec\n", fosa_abs_time_to_msec(after_activation_time) );
249
250         // sleep for a while
251         activation_time = fosa_abs_time_incr(activation_time, period);
252         activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
253         
254         clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
255                         &activation_time_tspec, NULL);
256     } // while
257 }
258
259
260 /*----------------------------------------------------------------------*/
261
262 /** Body of signal handler thread 
263  * The signal mask is assumed to be inherited from the parent
264  */
265
266 void * signal_handler_thread (void * arg) {
267
268   fosa_signal_t set[1];
269   fosa_signal_t sig;
270   fosa_signal_info_t siginfo;
271
272   budget_timer_info_t *info;
273
274   // Wait for a budget overrun signal
275   set[0]=BUDGET_OVERRUN_SIGNAL;
276   while (1) {
277     if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
278       error_status=RT_ERROR_SIGWAIT;
279       pthread_exit ( (void*)&error_status);
280     }
281     // Restore periodic thread's context
282     printf("About to restore\n");
283     info=((budget_timer_info_t*) (siginfo.sival_ptr));
284     marte_nonlocaljmp_restorecontext(info->tid,info->context_ptr);
285     printf("Restored thread %d\n",info->dummy);
286   }
287 }