summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_kse.c3
-rw-r--r--sys/kern/kern_thread.c40
-rw-r--r--sys/sys/proc.h1
3 files changed, 28 insertions, 16 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c
index 85732da..7ed6380 100644
--- a/sys/kern/kern_kse.c
+++ b/sys/kern/kern_kse.c
@@ -347,8 +347,7 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
* One possibility is to return to the user. It may not cope well.
* The other possibility would be to let the process exit.
*/
- p->p_flag &= ~(P_SA|P_HADTHREADS);
- sched_set_concurrency(td->td_ksegrp, 1);
+ thread_unthread(td);
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
#if 1
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index b853520..28dcb13 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -709,6 +709,29 @@ thread_link(struct thread *td, struct ksegrp *kg)
}
/*
+ * Convert a process with one thread to an unthreaded process.
+ * Called from:
+ * thread_single(exit) (called from execve and exit)
+ * kse_exit() XXX may need cleaning up wrt KSE stuff
+ */
+void
+thread_unthread(struct thread *td)
+{
+ struct proc *p = td->td_proc;
+
+ KASSERT((p->p_numthreads == 1), ("Unthreading with >1 threads"));
+ upcall_remove(td);
+ p->p_flag &= ~(P_SA|P_HADTHREADS);
+ td->td_mailbox = NULL;
+ td->td_pflags &= ~(TDP_SA | TDP_CAN_UNBIND);
+ if (td->td_standin != NULL) {
+ thread_stash(td->td_standin);
+ td->td_standin = NULL;
+ }
+ sched_set_concurrency(td->td_ksegrp, 1);
+}
+
+/*
* Called from:
* thread_exit()
*/
@@ -835,21 +858,11 @@ thread_single(int force_exit)
* we try our utmost to revert to being a non-threaded
* process.
*/
- upcall_remove(td);
- p->p_flag &= ~(P_SA|P_HADTHREADS);
- td->td_mailbox = NULL;
- td->td_pflags &= ~(TDP_SA | TDP_CAN_UNBIND);
- p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT);
p->p_singlethread = NULL;
- if (td->td_standin != NULL) {
- thread_stash(td->td_standin);
- td->td_standin = NULL;
- }
- sched_set_concurrency(td->td_ksegrp, 1);
- mtx_unlock_spin(&sched_lock);
- } else {
- mtx_unlock_spin(&sched_lock);
+ p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT);
+ thread_unthread(td);
}
+ mtx_unlock_spin(&sched_lock);
return (0);
}
@@ -1004,7 +1017,6 @@ thread_unsuspend(struct proc *p)
/*
* End the single threading mode..
- * Part of this is duplicated in thread-single in the SINGLE_EXIT case.
*/
void
thread_single_end(void)
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 9d75c92..cdaa8f5 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -915,6 +915,7 @@ void thread_unlink(struct thread *td);
void thread_unsuspend(struct proc *p);
void thread_unsuspend_one(struct thread *td);
int thread_upcall_check(struct thread *td);
+void thread_unthread(struct thread *td);
int thread_userret(struct thread *td, struct trapframe *frame);
void thread_user_enter(struct thread *td);
void thread_wait(struct proc *p);
OpenPOWER on IntegriCloud