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