aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorDavid Xu <davidxu@FreeBSD.org>2006-02-13 03:16:55 +0000
committerDavid Xu <davidxu@FreeBSD.org>2006-02-13 03:16:55 +0000
commitd8267df729802aaef8b14a20ebbf4193b0925588 (patch)
tree2b44d58fb82cd9bbf9b4abef26ee9b14337b552c /sys/kern/kern_sig.c
parent129d4752a0fcbfcba65cff88e2db855d2220c949 (diff)
downloadsrc-d8267df729802aaef8b14a20ebbf4193b0925588.tar.gz
src-d8267df729802aaef8b14a20ebbf4193b0925588.zip
In order to speed up process suspension on MP machine, send IPI to
remote CPU. While here, abstract thread suspension code into a function called sig_suspend_threads, the function is called when a process received a STOP signal.
Notes
Notes: svn path=/head/; revision=155594
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 061fda4e5797..de44a720d89a 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -90,7 +90,8 @@ static char *expand_name(const char *, uid_t, pid_t);
static int killpg1(struct thread *td, int sig, int pgid, int all);
static int issignal(struct thread *p);
static int sigprop(int sig);
-static void tdsigwakeup(struct thread *td, int sig, sig_t action);
+static void tdsigwakeup(struct thread *, int, sig_t);
+static void sig_suspend_threads(struct thread *, struct proc *, int);
static int filt_sigattach(struct knote *kn);
static void filt_sigdetach(struct knote *kn);
static int filt_signal(struct knote *kn, long hint);
@@ -2046,7 +2047,6 @@ do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
{
sig_t action;
sigqueue_t *sigqueue;
- struct thread *td0;
int prop;
struct sigacts *ps;
int ret = 0;
@@ -2276,15 +2276,7 @@ do_tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
p->p_flag |= P_STOPPED_SIG;
p->p_xstat = sig;
mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0) {
- if (TD_IS_SLEEPING(td0) &&
- (td0->td_flags & TDF_SINTR) &&
- !TD_IS_SUSPENDED(td0)) {
- thread_suspend_one(td0);
- } else {
- td0->td_flags |= TDF_ASTPENDING;
- }
- }
+ sig_suspend_threads(td, p, 1);
if (p->p_numthreads == p->p_suspcount) {
/*
* only thread sending signal to another
@@ -2397,11 +2389,34 @@ tdsigwakeup(struct thread *td, int sig, sig_t action)
}
}
+static void
+sig_suspend_threads(struct thread *td, struct proc *p, int sending)
+{
+ struct thread *td2;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ mtx_assert(&sched_lock, MA_OWNED);
+
+ FOREACH_THREAD_IN_PROC(p, td2) {
+ if ((TD_IS_SLEEPING(td2) || TD_IS_SWAPPED(td2)) &&
+ (td2->td_flags & TDF_SINTR) &&
+ !TD_IS_SUSPENDED(td2)) {
+ thread_suspend_one(td2);
+ } else {
+ if (sending || td != td2)
+ td2->td_flags |= TDF_ASTPENDING;
+#ifdef SMP
+ if (TD_IS_RUNNING(td2) && td2 != td)
+ forward_signal(td2);
+#endif
+ }
+ }
+}
+
int
ptracestop(struct thread *td, int sig)
{
struct proc *p = td->td_proc;
- struct thread *td0;
PROC_LOCK_ASSERT(p, MA_OWNED);
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK,
@@ -2426,15 +2441,7 @@ ptracestop(struct thread *td, int sig)
p->p_xthread = td;
p->p_flag |= (P_STOPPED_SIG|P_STOPPED_TRACE);
mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0) {
- if (TD_IS_SLEEPING(td0) &&
- (td0->td_flags & TDF_SINTR) &&
- !TD_IS_SUSPENDED(td0)) {
- thread_suspend_one(td0);
- } else if (td != td0) {
- td0->td_flags |= TDF_ASTPENDING;
- }
- }
+ sig_suspend_threads(td, p, 0);
stopme:
thread_stopped(p);
thread_suspend_one(td);
@@ -2476,7 +2483,6 @@ issignal(td)
struct sigacts *ps;
sigset_t sigpending;
int sig, prop, newsig;
- struct thread *td0;
p = td->td_proc;
ps = p->p_sigacts;
@@ -2602,15 +2608,7 @@ issignal(td)
p->p_flag |= P_STOPPED_SIG;
p->p_xstat = sig;
mtx_lock_spin(&sched_lock);
- FOREACH_THREAD_IN_PROC(p, td0) {
- if (TD_IS_SLEEPING(td0) &&
- (td0->td_flags & TDF_SINTR) &&
- !TD_IS_SUSPENDED(td0)) {
- thread_suspend_one(td0);
- } else if (td != td0) {
- td0->td_flags |= TDF_ASTPENDING;
- }
- }
+ sig_suspend_threads(td, p, 0);
thread_stopped(p);
thread_suspend_one(td);
PROC_UNLOCK(p);