1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2008 FRESCOR consortium partners:
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
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
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
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FOSA (Frsh Operating System Adaption)
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.
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 // 11-Jul-2007 SANGORRIN change calibrate and eat because it didn't work for
56 // MaRTE OS linux_arch
57 // 13-Jul-2007 SANGORRIN substitute calibrate for a new eat that I have added
58 // -----------------------------------------------------------------------
66 //#include <pthread.h>
73 #include "misc/marte_non_local_jmp.h"
75 /************************/
76 /** Constants and types */
77 /************************/
79 #define BUDGET_OVERRUN_SIGNAL SIGRTMIN+3
80 #define RT_ERROR_SIGWAIT -2
81 #define RT_ERROR_TIMER -3
85 marte_nonlocaljmp_context_t *context_ptr;
87 } budget_timer_info_t;
90 /************************/
91 /** Global Variables */
92 /************************/
94 static marte_nonlocaljmp_context_t context;
95 static int error_status;
98 /************************/
100 /************************/
102 static void * thread_body(void *arg);
103 static void * signal_handler_thread (void * arg);
106 /************************************************************************/
108 /************************************************************************/
112 fosa_signal_t set[1];
113 fosa_thread_attr_t attr;
115 fosa_thread_id_t tid1, tid2;
119 set[0]=BUDGET_OVERRUN_SIGNAL;
120 if (fosa_set_accepted_signals(set, 1) !=0) {
121 printf ("Error while setting the signal mask\n");
125 // Create the thread attributes object
126 if (fosa_thread_attr_init (&attr) != 0) {
127 printf("Error while initializing the attributes\n");
131 if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_max()-2) != 0) {
132 printf("Error while setting schedparam\n");
137 /* create the signal handler thread */
138 terror = fosa_thread_create(&tid1, &attr, signal_handler_thread, NULL);
140 printf("pthread_create signal handler\n");
144 // set priority of periodic thread
145 if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
146 printf("Error while setting schedparam\n");
150 /* create the periodic thread */
151 terror = fosa_thread_create(&tid2, &attr, thread_body, NULL);
153 printf("pthread_create periodic thread\n");
157 printf("Main goes to sleep...\n");
163 // work to be aborted if too long
166 fosa_rel_time_t exec_time = fosa_msec_to_rel_time(1000); // 1 second
169 printf("start regular code %d\n",i);
171 // eat one second of budget
172 fosa_eat(&exec_time);
173 // every five cycles eat an additional one second of budget */
176 fosa_eat(&exec_time);
177 printf("aqui tambien\n");
183 /* ------------------------------------------------------------ */
184 /** Body of periodic thread that consumes budget */
186 static void * thread_body(void *thread_arg)
188 fosa_rel_time_t period = fosa_msec_to_rel_time(2500);
189 fosa_rel_time_t budget = fosa_msec_to_rel_time(1400);
190 fosa_abs_time_t activation_time, after_activation_time;
191 fosa_rel_time_t elapsed_time;
192 struct timespec activation_time_tspec;
194 fosa_timer_id_t timerid;
195 fosa_clock_id_t clockid;
196 budget_timer_info_t timerinfo;
197 fosa_signal_info_t siginfo;
200 timerinfo.tid=pthread_self();
201 timerinfo.context_ptr=&context;
203 fosa_clock_get_time(FOSA_CLOCK_REALTIME,&activation_time);
205 if (fosa_thread_get_cputime_clock(timerinfo.tid,&clockid) !=0) {
206 error_status=RT_ERROR_TIMER;
207 pthread_exit ( (void*)&error_status);
210 // create budget timer
211 siginfo.sival_ptr=(void *)(&timerinfo);
212 if (fosa_timer_create (clockid,BUDGET_OVERRUN_SIGNAL,siginfo,&timerid)
215 error_status=RT_ERROR_TIMER;
216 pthread_exit ( (void*)&error_status);
219 printf("Start periodic thread body\n");
224 // set the budget timer
225 if (fosa_rel_timer_arm(timerid, &budget) != 0) {
226 error_status=RT_ERROR_TIMER;
227 pthread_exit ( (void*)&error_status);
230 printf("Begin thread %ld msec\n", fosa_abs_time_to_msec(activation_time) );
236 marte_nonlocaljmp_savecontext(&context);
237 printf ("salvado\n");
239 if (marte_nonlocaljmp_afterjmp(&context)==0) {
240 printf("start regular code\n");
243 // code executed if asynchronous jump instruction invoked */
244 printf("Aborted thread\n");
247 //printf("after block %d\n",marte_nonlocaljmp_afterjmp(&context));
248 printf("after block\n");
249 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &after_activation_time);
250 elapsed_time = fosa_abs_time_extract_interval(activation_time, after_activation_time);
251 printf("End thread %ld msec\n", fosa_abs_time_to_msec(after_activation_time) );
254 activation_time = fosa_abs_time_incr(activation_time, period);
255 activation_time_tspec = fosa_abs_time_to_timespec(activation_time);
257 clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
258 &activation_time_tspec, NULL);
263 /*----------------------------------------------------------------------*/
265 /** Body of signal handler thread
266 * The signal mask is assumed to be inherited from the parent
269 void * signal_handler_thread (void * arg) {
271 fosa_signal_t set[1];
273 fosa_signal_info_t siginfo;
275 budget_timer_info_t *info;
277 // Wait for a budget overrun signal
278 set[0]=BUDGET_OVERRUN_SIGNAL;
280 if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
281 error_status=RT_ERROR_SIGWAIT;
282 pthread_exit ( (void*)&error_status);
284 // Restore periodic thread's context
285 printf("About to restore\n");
286 info=((budget_timer_info_t*) (siginfo.sival_ptr));
287 marte_nonlocaljmp_restorecontext(info->tid,info->context_ptr);
288 printf("Restored thread %d\n",info->dummy);