1 //----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2007 by the FRESCOR consortium:
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
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org
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
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 // This file is part of FRSH (FRescor ScHeduler)
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.
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 // -----------------------------------------------------------------------
63 //#include <pthread.h>
69 #include "timespec_operations.h"
71 #include "marte_non_local_jmp.h"
73 /************************/
74 /** Constants and types */
75 /************************/
77 #define BUDGET_OVERRUN_SIGNAL SIGRTMIN+3
78 #define RT_ERROR_SIGWAIT -2
79 #define RT_ERROR_TIMER -3
83 marte_nonlocaljmp_context_t *context_ptr;
85 } budget_timer_info_t;
88 /************************/
89 /** Global Variables */
90 /************************/
92 static marte_nonlocaljmp_context_t context;
93 static int error_status;
96 /************************/
98 /************************/
100 static void * thread_body(void *arg);
101 static void * signal_handler_thread (void * arg);
104 /************************************************************************/
106 /************************************************************************/
110 fosa_signal_t set[1];
111 fosa_thread_attr_t attr;
113 fosa_thread_id_t tid1, tid2;
117 set[0]=BUDGET_OVERRUN_SIGNAL;
118 if (fosa_set_accepted_signals(set, 1) !=0) {
119 printf ("Error while setting the signal mask\n");
123 // Create the thread attributes object
124 if (fosa_thread_attr_init (&attr) != 0) {
125 printf("Error while initializing the attributes\n");
129 if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_max()-2) != 0) {
130 printf("Error while setting schedparam\n");
135 /* create the signal handler thread */
136 terror = fosa_thread_create(&tid1, &attr, signal_handler_thread, NULL);
138 printf("pthread_create signal handler\n");
142 // set priority of periodic thread
143 if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
144 printf("Error while setting schedparam\n");
148 /* create the periodic thread */
149 terror = fosa_thread_create(&tid2, &attr, thread_body, NULL);
151 printf("pthread_create periodic thread\n");
155 printf("Main goes to sleep...\n");
161 // work to be aborted if too long
164 struct timespec exec_time={1,0}; // 1 second
167 printf("start regular code %d\n",i);
169 // eat one second of budget
170 fosa_eat(&exec_time);
171 // every five cycles eat an additional one second of budget */
174 fosa_eat(&exec_time);
175 printf("aqui tambien\n");
181 /* ------------------------------------------------------------ */
182 /** Body of periodic thread that consumes budget */
184 static void * thread_body(void *thread_arg)
186 struct timespec period={2,500000000}; // 2.5 seconds
187 struct timespec activation_time, old_activation_time;
188 struct timespec budget ={1,400000000}; // 1.4 seconds
189 fosa_timer_id_t timerid;
190 fosa_clock_id_t clockid;
191 budget_timer_info_t timerinfo;
192 fosa_signal_info_t siginfo;
195 timerinfo.tid=pthread_self();
196 timerinfo.context_ptr=&context;
198 fosa_clock_get_time(FOSA_CLOCK_REALTIME,&activation_time);
200 if (fosa_thread_get_cputime_clock(timerinfo.tid,&clockid) !=0) {
201 error_status=RT_ERROR_TIMER;
202 pthread_exit ( (void*)&error_status);
205 // create budget timer
206 siginfo.sival_ptr=(void *)(&timerinfo);
207 if (fosa_timer_create (clockid,BUDGET_OVERRUN_SIGNAL,siginfo,&timerid)
210 error_status=RT_ERROR_TIMER;
211 pthread_exit ( (void*)&error_status);
214 printf("Start periodic thread body\n");
219 // set the budget timer
220 if (fosa_timer_arm(timerid, false, &budget) != 0) {
221 error_status=RT_ERROR_TIMER;
222 pthread_exit ( (void*)&error_status);
225 printf("Begin thread %d,%d\n",(int)activation_time.tv_sec,
226 (int)(activation_time.tv_nsec/1000000));
232 marte_nonlocaljmp_savecontext(&context);
233 printf ("salvado\n");
235 if (marte_nonlocaljmp_afterjmp(&context)==0) {
236 printf("start regular code\n");
239 // code executed if asynchronous jump instruction invoked */
240 printf("Aborted thread\n");
243 //printf("after block %d\n",marte_nonlocaljmp_afterjmp(&context));
244 printf("after block\n");
245 fosa_clock_get_time(FOSA_CLOCK_REALTIME,&old_activation_time);
246 decr_timespec(&old_activation_time,&activation_time);
247 printf("End thread %6.3f\n",old_activation_time.tv_sec+(float)
248 (float)old_activation_time.tv_nsec/1000000000.0);
250 incr_timespec(&activation_time,&period);
251 clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
252 &activation_time,&old_activation_time);
257 /*----------------------------------------------------------------------*/
259 /** Body of signal handler thread
260 * The signal mask is assumed to be inherited from the parent
263 void * signal_handler_thread (void * arg) {
265 fosa_signal_t set[1];
267 fosa_signal_info_t siginfo;
269 budget_timer_info_t *info;
271 // Wait for a budget overrun signal
272 set[0]=BUDGET_OVERRUN_SIGNAL;
274 if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
275 error_status=RT_ERROR_SIGWAIT;
276 pthread_exit ( (void*)&error_status);
278 // Restore periodic thread's context
279 printf("About to restore\n");
280 info=((budget_timer_info_t*) (siginfo.sival_ptr));
281 marte_nonlocaljmp_restorecontext(info->tid,info->context_ptr);
282 printf("Restored thread %d\n",info->dummy);