summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2002-04-04 15:19:41 +0000
committerbde <bde@FreeBSD.org>2002-04-04 15:19:41 +0000
commit3b8182ff404d880440c6a41d8b8496f765081777 (patch)
treefe0f65124fa6da5af3eb9a5b24516923f9f48da8 /sys
parent0de93566db10d6dcabfa9d11c5c20f30047475a8 (diff)
downloadFreeBSD-src-3b8182ff404d880440c6a41d8b8496f765081777.zip
FreeBSD-src-3b8182ff404d880440c6a41d8b8496f765081777.tar.gz
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().
Diffstat (limited to 'sys')
-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