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 // -----------------------------------------------------------------------
59 //#include <pthread.h>
64 #include "frsh_fosa.h"
65 #include "fosa_threads_and_signals.h"
66 #include "fosa_clocks_and_timers.h"
67 #include "fosa_configuration_parameters.h"
69 #include "timespec_operations.h"
71 #include "fosa_long_jump.h"
73 /************************/
74 /** Constants and types */
75 /************************/
77 #define RT_ERROR_SIGWAIT -2
78 #define RT_ERROR_TIMER -3
79 #define RT_ERROR_HANDLER -4
82 /************************/
83 /** Global Variables */
84 /************************/
86 static fosa_long_jump_context_t context;
87 static int error_status = 0;
90 /************************/
92 /************************/
94 static void * thread_body(void *arg);
98 /************************************************************************/
100 /************************************************************************/
104 //frsh_signal_t set[1];
105 frsh_thread_attr_t attr;
107 frsh_thread_id_t tid_periodic_thread;
109 frsh_signal_t signal_set[1];
112 memset(&attr, 0, sizeof(attr) );
113 memset(&tid_periodic_thread, 0, sizeof(tid_periodic_thread) );
114 memset(&context, 0, sizeof(context) );
115 memset(&signal_set, 0, sizeof(signal_set) );
117 /* Create the thread attributes object and assign the new thread a
118 priority lower than the main */
119 if (frsh_thread_attr_init (&attr) != 0) {
120 printf("Error while initializing the attributes\n");
124 // set priority of periodic thread
125 if (fosa_thread_attr_set_prio (&attr,fosa_get_priority_min()+3) != 0) {
126 printf("Error while setting schedparam\n");
130 /* We set the priority of this main thread to a lever higher */
131 /* than the future periodic thread. */
132 /*************************************************************/
133 if (fosa_thread_set_prio(fosa_thread_self(), fosa_get_priority_min() + 4) )
135 printf("Error while changing main's priority\n");
139 /* create the periodic thread */
140 /******************************/
141 terror = fosa_thread_create(&tid_periodic_thread, &attr, thread_body, NULL);
143 printf("pthread_create periodic thread\n");
147 printf("Main goes to sleep...\n");
156 /* ------------------------------------------------------------ */
157 /** Body of periodic thread that consumes budget */
159 static void * thread_body(void *thread_arg)
161 struct timespec period={2,500000000}; // 2.5 seconds
162 struct timespec activation_time, old_activation_time;
163 struct timespec budget ={1,400000000}; // 1.4 seconds
164 fosa_timer_id_t timerid;
165 fosa_clock_id_t clockid;
166 frsh_signal_info_t siginfo;
167 frsh_signal_t signal;
168 frsh_thread_id_t handler;
173 fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time);
175 if (fosa_thread_get_cputime_clock(pthread_self(),&clockid) !=0) {
176 error_status=RT_ERROR_TIMER;
177 pthread_exit ( (void*)&error_status);
180 // install long jump handler
181 if (fosa_long_jump_install_handler(&signal,&handler)!=0)
183 error_status=RT_ERROR_HANDLER;
184 pthread_exit ( (void*)&error_status);
187 // create budget timer
188 siginfo.sival_ptr=(void *)(&context);
189 if (fosa_timer_create_with_receiver
190 (clockid,signal,siginfo,&timerid,handler) != 0)
192 error_status=RT_ERROR_TIMER;
193 pthread_exit ( (void*)&error_status);
196 printf("Start periodic thread body\n");
203 // set the budget timer
204 if (fosa_timer_arm(timerid, false, &budget) != 0) {
205 error_status=RT_ERROR_TIMER;
206 pthread_exit ( (void*)&error_status);
209 printf("Begin thread main loop at %d,%d\n",(int)activation_time.tv_sec,
210 (int)(activation_time.tv_nsec/1000000));
214 err=fosa_long_jump_save_context(&context);
216 error_status=RT_ERROR_HANDLER;
217 pthread_exit ( (void*)&error_status);
220 err=fosa_long_jump_was_performed(&context,&jumped);
222 error_status=RT_ERROR_HANDLER;
223 pthread_exit ( (void*)&error_status);
228 // code executed if asynchronous jump instruction invoked */
229 printf("Aborted thread\n");
232 printf("after abortable block\n");
233 fosa_clock_get_time(FOSA_CLOCK_REALTIME,&old_activation_time);
234 decr_timespec(&old_activation_time,&activation_time);
235 printf("End thread %6.3f\n",old_activation_time.tv_sec+(float)
236 (float)old_activation_time.tv_nsec/1000000000.0);
238 incr_timespec(&activation_time,&period);
239 clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
240 &activation_time,&old_activation_time);
246 // ---------------------------------------------------------------------
248 // work to be aborted if too long
252 struct timespec exec_time={1,0}; // 1 second
255 printf("start regular code %d\n",i);
257 // eat one second of budget
258 frsh_eat(&exec_time);
259 // every five cycles eat an additional one second of budget */
261 frsh_eat(&exec_time);
262 frsh_eat(&exec_time);
263 frsh_eat(&exec_time);
264 frsh_eat(&exec_time);
265 frsh_eat(&exec_time);