--- /dev/null
+//----------------------------------------------------------------------
+// Copyright (C) 2006 - 2007 by the FRESCOR consortium:
+//
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+// Scuola Superiore Sant'Anna, ITALY
+// Kaiserslautern University, GERMANY
+// Univ. Politecnica Valencia, SPAIN
+// Czech Technical University in Prague, CZECH REPUBLIC
+// ENEA SWEDEN
+// Thales Communication S.A. FRANCE
+// Visual Tools S.A. SPAIN
+// Rapita Systems Ltd UK
+// Evidence ITALY
+//
+// See http://www.frescor.org
+//
+// The FRESCOR project (FP6/2005/IST/5-034026) is funded
+// in part by the European Union Sixth Framework Programme
+// The European Union is not liable of any use that may be
+// made of this code.
+//
+//
+// based on previous work (FSF) done in the FIRST project
+//
+// Copyright (C) 2005 Mälardalen University, SWEDEN
+// Scuola Superiore S.Anna, ITALY
+// Universidad de Cantabria, SPAIN
+// University of York, UK
+//
+// This file is part of FOSA (Frsh Operating System Abstraction)
+//
+// FOSA is free software; you can redistribute it and/or modify it
+// under terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option) any
+// later version. FOSA is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details. You should have received a
+// copy of the GNU General Public License along with FOSA; see file
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
+// Cambridge, MA 02139, USA.
+//
+// As a special exception, including FOSA header files in a file,
+// instantiating FOSA generics or templates, or linking other files
+// with FOSA objects to produce an executable application, does not
+// by itself cause the resulting executable application to be covered
+// by the GNU General Public License. This exception does not
+// however invalidate any other reasons why the executable file might be
+// covered by the GNU Public License.
+// -----------------------------------------------------------------------
+//fosa_long_jump.h
+//==============================================
+// ******** ****** ******** **********
+// **///// /** ** **////// /** /**
+// ** /** ** /** /** /**
+// ******* /** ** /********* /**********
+// **//// /** ** ////////** /**//////**
+// ** /** ** /** /** /**
+// ** /** ** ******** /** /**
+// // /******/ //////// // //
+//
+// FOSA(Frescor Operating System Adaptation layer)
+//================================================
+
+#ifdef CONFIG_LONGJUMP
+
+#include <fosa_long_jump.h>
+
+enum {
+ LONGJMP_MAGIC = 0x01234567,
+ LONGJMP_NSIG = 3,
+ LONGJMP_FIRSTSIG = SIGRTMIN + 1,
+};
+
+int jmp_used_signals [LONGJMP_NSIG] = {[0 ... (LONGJMP_NSIG - 1)] = 0};
+
+int fosa_long_jump_save_context
+ (fosa_long_jump_context_t * context)
+{
+ if (!context)
+ return FOSA_EINVAL;
+
+ // Save the actual signal mask & mark the jump as still not performed
+ pthread_sigmask (SIG_SETMASK, NULL, &(context -> jmp_sigmask));
+ context -> jmp_hasexecuted = false;
+
+ if (setjmp (context -> jmp_context) == LONGJMP_MAGIC) {
+ context -> jmp_hasexecuted = true;
+ pthread_sigmask (SIG_SETMASK, &(context -> jmp_sigmask), NULL);
+ }
+ return 0;
+}
+
+int fosa_long_jump_was_performed
+ (const fosa_long_jump_context_t * context, int * jumped)
+{
+ if (!context && !jumped)
+ return FOSA_EINVAL;
+
+ *jumped = context -> jmp_hasexecuted? 1:0;
+ return 0;
+}
+
+void jmp_handler (int signo, siginfo_t *info, void *context)
+{
+ fosa_long_jump_context_t *jmp_info = (fosa_long_jump_context_t *) info -> si_value.sival_ptr;
+ longjmp (jmp_info -> jmp_context, LONGJMP_MAGIC);
+ return;
+}
+
+int fosa_long_jump_install_handler
+ (fosa_signal_t *signal, fosa_thread_id_t *handler)
+{
+ int i;
+ struct sigaction sa;
+ sigset_t sigmask;
+
+ // Find the first usable signal
+ // FIXME: Should be atomical
+ for (i = 0; i < LONGJMP_NSIG && jmp_used_signals [i]; i++);
+ if (i >= LONGJMP_NSIG)
+ return FOSA_ENOMEM;
+
+ jmp_used_signals [i] = 1;
+
+ *signal = LONGJMP_FIRSTSIG + i;
+ *handler = pthread_self ();
+
+ // intall the jump handler
+ sa.sa_flags = SA_SIGINFO;
+ sigfillset (&sa.sa_mask);
+ sa.sa_sigaction = jmp_handler;
+ sigaction (*signal, &sa, NULL);
+
+ // unmask the signal for the calling thread
+ sigemptyset (&sigmask);
+ sigaddset (&sigmask, *signal);
+ pthread_sigmask (SIG_UNBLOCK, &sigmask, NULL);
+
+ return 0;
+}
+
+
+#endif /* CONFIG_LONGJUMP */