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:
parent
55d884db38
commit
179235b38b
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user