From b3a0a104106e423b9d481aed060f4e9f29ebaf5e Mon Sep 17 00:00:00 2001 From: brocalv Date: Mon, 25 Feb 2008 08:45:03 +0000 Subject: [PATCH] FOSA-PaRTiKle: long jumps initial git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@1028 35b4ef3e-fd22-0410-ab77-dab3279adceb --- src_partikle/fosa_long_jump.c | 145 ++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src_partikle/fosa_long_jump.c diff --git a/src_partikle/fosa_long_jump.c b/src_partikle/fosa_long_jump.c new file mode 100644 index 0000000..6ad5407 --- /dev/null +++ b/src_partikle/fosa_long_jump.c @@ -0,0 +1,145 @@ +//---------------------------------------------------------------------- +// 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 + +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 */ -- 2.39.2