Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_sig.c
Show All 25 Lines | |||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include "namespace.h" | #include "namespace.h" | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/types.h> | #include <sys/auxv.h> | ||||
#include <sys/elf.h> | |||||
#include <sys/signalvar.h> | #include <sys/signalvar.h> | ||||
#include <sys/syscall.h> | #include <sys/syscall.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <pthread.h> | #include <pthread.h> | ||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | static const sigset_t _thr_deferset={{ | ||||
0xffffffff}}; | 0xffffffff}}; | ||||
static const sigset_t _thr_maskset={{ | static const sigset_t _thr_maskset={{ | ||||
0xffffffff, | 0xffffffff, | ||||
0xffffffff, | 0xffffffff, | ||||
0xffffffff, | 0xffffffff, | ||||
0xffffffff}}; | 0xffffffff}}; | ||||
void | static void | ||||
_thr_signal_block(struct pthread *curthread) | thr_signal_block_slow(struct pthread *curthread) | ||||
{ | { | ||||
if (curthread->sigblock > 0) { | if (curthread->sigblock > 0) { | ||||
curthread->sigblock++; | curthread->sigblock++; | ||||
return; | return; | ||||
} | } | ||||
__sys_sigprocmask(SIG_BLOCK, &_thr_maskset, &curthread->sigmask); | __sys_sigprocmask(SIG_BLOCK, &_thr_maskset, &curthread->sigmask); | ||||
curthread->sigblock++; | curthread->sigblock++; | ||||
} | } | ||||
void | static void | ||||
_thr_signal_unblock(struct pthread *curthread) | thr_signal_unblock_slow(struct pthread *curthread) | ||||
{ | { | ||||
if (--curthread->sigblock == 0) | if (--curthread->sigblock == 0) | ||||
__sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); | __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); | ||||
} | |||||
static void | |||||
thr_signal_block_fast(struct pthread *curthread) | |||||
{ | |||||
atomic_add_32(&curthread->fsigblock, SIGFASTBLOCK_INC); | |||||
jilles: It would be nice if this mechanism can also replace the userspace signal handler defer… | |||||
Done Inline ActionsI considered this, and I decided that it is not enough to stop redirecting the signal handlers to libthr. libthr needs to delay cancellation while executing signal handlers, in other words, libthr wrappers around syscalls should be made inactive. kib: I considered this, and I decided that it is not enough to stop redirecting the signal handlers… | |||||
Not Done Inline ActionsRight, libthr needs to wrap signal handlers for disabling cancellation and for something related to sigsuspend(2), but the postpone part can probably be replaced by fast sigblock (not in this review though). jilles: Right, libthr needs to wrap signal handlers for disabling cancellation and for something… | |||||
} | |||||
static void | |||||
thr_signal_unblock_fast(struct pthread *curthread) | |||||
{ | |||||
uint32_t oldval; | |||||
oldval = atomic_fetchadd_32(&curthread->fsigblock, -SIGFASTBLOCK_INC); | |||||
if (oldval == (SIGFASTBLOCK_PEND | SIGFASTBLOCK_INC)) | |||||
__sys_sigfastblock(SIGFASTBLOCK_UNBLOCK, NULL); | |||||
} | |||||
static bool fast_sigblock; | |||||
void | |||||
_thr_signal_block(struct pthread *curthread) | |||||
{ | |||||
if (fast_sigblock) | |||||
thr_signal_block_fast(curthread); | |||||
else | |||||
thr_signal_block_slow(curthread); | |||||
} | |||||
void | |||||
_thr_signal_unblock(struct pthread *curthread) | |||||
{ | |||||
if (fast_sigblock) | |||||
thr_signal_unblock_fast(curthread); | |||||
else | |||||
thr_signal_unblock_slow(curthread); | |||||
} | |||||
void | |||||
_thr_signal_block_check_fast(void) | |||||
{ | |||||
int bsdflags, error; | |||||
error = elf_aux_info(AT_BSDFLAGS, &bsdflags, sizeof(bsdflags)); | |||||
if (error != 0) | |||||
return; | |||||
fast_sigblock = (bsdflags & ELF_BSDF_SIGFASTBLK) != 0; | |||||
} | |||||
void | |||||
_thr_signal_block_setup(struct pthread *curthread) | |||||
{ | |||||
if (!fast_sigblock) | |||||
return; | |||||
__sys_sigfastblock(SIGFASTBLOCK_SETPTR, &curthread->fsigblock); | |||||
} | } | ||||
int | int | ||||
_thr_send_sig(struct pthread *thread, int sig) | _thr_send_sig(struct pthread *thread, int sig) | ||||
{ | { | ||||
return thr_kill(thread->tid, sig); | return thr_kill(thread->tid, sig); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 645 Lines • Show Last 20 Lines |
It would be nice if this mechanism can also replace the userspace signal handler defer mechanism, but that need not be in this review.