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 FOSA (Frsh Operating System Abstraction)
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.
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 // -----------------------------------------------------------------------
53 //==============================================
54 // ******** ****** ******** **********
55 // **///// /** ** **////// /** /**
56 // ** /** ** /** /** /**
57 // ******* /** ** /********* /**********
58 // **//// /** ** ////////** /**//////**
59 // ** /** ** /** /** /**
60 // ** /** ** ******** /** /**
61 // // /******/ //////// // //
63 // FOSA(Frescor Operating System Adaptation layer)
64 //================================================
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>
76 static int handler_installed=0;
77 static frsh_thread_id_t handler_tid;
80 * fosa_long_jump_save_context
82 * Save the context of the current thread for a future long jump
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
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
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.
101 * Returns 0 if successful; otherwise it returns an error code:
102 * FOSA_EINVAL: the value of context is invalid
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
108 int fosa_long_jump_save_context
109 (fosa_long_jump_context_t * context)
114 marte_nonlocaljmp_savecontext (&(context->marte_context));
115 context->tid=pthread_self();
122 * fosa_long_jump_was_performed
124 * Check whether the current thread suffered a long jump or not
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
135 * Returns 0 if successful; otherwise it returns an error code:
136 * FOSA_EINVAL: the value of context is invalid
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
142 int fosa_long_jump_was_performed
143 (const fosa_long_jump_context_t * context, int * jumped)
148 *jumped=marte_nonlocaljmp_afterjmp (&(context->marte_context));
155 * Body of the long-jump handler thread
158 void * fosa_long_jump_handler (void * arg) {
160 frsh_signal_t set[1];
162 frsh_signal_info_t siginfo;
164 fosa_long_jump_context_t *info;
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");
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");
180 // Restore thread's context
181 info=((fosa_long_jump_context_t*) (siginfo.sival_ptr));
182 marte_nonlocaljmp_restorecontext(info->tid,&(info->marte_context));
189 * fosa_long_jump_install_handler
191 * Install a long jump handler for the calling thread
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.
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.
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.
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.
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
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
230 int fosa_long_jump_install_handler
231 (frsh_signal_t *signal, frsh_thread_id_t *handler)
233 frsh_thread_attr_t attr;
236 if (!handler_installed) {
240 //////////////////////////////////////////////////
241 // create the long jump handler thread
242 //////////////////////////////////////////////////
244 // Create the thread attributes object
245 err=frsh_thread_attr_init (&attr);
247 printf("Error while initializing the attributes\n");
251 // set the maximum priority level for the handler
252 err=fosa_thread_attr_set_prio (&attr,fosa_get_priority_max());
254 printf("Error while setting schedparam\n");
258 /* create the signal handler thread */
259 err = fosa_thread_create(&handler_tid, &attr,
260 fosa_long_jump_handler, NULL);
262 printf("pthread_create signal handler\n");
266 // destroy the thread attributes object
267 err=frsh_thread_attr_destroy (&attr);
269 printf("Error while destroying the attributes\n");
273 } // if handler not installed
275 // return handler and signal information
276 *handler=handler_tid;
277 *signal=FOSA_LONG_JUMP_SIGNAL;