transition to using functions for internal signal blocking/restoring
authorRich Felker <dalias@aerifal.cx>
Fri, 26 Apr 2013 23:48:01 +0000 (19:48 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 26 Apr 2013 23:48:01 +0000 (19:48 -0400)
there are several reasons for this change. one is getting rid of the
repetition of the syscall signature all over the place. another is
sharing the constant masks without costly GOT accesses in PIC.

the main motivation, however, is accurately representing whether we
want to block signals that might be handled by the application, or all
signals.

src/internal/pthread_impl.h
src/signal/block.c [new file with mode: 0644]
src/signal/raise.c
src/signal/siglongjmp.c
src/thread/pthread_create.c

index 78b69cde85cee8455c74819d5445d9a98151d1a3..67b0575345eef1b186e6aa7de8734e6a3e5d4fe9 100644 (file)
@@ -115,6 +115,10 @@ void __acquire_ptc();
 void __release_ptc();
 void __inhibit_ptc();
 
+void __block_all_sigs(void *);
+void __block_app_sigs(void *);
+void __restore_sigs(void *);
+
 #define DEFAULT_STACK_SIZE 81920
 #define DEFAULT_GUARD_SIZE PAGE_SIZE
 
diff --git a/src/signal/block.c b/src/signal/block.c
new file mode 100644 (file)
index 0000000..d7f6100
--- /dev/null
@@ -0,0 +1,44 @@
+#include "pthread_impl.h"
+#include "syscall.h"
+#include <signal.h>
+
+static const unsigned long all_mask[] = {
+#if ULONG_MAX == 0xffffffff && _NSIG == 129
+       -1UL, -1UL, -1UL, -1UL
+#elif ULONG_MAX == 0xffffffff
+       -1UL, -1UL
+#else
+       -1UL
+#endif
+};
+
+static const unsigned long app_mask[] = {
+#if ULONG_MAX == 0xffffffff
+#if _NSIG == 65
+       0x7fffffff, 0xfffffffc
+#else
+       0x7fffffff, 0xfffffffc, -1UL, -1UL
+#endif
+#else
+#if _NSIG == 65
+       0xfffffffc7fffffff
+#else
+       0xfffffffc7fffffff, -1UL
+#endif
+#endif
+};
+
+void __block_all_sigs(void *set)
+{
+       __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8);
+}
+
+void __block_app_sigs(void *set)
+{
+       __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8);
+}
+
+void __restore_sigs(void *set)
+{
+       __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8);
+}
index b24dc7417f46131ed8e8d687db75ac9487e85768..6fa43bef97ee1508c23e1dd1328e588ddcf68cf4 100644 (file)
@@ -8,10 +8,10 @@ int raise(int sig)
 {
        int pid, tid, ret;
        sigset_t set;
-       __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET, &set, _NSIG/8);
+       __block_app_sigs(&set);
        tid = __syscall(SYS_gettid);
        pid = __syscall(SYS_getpid);
        ret = syscall(SYS_tgkill, pid, tid, sig);
-       __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, 0, _NSIG/8);
+       __restore_sigs(&set);
        return ret;
 }
index bbdde796bb8f0e8b74bc6ab8d4cb96e19794b767..a7bcca2439e67575c1317bb76e4862d183b58db8 100644 (file)
@@ -2,10 +2,10 @@
 #include <signal.h>
 #include <stdlib.h>
 #include "syscall.h"
+#include "pthread_impl.h"
 
 _Noreturn void siglongjmp(sigjmp_buf buf, int ret)
 {
-       if (buf->__fl) __syscall(SYS_rt_sigprocmask, SIG_SETMASK,
-               buf->__ss, 0, _NSIG/8);
+       if (buf->__fl) __restore_sigs(buf->__ss);
        longjmp(buf->__jb, ret);
 }
index 6e49acdc6bb77389de220d2b91e2227702b8b626..6c841be799b1632917c4b318dc0fa8faf4bd3e3a 100644 (file)
@@ -35,7 +35,7 @@ _Noreturn void pthread_exit(void *result)
         * This is important to ensure that dynamically allocated TLS
         * is not under-allocated/over-committed, and possibly for other
         * reasons as well. */
-       __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET, &set, _NSIG/8);
+       __block_all_sigs(&set);
 
        /* Wait to unlock the kill lock, which governs functions like
         * pthread_kill which target a thread id, until signals have
@@ -51,7 +51,7 @@ _Noreturn void pthread_exit(void *result)
         * stdio cleanup code a consistent state. */
        if (a_fetch_add(&libc.threads_minus_1, -1)==0) {
                libc.threads_minus_1 = 0;
-               __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, 0, _NSIG/8);
+               __restore_sigs(&set);
                exit(0);
        }
 
@@ -94,8 +94,7 @@ static int start(void *p)
                        self->detached = 2;
                        pthread_exit(0);
                }
-               __syscall(SYS_rt_sigprocmask, SIG_SETMASK,
-                       self->sigmask, 0, _NSIG/8);
+               __restore_sigs(self->sigmask);
        }
        if (self->unblock_cancel)
                __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
@@ -202,8 +201,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp
        }
        if (attr._a_sched) {
                do_sched = new->startlock[0] = 1;
-               __syscall(SYS_rt_sigprocmask, SIG_BLOCK,
-                       SIGALL_SET, new->sigmask, _NSIG/8);
+               __block_app_sigs(new->sigmask);
        }
        new->unblock_cancel = self->cancel;
        new->canary = self->canary;
@@ -214,8 +212,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp
        __release_ptc();
 
        if (do_sched) {
-               __syscall(SYS_rt_sigprocmask, SIG_SETMASK,
-                       new->sigmask, 0, _NSIG/8);
+               __restore_sigs(new->sigmask);
        }
 
        if (ret < 0) {