]> rtime.felk.cvut.cz Git - frescor/fosa.git/blob - src_marte/fosa_long_jump.c
417c94ab6867a7d03d23148cebaa8aa9be4f65ac
[frescor/fosa.git] / src_marte / 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 FOSA (Frsh Operating System Abstraction)
32 //
33 // FOSA 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.  FOSA 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 FOSA; 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 FOSA header files in a file,
45 // instantiating FOSA generics or templates, or linking other files
46 // with FOSA 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 //fosa_long_jump.c
53 //==============================================
54 //  ********  ******    ********  **********
55 //  **///// /**    **  **//////  /**     /**
56 //  **      /**    ** /**        /**     /**
57 //  ******* /**    ** /********* /**********
58 //  **////  /**    ** ////////** /**//////**
59 //  **      /**    **        /** /**     /**
60 //  **      /**    **  ********  /**     /**
61 //  //       /******/  ////////   //      //
62 //
63 // FOSA(Frescor Operating System Adaptation layer)
64 //================================================
65
66 #include <stdio.h>
67 #include "fosa_long_jump.h"
68 #include "fosa_configuration_parameters.h"
69 #include "fosa_threads_and_signals.h"
70 #include <marte_non_local_jmp.h>
71
72 /**
73  * Global variables
74  */
75
76 static int handler_installed=0;
77 static frsh_thread_id_t handler_tid;
78
79 /**
80  *  fosa_long_jump_save_context
81  *
82  *  Save the context of the current thread for a future long jump
83  *
84  *  This function stores in context the information required to modify
85  *  the stack of the calling thread so that a later long jump may be 
86  *  executed in the future to restore this context
87  *
88  *  This function stores in 'context' the registers and the stack
89  *  frame of the calling thread. This information can be used by
90  *  'restorecontext' to change the stack of the task so that when it
91  *  is scheduled again it returns to the end of this function
92  *
93  *  Depending on the underlying implementation, the first invocation
94  *  of this function for a given thread may also install a signal
95  *  handler or a signal handler thread that is capable of executing
96  *  the actions required to restore the context of a thread from the
97  *  appropriate context. For instance, in POSIX it is necesaray that
98  *  the context is restored from the same thread being restored,
99  *  usually from a signal handler of that thread.
100  *
101  *  Returns 0 if successful; otherwise it returns an error code:
102  *     FOSA_EINVAL: the value of context is invalid
103  *
104  *  Alternatively, in case of error the implementation is allowed to
105  *  notify it to the system console and then terminate the FRSH
106  *  implementation and dependant applications
107  */
108 int fosa_long_jump_save_context
109    (fosa_long_jump_context_t * context) 
110 {
111   if (context==NULL) {
112     return FOSA_EINVAL;
113   } else {
114     marte_nonlocaljmp_savecontext (&(context->marte_context));
115     context->tid=pthread_self();
116     return 0;
117   }
118 }
119
120
121 /**
122  *  fosa_long_jump_was_performed
123  *
124  *  Check whether the current thread suffered a long jump or not
125  *
126  *  This function should be invoked after fosa_long_jump_save_context
127  *  to determine whether the current thread is executing normally, or
128  *  has suffered a long jump to the point where the context was
129  *  saved. If invoked after a direct invocation to
130  *  fosa_long_jump_save_context, the function shall return 0. If
131  *  invoked after returning from fosa_long_jump_save_context due to a
132  *  call to fosa_long_jump_restore_context, the function shall return
133  *  1.
134  *
135  *  Returns 0 if successful; otherwise it returns an error code:
136  *     FOSA_EINVAL: the value of context is invalid
137  *
138  *  Alternatively, in case of error the implementation is allowed to
139  *  notify it to the system console and then terminate the FRSH
140  *  implementation and dependant applications
141  */
142 int fosa_long_jump_was_performed
143 (const fosa_long_jump_context_t * context, int * jumped) 
144 {
145   if (context==NULL) {
146     return FOSA_EINVAL;
147   } else {
148     *jumped=marte_nonlocaljmp_afterjmp (&(context->marte_context));
149     return 0;
150   }  
151 }
152
153
154 /** 
155  * Body of the long-jump handler thread 
156  */
157
158 void * fosa_long_jump_handler (void * arg) {
159
160   frsh_signal_t set[1];
161   frsh_signal_t sig;
162   frsh_signal_info_t siginfo;
163
164   fosa_long_jump_context_t *info;
165
166   // initialize signal handling
167   set[0]=FOSA_LONG_JUMP_SIGNAL;
168   if (fosa_set_accepted_signals(set, 1) !=0) {
169       printf("FRSH_ERR_INTERNAL_ERROR, Error setting the signal mask\n");
170       exit(1); 
171   }
172
173   // main thread loop  
174   while (1) {
175     // Wait for a budget overrun signal
176     if ((fosa_signal_wait(set, 1, &sig, &siginfo)) == -1) {
177       printf("FRSH_ERR_INTERNAL_ERROR, signal wait in long jump handler\n");
178       exit(1);
179     }
180     // Restore thread's context
181     info=((fosa_long_jump_context_t*) (siginfo.sival_ptr));
182     marte_nonlocaljmp_restorecontext(info->tid,&(info->marte_context));
183   }
184 }
185
186
187
188 /**
189  *  fosa_long_jump_install_handler
190  *
191  *  Install a long jump handler for the calling thread
192  *
193  *  This function shall install a handler that is capable of causing a
194  *  long jump operation that restores the context of a thread to a
195  *  previously saved value. If the handler has already been installed
196  *  for this thread the previously installed handler will be used and
197  *  the call shall succeed.
198  *
199  *  The long-jump handler is waiting for a signal to notify that a
200  *  thread context should be restored. This signal must carry attached
201  *  to it a pointer to the variable where the thread context was
202  *  saved. The thread referenced in that context will have its
203  *  internal context restored to the point where it was saved. For
204  *  this restore operation to work properly, the program frame where
205  *  the thread saved its context must still be valid.
206  *
207  *  Depending on the implementation a given thread may also install a signal
208  *  handler or a signal handler thread that is capable of executing
209  *  the actions required to restore the context of a thread from the
210  *  appropriate context. For instance, in POSIX it is necesaray that
211  *  the context is restored from the same thread being restored,
212  *  usually from a signal handler of that thread.
213  *
214  *  The function shall store in the variable pointed to by signal the
215  *  identifier of the signal that must be used to notify the request
216  *  for a long jump to be executed. In the variable pointed to by
217  *  handler, it shall store the thread id to which the signal must be
218  *  sent. The signal must be sent with its attached information set to
219  *  a pointer to the variable of type fosa_long_jump_context_t where
220  *  the context of the thread to be restored was saved.
221  *
222  *  Returns 0 if successful; otherwise it returns an error code:
223  *     FOSA_EINVAL: the value of context is invalid
224  *     FOSA_ENOMEM: there are no resources to satisfy the call at this time
225  *
226  *  Alternatively, in case of error the implementation is allowed to
227  *  notify it to the system console and then terminate the FRSH
228  *  implementation and dependant applications
229  */
230 int fosa_long_jump_install_handler
231 (frsh_signal_t *signal, frsh_thread_id_t *handler)
232 {
233   frsh_thread_attr_t attr;
234   int err;
235   
236   if (!handler_installed) {
237
238     handler_installed=1;
239
240     //////////////////////////////////////////////////
241     // create the long jump handler thread
242     //////////////////////////////////////////////////
243     
244     // Create the thread attributes object
245     err=frsh_thread_attr_init (&attr);
246     if (err != 0) {
247       printf("Error while initializing the attributes\n");
248       return err;
249     }
250     
251     // set the maximum priority level for the handler
252     err=fosa_thread_attr_set_prio (&attr,fosa_get_priority_max());
253     if (err != 0) {
254       printf("Error while setting schedparam\n");
255       return err;
256     }
257     
258     /* create the signal handler thread */
259     err = fosa_thread_create(&handler_tid, &attr, 
260                              fosa_long_jump_handler, NULL);
261     if (err) {
262       printf("pthread_create signal handler\n");
263       return err;
264     }
265     
266     // destroy the thread attributes object
267     err=frsh_thread_attr_destroy (&attr);
268     if (err != 0) {
269       printf("Error while destroying the attributes\n");
270       return err;
271     }
272   
273   } // if handler not installed
274
275   // return handler and signal information
276   *handler=handler_tid;
277   *signal=FOSA_LONG_JUMP_SIGNAL;
278   return 0;
279
280 }
281
282
283
284 /*@}*/
285