From 179235b38b56f8006e208d42bcff09a0393191b7 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Thu, 4 Apr 2002 15:19:41 +0000 Subject: [PATCH] Optimized the check for unmasked pending signals in CURSIG() using a new inline function sigsetmasked() and a new macro SIGPENDING(). CURSIG() will soon be moved out of the normal path of execution for syscalls and traps. Then its efficiency will be less important but the new interfaces will be useful for checking for unmasked pending signals in more places. Submitted by: luoqi (long ago, in a slightly different form) Assert that sched_lock is not held in CURSIG(). --- sys/kern/kern_sig.c | 10 ++-------- sys/sys/signalvar.h | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 8c75985043a0..bfefd2460def 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -174,16 +174,10 @@ static int sigproptbl[NSIG] = { int CURSIG(struct proc *p) { - sigset_t tmpset; PROC_LOCK_ASSERT(p, MA_OWNED); - if (SIGISEMPTY(p->p_siglist)) - return (0); - tmpset = p->p_siglist; - SIGSETNAND(tmpset, p->p_sigmask); - if (SIGISEMPTY(tmpset) && (p->p_flag & P_TRACED) == 0) - return (0); - return (issignal(p)); + mtx_assert(&sched_lock, MA_NOTOWNED); + return (SIGPENDING(p) ? issignal(p) : 0); } static __inline int diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 19abed3662df..77923c29c89e 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -189,6 +189,29 @@ __sigseteq(sigset_t *set1, sigset_t *set2) #ifdef _KERNEL +/* Return nonzero if process p has an unmasked pending signal. */ +#define SIGPENDING(p) \ + (!SIGISEMPTY((p)->p_siglist) && \ + (!sigsetmasked(&(p)->p_siglist, &(p)->p_sigmask) || \ + (p)->p_flag & P_TRACED)) + +/* + * Return the value of the pseudo-expression ((*set & ~*mask) != 0). This + * is an optimized version of SIGISEMPTY() on a temporary variable + * containing SIGSETNAND(*set, *mask). + */ +static __inline int +sigsetmasked(sigset_t *set, sigset_t *mask) +{ + int i; + + for (i = 0; i < _SIG_WORDS; i++) { + if (set->__bits[i] & ~mask->__bits[i]) + return (0); + } + return (1); +} + struct pgrp; struct thread; struct proc;