aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2021-04-24 11:47:53 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2021-05-03 16:13:47 +0000
commitaf928fded0705100e4f3926c99ed488f7ab6dcf1 (patch)
treedf72bf71e1ebdc902bd12156d40d07c0b23d48f2
parent15465a2c25cc2915e8c7c65178805b10e339dde3 (diff)
downloadsrc-af928fded0705100e4f3926c99ed488f7ab6dcf1.tar.gz
src-af928fded0705100e4f3926c99ed488f7ab6dcf1.zip
Add thread_run_flash() helper
It unsuspends single suspended thread, passed as the argument. It is up to the caller to arrange the target thread to suspend later, since the state of the process is not changed from stopped. In particular, the unsuspended thread must not leave to userspace, since boundary code is not prepared to this situation. 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/kern_thread.c25
-rw-r--r--sys/sys/proc.h1
2 files changed, 26 insertions, 0 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index ea569576e7c9..d5549baa6ad5 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -1514,6 +1514,31 @@ thread_unsuspend_one(struct thread *td, struct proc *p, bool boundary)
return (setrunnable(td, 0));
}
+void
+thread_run_flash(struct thread *td)
+{
+ struct proc *p;
+
+ p = td->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ if (TD_ON_SLEEPQ(td))
+ sleepq_remove_nested(td);
+ else
+ thread_lock(td);
+
+ THREAD_LOCK_ASSERT(td, MA_OWNED);
+ KASSERT(TD_IS_SUSPENDED(td), ("Thread not suspended"));
+
+ TD_CLR_SUSPENDED(td);
+ PROC_SLOCK(p);
+ MPASS(p->p_suspcount > 0);
+ p->p_suspcount--;
+ PROC_SUNLOCK(p);
+ if (setrunnable(td, 0))
+ kick_proc0();
+}
+
/*
* Allow all threads blocked by single threading to continue running.
*/
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index b82de183aa44..a078b859ddc1 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1191,6 +1191,7 @@ void thread_stopped(struct proc *p);
void childproc_stopped(struct proc *child, int reason);
void childproc_continued(struct proc *child);
void childproc_exited(struct proc *child);
+void thread_run_flash(struct thread *td);
int thread_suspend_check(int how);
bool thread_suspend_check_needed(void);
void thread_suspend_switch(struct thread *, struct proc *p);