1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2008 FRESCOR consortium partners:
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
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
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
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 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FOSA (Frsh Operating System Adaption)
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.
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 // -----------------------------------------------------------------------
56 //==============================================
57 // ******** ****** ******** **********
58 // **///// /** ** **////// /** /**
59 // ** /** ** /** /** /**
60 // ******* /** ** /********* /**********
61 // **//// /** ** ////////** /**//////**
62 // ** /** ** /** /** /**
63 // ** /** ** ******** /** /**
64 // // /******/ //////// // //
66 // FOSA(Frescor Operating System Adaptation layer)
67 //================================================
73 #include <marte_non_local_jmp.h>
79 static int handler_installed=0;
80 static fosa_thread_id_t handler_tid;
83 * fosa_long_jump_save_context
85 * Save the context of the current thread for a future long jump
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
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
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.
104 * Returns 0 if successful; otherwise it returns an error code:
105 * FOSA_EINVAL: the value of context is invalid
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
111 int fosa_long_jump_save_context
112 (fosa_long_jump_context_t * context)
117 marte_nonlocaljmp_savecontext (&(context->marte_context));
118 context->tid=pthread_self();
125 * fosa_long_jump_was_performed
127 * Check whether the current thread suffered a long jump or not
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
138 * Returns 0 if successful; otherwise it returns an error code:
139 * FOSA_EINVAL: the value of context is invalid
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
145 int fosa_long_jump_was_performed
146 (const fosa_long_jump_context_t * context, int * jumped)
151 *jumped=marte_nonlocaljmp_afterjmp (&(context->marte_context));
158 * Body of the long-jump handler thread
161 void * fosa_long_jump_handler (void * arg) {
163 fosa_signal_t set[1];
165 fosa_signal_info_t siginfo;
167 fosa_long_jump_context_t *info;
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");
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");
183 // Restore thread's context
184 info=((fosa_long_jump_context_t*) (siginfo.sival_ptr));
185 marte_nonlocaljmp_restorecontext(info->tid,&(info->marte_context));
192 * fosa_long_jump_install_handler
194 * Install a long jump handler for the calling thread
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.
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.
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.
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.
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
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
233 int fosa_long_jump_install_handler
234 (fosa_signal_t *signal, fosa_thread_id_t *handler)
236 fosa_thread_attr_t attr;
239 if (!handler_installed) {
243 //////////////////////////////////////////////////
244 // create the long jump handler thread
245 //////////////////////////////////////////////////
247 // Create the thread attributes object
248 err=fosa_thread_attr_init (&attr);
250 printf("Error while initializing the attributes\n");
254 // set the maximum priority level for the handler
255 err=fosa_thread_attr_set_prio (&attr,fosa_get_priority_max());
257 printf("Error while setting schedparam\n");
261 /* create the signal handler thread */
262 err = fosa_thread_create(&handler_tid, &attr,
263 fosa_long_jump_handler, NULL);
265 printf("pthread_create signal handler\n");
269 // destroy the thread attributes object
270 err=fosa_thread_attr_destroy (&attr);
272 printf("Error while destroying the attributes\n");
276 } // if handler not installed
278 // return handler and signal information
279 *handler=handler_tid;
280 *signal=FOSA_LONG_JUMP_SIGNAL;