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().
This commit is contained in:
Bruce Evans 2002-04-04 15:19:41 +00:00
parent 55d884db38
commit 179235b38b
2 changed files with 25 additions and 8 deletions

View File

@ -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

View File

@ -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;