Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_trap.c
Show First 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | |||||
* This is relatively easy. | * This is relatively easy. | ||||
* This function will return with preemption disabled. | * This function will return with preemption disabled. | ||||
*/ | */ | ||||
void | void | ||||
ast(struct trapframe *framep) | ast(struct trapframe *framep) | ||||
{ | { | ||||
struct thread *td; | struct thread *td; | ||||
struct proc *p; | struct proc *p; | ||||
int flags; | uint32_t oldval; | ||||
int sig; | int flags, sig; | ||||
td = curthread; | td = curthread; | ||||
p = td->td_proc; | p = td->td_proc; | ||||
CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td, p->p_pid, | CTR3(KTR_SYSC, "ast: thread %p (pid %d, %s)", td, p->p_pid, | ||||
p->p_comm); | p->p_comm); | ||||
KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); | KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); | ||||
WITNESS_WARN(WARN_PANIC, NULL, "Returning to user mode"); | WITNESS_WARN(WARN_PANIC, NULL, "Returning to user mode"); | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | #endif | ||||
/* | /* | ||||
* Check for signals. Unlocked reads of p_pendingcnt or | * Check for signals. Unlocked reads of p_pendingcnt or | ||||
* p_siglist might cause process-directed signal to be handled | * p_siglist might cause process-directed signal to be handled | ||||
* later. | * later. | ||||
*/ | */ | ||||
if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || | if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || | ||||
!SIGISEMPTY(p->p_siglist)) { | !SIGISEMPTY(p->p_siglist)) { | ||||
fetch_fast_sigblock(td); | |||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
mtx_lock(&p->p_sigacts->ps_mtx); | mtx_lock(&p->p_sigacts->ps_mtx); | ||||
while ((sig = cursig(td)) != 0) { | while ((sig = cursig(td)) != 0) { | ||||
KASSERT(sig >= 0, ("sig %d", sig)); | KASSERT(sig >= 0, ("sig %d", sig)); | ||||
postsig(sig); | postsig(sig); | ||||
} | } | ||||
cem: As mentioned above, it seems like this actually schedule all pending signals (not otherwise… | |||||
mtx_unlock(&p->p_sigacts->ps_mtx); | mtx_unlock(&p->p_sigacts->ps_mtx); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
} | } | ||||
/* | |||||
* Handle deferred update of the fast sigblock value, after | |||||
* the postsig() loop was performed. | |||||
*/ | |||||
if (td->td_pflags & TDP_FAST_SIGPENDING) { | |||||
td->td_pflags &= ~TDP_FAST_SIGPENDING; | |||||
oldval = fuword32(td->td_sigblock_ptr); | |||||
if (oldval == -1) { | |||||
fetch_fast_sigblock_failed(td, 0); | |||||
} else { | |||||
oldval |= FAST_SIGBLOCK_PEND; | |||||
if (suword32(td->td_sigblock_ptr, oldval) == -1) | |||||
fetch_fast_sigblock_failed(td, 1); | |||||
else | |||||
td->td_sigblock_val = oldval; | |||||
} | |||||
} | |||||
/* | /* | ||||
* We need to check to see if we have to exit or wait due to a | * We need to check to see if we have to exit or wait due to a | ||||
* single threading requirement or some other STOP condition. | * single threading requirement or some other STOP condition. | ||||
*/ | */ | ||||
if (flags & TDF_NEEDSUSPCHK) { | if (flags & TDF_NEEDSUSPCHK) { | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
thread_suspend_check(0); | thread_suspend_check(0); | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
Show All 21 Lines |
As mentioned above, it seems like this actually schedule all pending signals (not otherwise blocked by td_sigmask) onto td, completely ignoring td_sigblock_val.