summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_sig.c10
-rw-r--r--sys/sys/signalvar.h23
2 files changed, 25 insertions, 8 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 8c75985..bfefd24 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 19abed3..77923c2 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;
OpenPOWER on IntegriCloud