From 9bfbe4fd7c9069a9b57c9c15c225a1d4cf8ede23 Mon Sep 17 00:00:00 2001 From: brocalv Date: Mon, 19 May 2008 13:24:34 +0000 Subject: [PATCH] FOSA-PaRTiKle: fixes in long jumps git-svn-id: http://www.frescor.org/private/svn/frescor/fosa/trunk@1177 35b4ef3e-fd22-0410-ab77-dab3279adceb --- include/fosa_opaque_types.h | 15 ++++++---- src_partikle/fosa_long_jump.c | 26 ++++++++++++----- src_partikle/fosa_setjmp.S | 34 +++++++++++++++++++++- src_partikle/tests/test_long_jump.c | 45 ++++++++++++++++++++--------- 4 files changed, 92 insertions(+), 28 deletions(-) diff --git a/include/fosa_opaque_types.h b/include/fosa_opaque_types.h index bf2ee76..8f47e5f 100644 --- a/include/fosa_opaque_types.h +++ b/include/fosa_opaque_types.h @@ -333,6 +333,7 @@ typedef pthread_mutex_t FOSA_MUTEX_T_OPAQUE; #include #include #include +#include typedef struct { posix_appsched_actions_t actions; @@ -343,11 +344,7 @@ typedef struct { bool activated; } FOSA_ADS_ACTIONS_T_OPAQUE; -typedef struct { - jmp_buf jmp_context; - bool jmp_hasexecuted; - sigset_t jmp_sigmask; -} FOSA_LONG_JUMP_CONTEXT_T_OPAQUE; +typedef unsigned long FOSA_LONG_JUMP_CONTEXT_T_OPAQUE [32]; typedef pthread_t FOSA_THREAD_ID_T_OPAQUE; typedef pthread_attr_t FOSA_THREAD_ATTR_T_OPAQUE; @@ -363,13 +360,19 @@ enum _fosa_clocks_e { FOSA_SYSTEM_CLOCK_OPAQUE = CLOCK_MONOTONIC }; +#define LONGJMP_NSIG 3 + +#if LONGJMP_NSIG > (RTSIG_MAX - 1) +# error LONGJMP_NSIG too big (LONGJMP_NSIG > RTSIG_MAX - 1) +#endif + enum _fosa_signal_limits_e { - LONGJMP_NSIG = 3, LONGJMP_FIRSTSIG = SIGRTMAX - LONGJMP_NSIG + 1, FOSA_SIGNAL_MAX = LONGJMP_FIRSTSIG - 1, FOSA_SIGNAL_MIN = FOSA_SIGNAL_MAX, }; + enum _fosa_errors_e { FOSA_EINVAL = EINVAL, FOSA_EAGAIN = EAGAIN, diff --git a/src_partikle/fosa_long_jump.c b/src_partikle/fosa_long_jump.c index e59a69f..0868ec7 100644 --- a/src_partikle/fosa_long_jump.c +++ b/src_partikle/fosa_long_jump.c @@ -69,7 +69,7 @@ #include #define LONGJMP_MAGIC 0x01234567 -int jmp_used_signals [LONGJMP_NSIG] = {[0 ... (LONGJMP_NSIG - 1)] = 0}; +pthread_t jmp_used_signals [LONGJMP_NSIG] = {[0 ... (LONGJMP_NSIG - 1)] = NULL}; pthread_mutex_t signal_pool_m = PTHREAD_MUTEX_INITIALIZER; extern void fosa_longjmp (fosa_long_jump_context_t ctx, unsigned long magic); @@ -80,7 +80,6 @@ int fosa_long_jump_was_performed if (!context && !jumped) return FOSA_EINVAL; -// printf ("context [6]=%ld\n", (*(context))[6]); *jumped = ((*(context))[6] == LONGJMP_MAGIC); return 0; } @@ -90,11 +89,14 @@ 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; -#ifdef CONFIG_LONGJUMP_FREE_SIGNAL - sigset_t set; + sigset_t s; // Restore the signal mask -// pthread_sigmask (SIG_SETMASK, &(jmp_info -> jmp_sigmask), NULL); + s.sig = (*jmp_info)[7]; + pthread_sigmask (SIG_SETMASK, &s, NULL); + +#ifdef CONFIG_LONGJUMP_FREE_SIGNAL + sigset_t set; // Free this signal sigemptyset (&set); @@ -102,11 +104,10 @@ void jmp_handler (int signo, siginfo_t *info, void *context) pthread_sigmask (SIG_BLOCK, &sigmask, NULL); pthread_mutex_lock (&signal_pool_m); - jmp_used_signals [signo] = 0; + jmp_used_signals [signo] = NULL; pthread_mutex_unlock (&signal_pool_m); #endif -// printf ("\t\t\t\t>>> RESTORE CONTEXT <<<\n\n"); // Restore the saved context fosa_longjmp (*jmp_info, LONGJMP_MAGIC); return; @@ -120,6 +121,15 @@ int fosa_long_jump_install_handler struct sigaction sa; sigset_t sigmask; + // Check if current thread has a handler associated + for (i = 0; i < LONGJMP_NSIG; i ++) + if (jmp_used_signals [i] == pthread_self ()) { + sigemptyset (&sigmask); + sigaddset (&sigmask, LONGJMP_FIRSTSIG + i); + pthread_sigmask (SIG_UNBLOCK, &sigmask, NULL); + return 0; + } + // Find the first usable signal pthread_mutex_lock (&signal_pool_m); for (i = 0; i < LONGJMP_NSIG && jmp_used_signals [i]; i++); @@ -128,7 +138,7 @@ int fosa_long_jump_install_handler return FOSA_ENOMEM; } - jmp_used_signals [i] = 1; + jmp_used_signals [i] = pthread_self (); pthread_mutex_unlock (&signal_pool_m); *signal = LONGJMP_FIRSTSIG + i; diff --git a/src_partikle/fosa_setjmp.S b/src_partikle/fosa_setjmp.S index 08795ce..e72d127 100644 --- a/src_partikle/fosa_setjmp.S +++ b/src_partikle/fosa_setjmp.S @@ -61,11 +61,43 @@ .text -.global fosa_long_jump_save_context, fosa_longjmp +.global fosa_long_jump_save_context, fosa_setjmp, fosa_longjmp .type fosa_long_jump_save_context,@function +.type fosa_setjmp,@function .type fosa_longjmp,@function + fosa_long_jump_save_context: + subl $44, %esp + cmpl $0, 48(%esp) + jne .L2 + movl $22, 24(%esp) + jmp .L4 +.L2: + movl 44(%esp), %ecx + leal 48(%esp), %edx + movl 48(%esp), %eax + movl %ebx, 0(%eax) + movl %esi, 4(%eax) + movl %edi, 8(%eax) + movl %ebp, 12(%eax) + movl %edx, 16(%eax) + movl %ecx, 20(%eax) + movl $0, 24(%eax) + + leal 28(%eax), %eax + movl %eax, 8(%esp) + movl $0, 4(%esp) + movl $0, (%esp) + call pthread_sigmask + +.L4: + movl 24(%esp), %eax + addl $44, %esp + ret + + +fosa_setjmp: movl 0(%esp), %ecx leal 4(%esp), %edx movl (%edx), %eax diff --git a/src_partikle/tests/test_long_jump.c b/src_partikle/tests/test_long_jump.c index e4bba65..b9b12d4 100644 --- a/src_partikle/tests/test_long_jump.c +++ b/src_partikle/tests/test_long_jump.c @@ -10,38 +10,57 @@ void f1 (void) fosa_thread_id_t th; int jmp; fosa_signal_info_t ctx_info; + sigset_t s; + pthread_sigmask (SIG_SETMASK, NULL, &s); + printf (">>> Current signal mask = 0x%x\n", (unsigned int) s.sig); printf (">>> save context\n\n"); - if (fosa_long_jump_save_context (&ctx)) - perror ("fosa_long_jump_save_context"); + if (fosa_long_jump_save_context (&ctx)) { + printf ("fosa_long_jump_save_context"); + exit (-1); + } printf (">>> check jump performed\n\n"); - if (fosa_long_jump_was_performed ((const fosa_long_jump_context_t *) &ctx, &jmp)) - perror ("fosa_long_jump_was_performed"); + if (fosa_long_jump_was_performed ((const fosa_long_jump_context_t *) &ctx, &jmp)) { + printf ("fosa_long_jump_was_performed"); + exit (-2); + } if (jmp) { printf ("\t <<<< JUMPED\n\n"); + pthread_sigmask (SIG_SETMASK, NULL, &s); + printf (">>> Current signal mask = 0x%x\n",(unsigned int) s.sig); exit (10); } - + printf (">>> install handler\n\n"); - if (fosa_long_jump_install_handler (&sig, &th)) - perror ("fosa_long_jump_install_handler()"); - + if (fosa_long_jump_install_handler (&sig, &th)) { + printf ("fosa_long_jump_install_handler()"); + exit (-3); + } + printf ("\t signal=%d, thread=0x%x (self=0x%x)\n", sig, (unsigned int) th, (unsigned int) fosa_thread_self()); printf (">>> trigger a long jump using a signal\n\n"); ctx_info.sival_ptr = &ctx; - if (fosa_signal_queue (sig, ctx_info, th)) - perror ("fosa_signal_queue"); - + if (fosa_signal_queue (sig, ctx_info, th)) { + printf ("fosa_signal_queue"); + exit (-4); + } } int main (void) { - f1 (); - return 0; + sigset_t s; + + sigemptyset (&s); + sigaddset (&s, SIGRTMIN); + sigaddset (&s, SIGRTMAX); + pthread_sigmask (SIG_SETMASK, &s, NULL); + + f1 (); + return 0; } -- 2.39.2