]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte/tests/test_non_local_jump/test_fosa_long_jump.c
Reworking indentation of test_fosa_long_jump.c
[frescor/fosa.git] / src_marte / tests / test_non_local_jump / test_fosa_long_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 #include <stdio.h>
53 #include <stdlib.h>
54 #include <unistd.h>
55 #include <time.h>
56
57 //#include <string.h>
58 //#include <errno.h>
59 //#include <pthread.h>
60 //#include <sched.h>
61 //#include <signal.h>
62 //#include <frsh.h>
63
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"
68
69 #include "timespec_operations.h"
70
71 #include "fosa_long_jump.h"
72
73 /************************/
74 /** Constants and types */
75 /************************/
76
77 #define RT_ERROR_SIGWAIT -2
78 #define RT_ERROR_TIMER   -3
79 #define RT_ERROR_HANDLER -4
80
81
82 /************************/
83 /** Global Variables    */
84 /************************/
85
86 static fosa_long_jump_context_t context;
87 static int error_status = 0;
88
89
90 /************************/
91 /** Prototypes          */
92 /************************/
93
94 static void * thread_body(void *arg);
95 static void work();
96
97
98 /************************************************************************/
99 /*                             Main program                             */
100 /************************************************************************/
101
102 int main()
103 {
104     //frsh_signal_t set[1];
105     frsh_thread_attr_t attr;
106
107     frsh_thread_id_t tid_periodic_thread;
108     int terror = 0;
109     frsh_signal_t signal_set[1];
110
111
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) );
116
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");
121         exit(1);
122     }
123     
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");
127         exit(1);
128     }
129
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) )
134     {
135         printf("Error while changing main's priority\n");
136         exit(1);
137     }
138
139     /* create the periodic thread */
140     /******************************/
141     terror = fosa_thread_create(&tid_periodic_thread, &attr, thread_body, NULL);
142     if (terror) {
143         printf("pthread_create periodic thread\n");
144         exit(1);
145     }
146
147     printf("Main goes to sleep...\n");
148     sleep(20000);
149
150     return 0;
151 }
152
153
154
155
156 /* ------------------------------------------------------------ */
157 /** Body of periodic thread that consumes budget */
158
159 static void * thread_body(void *thread_arg)
160 {
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;
169     int jumped;
170     int err;
171
172
173     fosa_clock_get_time(FOSA_CLOCK_REALTIME, &activation_time);
174
175     if (fosa_thread_get_cputime_clock(pthread_self(),&clockid) !=0) {
176         error_status=RT_ERROR_TIMER;
177         pthread_exit ( (void*)&error_status);
178     }
179
180     // install long jump handler
181     if (fosa_long_jump_install_handler(&signal,&handler)!=0)
182         {
183         error_status=RT_ERROR_HANDLER;
184         pthread_exit ( (void*)&error_status);
185         }
186
187     // create budget timer
188     siginfo.sival_ptr=(void *)(&context);
189     if (fosa_timer_create_with_receiver 
190         (clockid,signal,siginfo,&timerid,handler) != 0) 
191     {
192         error_status=RT_ERROR_TIMER;
193         pthread_exit ( (void*)&error_status);
194     }
195
196     printf("Start periodic thread body\n");
197    
198     // main loop
199     while(1) {
200
201         jumped = 0;
202       
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);
207         }
208  
209         printf("Begin thread main loop at %d,%d\n",(int)activation_time.tv_sec, 
210                (int)(activation_time.tv_nsec/1000000));
211
212         // save context
213       
214         err=fosa_long_jump_save_context(&context);
215         if (err!=0) {
216             error_status=RT_ERROR_HANDLER;
217             pthread_exit ( (void*)&error_status);
218         }
219
220         err=fosa_long_jump_was_performed(&context,&jumped);
221         if (err!=0) {
222             error_status=RT_ERROR_HANDLER;
223             pthread_exit ( (void*)&error_status);
224         }
225         if (!jumped) { 
226             work();
227         } else { 
228             // code executed if asynchronous jump instruction invoked */
229             printf("Aborted thread\n"); 
230         } 
231
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);
237         // sleep for a while
238         incr_timespec(&activation_time,&period);
239         clock_nanosleep(FOSA_CLOCK_REALTIME,TIMER_ABSTIME,
240                         &activation_time,&old_activation_time);
241     } // while
242 }
243
244
245
246 // ---------------------------------------------------------------------
247
248 // work to be aborted if too long
249 static void work() 
250 {
251     static int i=0;
252     struct timespec exec_time={1,0}; // 1 second
253
254     i++;
255     printf("start regular code %d\n",i); 
256     // regular code 
257     // eat one second of budget 
258     frsh_eat(&exec_time); 
259     // every five cycles eat an additional one second of budget */
260     if (i%5==0) { 
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); 
266     } 
267 }