aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);