Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming.threads > #953

Re: Using sigsetjmp/siglongjmp from multithreaded application

From "Ersek, Laszlo" <lacos@caesar.elte.hu>
Newsgroups comp.programming.threads
Subject Re: Using sigsetjmp/siglongjmp from multithreaded application
Date 2012-07-21 03:32 +0200
Organization A noiseless patient Spider
Message-ID <alpine.DEB.2.00.1207210158050.1155@login01.caesar.elte.hu> (permalink)
References <be95cec9-1c3a-492a-a3bb-a58f409b648e@googlegroups.com>

Show all headers | View raw


On Fri, 20 Jul 2012, Michael Podolsky wrote:

> to my disappointment I found that there is no straightforward solution 
> to associate a sigjmp_buf buffer with a particular thread.

I'm not sure if it's a good idea, but I can think of three hacks:


(1) 
<http://gcc.gnu.org/onlinedocs/gcc/Thread_002dLocal.html#Thread_002dLocal>


(2) 
<http://pubs.opengroup.org/onlinepubs/000095399/functions/sigaltstack.html> 
<http://pubs.opengroup.org/onlinepubs/000095399/functions/sigaction.html>

(I'm referencing v3 of the SUS on purpose, because I think it might be 
better supported in practice.)

     #define _XOPEN_SOURCE 600

     #include <signal.h>
     #include <stdlib.h>
     #include <setjmp.h>


     static char unsigned *stacks;
     static sigjmp_buf *bufs;


     static void
     handler(int);


     static void
     main_setup(size_t num_threads)
     {
       struct sigaction sa;

       stacks = malloc(num_threads * SIGSTKSZ);
       bufs = malloc(num_threads * sizeof *bufs);

       sa.sa_handler = &handler;
       if (-1 == sigemptyset(&sa.sa_mask)) {
         abort();
       }
       sa.sa_flags = SA_ONSTACK;
       if (-1 == sigaction(SIGSEGV, &sa, 0)) {
         abort();
       }
     }


     static void
     thread_setup(unsigned my_id)
     {
       stack_t stk;

       stk.ss_sp = stacks + my_id * SIGSTKSZ;
       stk.ss_size = SIGSTKSZ;
       stk.ss_flags = 0;

       if (-1 == sigaltstack(&stk, 0)) {
         abort();
       }
     }


     static void
     handler(int signo)
     {
       stack_t stk;
       size_t my_id;

       if (-1 == sigaltstack(0, &stk) || 0 == (stk.ss_flags & SS_ONSTACK)) {
         abort();
       }
       my_id = ((char unsigned *)stk.ss_sp - stacks) / SIGSTKSZ;
       siglongjmp(bufs[my_id], 1);
       abort();
     }

(sigaltstack() is not listed as async signal safe, but I'm not sure how 
SS_ONSTACK can make sense otherwise.)

(3)

     #define _XOPEN_SOURCE 600

     #include <signal.h>
     #include <stdlib.h>
     #include <setjmp.h>
     #include <pthread.h>
     #include <ucontext.h>


     static void **sps;
     static sigjmp_buf *bufs;
     static pthread_barrier_t init;


     static void
     handler(int, siginfo_t *, void *);


     static void
     main_setup(size_t num_threads)
     {
       struct sigaction sa;

       sps = malloc((num_threads + 1u) * sizeof *sps);
       sps[num_threads] = 0;

       bufs = malloc(num_threads * sizeof *bufs);

       if (-1 == sigemptyset(&sa.sa_mask)) {
         abort();
       }
       sa.sa_flags = SA_SIGINFO;
       sa.sa_sigaction = handler;
       if (-1 == sigaction(SIGSEGV, &sa, 0)) {
         abort();
       }

       if (-1 == pthread_barrier_init(&init, 0, num_threads)) {
         abort();
       }
     }


     static void
     thread_setup(unsigned my_id)
     {
       ucontext_t context;

       getcontext(&context);
       sps[my_id] = context.uc_stack.ss_sp;
       pthread_barrier_wait(&init);
     }


     static void
     handler(int signo, siginfo_t *info, void *context)
     {
       void *my_sp;
       size_t my_id;

       my_sp = ((ucontext_t *)context)->uc_stack.ss_sp;
       for (my_id = 0; 0 != sps[my_id]; ++my_id) {
         if (sps[my_id] == my_sp) {
           siglongjmp(bufs[my_id], 1);
         }
       }
       abort();
     }



Laszlo

Back to comp.programming.threads | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Using sigsetjmp/siglongjmp from multithreaded application Michael Podolsky <michael.podolsky.69@gmail.com> - 2012-07-20 14:42 -0700
  Re: Using sigsetjmp/siglongjmp from multithreaded application "Ersek, Laszlo" <lacos@caesar.elte.hu> - 2012-07-21 03:32 +0200
    Re: Using sigsetjmp/siglongjmp from multithreaded application "Ersek, Laszlo" <lacos@caesar.elte.hu> - 2012-07-21 04:05 +0200
      Re: Using sigsetjmp/siglongjmp from multithreaded application Michael Podolsky <michael.podolsky.69@gmail.com> - 2012-07-24 10:22 -0700
        Re: Using sigsetjmp/siglongjmp from multithreaded application "Ersek, Laszlo" <lacos@caesar.elte.hu> - 2012-07-25 03:28 +0200
  Re: Using sigsetjmp/siglongjmp from multithreaded application Marcel Müller <news.5.maazl@spamgourmet.com> - 2012-07-21 09:10 +0200
    Re: Using sigsetjmp/siglongjmp from multithreaded application Michael Podolsky <michael.podolsky.69@gmail.com> - 2012-07-24 10:34 -0700
      Re: Using sigsetjmp/siglongjmp from multithreaded application Marcel Müller <news.5.maazl@spamgourmet.com> - 2012-07-24 22:58 +0200
        Re: Using sigsetjmp/siglongjmp from multithreaded application Drazen Kacar <dave@fly.srk.fer.hr> - 2012-07-24 21:23 +0000
        Re: Using sigsetjmp/siglongjmp from multithreaded application Michael Podolsky <michael.podolsky.69@gmail.com> - 2012-07-24 15:48 -0700

csiph-web