aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-04-25 00:01:32 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-05-03 16:13:47 +0000
commit15465a2c25cc2915e8c7c65178805b10e339dde3 (patch)
treefe317f6cdc885b38f0dc6cc16a6d8762769b83d2
parent86ffb3d1a0cbb09ba0123ff8d34149e691b461c4 (diff)
downloadsrc-15465a2c25cc2915e8c7c65178805b10e339dde3.tar.gz
src-15465a2c25cc2915e8c7c65178805b10e339dde3.zip
Add sleepq_remove_nested()
The helper removes the thread from a sleep queue, assuming that it would need to sleep. The sleepq_remove_nested() function is intended for quite special case, where suspended thread from traced stopped process is temporary unsuspended to do some work on behalf of the debugger in the target context, and this work might require sleep. Reviewed by: markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D29955
-rw-r--r--sys/kern/subr_sleepqueue.c20
-rw-r--r--sys/sys/sleepqueue.h1
2 files changed, 21 insertions, 0 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index 20ca455480b5..0718f01fa48a 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -854,6 +854,26 @@ sleepq_remove_thread(struct sleepqueue *sq, struct thread *td)
(void *)td, (long)td->td_proc->p_pid, td->td_name);
}
+void
+sleepq_remove_nested(struct thread *td)
+{
+ struct sleepqueue_chain *sc;
+ struct sleepqueue *sq;
+ const void *wchan;
+
+ MPASS(TD_ON_SLEEPQ(td));
+
+ wchan = td->td_wchan;
+ sc = SC_LOOKUP(wchan);
+ mtx_lock_spin(&sc->sc_lock);
+ sq = sleepq_lookup(wchan);
+ MPASS(sq != NULL);
+ thread_lock(td);
+ sleepq_remove_thread(sq, td);
+ mtx_unlock_spin(&sc->sc_lock);
+ /* Returns with the thread lock owned. */
+}
+
#ifdef INVARIANTS
/*
* UMA zone item deallocator.
diff --git a/sys/sys/sleepqueue.h b/sys/sys/sleepqueue.h
index ba2f85f2c8a1..18c7568777b6 100644
--- a/sys/sys/sleepqueue.h
+++ b/sys/sys/sleepqueue.h
@@ -100,6 +100,7 @@ void sleepq_release(const void *wchan);
void sleepq_remove(struct thread *td, const void *wchan);
int sleepq_remove_matching(struct sleepqueue *sq, int queue,
bool (*matches)(struct thread *), int pri);
+void sleepq_remove_nested(struct thread *td);
int sleepq_signal(const void *wchan, int flags, int pri, int queue);
void sleepq_set_timeout_sbt(const void *wchan, sbintime_t sbt,
sbintime_t pr, int flags);