There are a few places where we will want to reduce a threaded process
down to a single thread. The code in exit1 is a good start. For now,
I'm just pulling it out into a new function. Can also simplify setting
the return value.
Index: kern/kern_exit.c
===================================================================
RCS file: /home/tedu/cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.101
diff -u -p -r1.101 kern_exit.c
--- kern/kern_exit.c 5 Jul 2011 04:48:02 -0000 1.101
+++ kern/kern_exit.c 6 Jul 2011 22:00:22 -0000
@@ -111,28 +111,12 @@ sys_threxit(struct proc *p, void *v, reg
return (0);
}
-/*
- * Exit: deallocate address space and other resources, change proc state
- * to zombie, and unlink proc from allproc and parent's lists. Save exit
- * status and rusage for wait(). Check for child processes and orphan them.
- */
void
-exit1(struct proc *p, int rv, int flags)
+reduce_threads(struct proc *p, int flags)
{
+ struct process *pr = p->p_p;
struct proc *q, *nq;
- struct process *pr, *qr, *nqr;
- if (p->p_pid == 1)
- panic("init died (signal %d, exit %d)",
- WTERMSIG(rv), WEXITSTATUS(rv));
-
- atomic_setbits_int(&p->p_flag, P_WEXIT);
-
- /* unlink ourselves from the active threads */
- pr = p->p_p;
- TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
- if (TAILQ_EMPTY(&pr->ps_threads))
- wakeup(&pr->ps_threads);
/*
* if one thread calls exit, we take down everybody.
* we have to be careful not to get recursively caught.
@@ -144,8 +128,6 @@ exit1(struct proc *p, int rv, int flags)
* we are one of the threads. we SIGKILL the parent,
* it will wake us up again, then we proceed.
*/
- atomic_setbits_int(&pr->ps_mainproc->p_flag, P_IGNEXITRV);
- pr->ps_mainproc->p_xstat = rv;
ptsignal(pr->ps_mainproc, SIGKILL, SPROPAGATED);
tsleep(pr, PUSER, "thrdying", 0);
} else if ((p->p_flag & P_THREAD) == 0) {
@@ -153,8 +135,6 @@ exit1(struct proc *p, int rv, int flags)
q = TAILQ_FIRST(&pr->ps_threads);
for (; q != NULL; q = nq) {
nq = TAILQ_NEXT(q, p_thr_link);
- atomic_setbits_int(&q->p_flag, P_IGNEXITRV);
- q->p_xstat = rv;
ptsignal(q, SIGKILL, SPROPAGATED);
}
}
@@ -172,6 +152,35 @@ exit1(struct proc *p, int rv, int flags)
wakeup(pr->ps_pptr);
}
}
+}
+
+/*
+ * Exit: deallocate address space and other resources, change proc state
+ * to zombie, and unlink proc from allproc and parent's lists. Save exit
+ * status and rusage for wait(). Check for child processes and orphan them.
+ */
+void
+exit1(struct proc *p, int rv, int flags)
+{
+ struct process *pr, *qr, *nqr;
+
+ if (p->p_pid == 1)
+ panic("init died (signal %d, exit %d)",
+ WTERMSIG(rv), WEXITSTATUS(rv));
+
+ atomic_setbits_int(&p->p_flag, P_WEXIT);
+
+ /* unlink ourselves from the active threads */
+ pr = p->p_p;
+ TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
+ if (TAILQ_EMPTY(&pr->ps_threads))
+ wakeup(&pr->ps_threads);
+
+ if (flags == EXIT_NORMAL) {
+ atomic_setbits_int(&pr->ps_mainproc->p_flag, P_IGNEXITRV);
+ pr->ps_mainproc->p_xstat = rv;
+ }
+ reduce_threads(p, flags);
if (p->p_flag & P_PROFIL)
stopprofclock(p);
Index: sys/proc.h
===================================================================
RCS file: /home/tedu/cvs/src/sys/sys/proc.h,v
retrieving revision 1.139
diff -u -p -r1.139 proc.h
--- sys/proc.h 5 Jul 2011 04:48:02 -0000 1.139
+++ sys/proc.h 6 Jul 2011 21:55:54 -0000
@@ -480,6 +480,7 @@ void resetpriority(struct proc *);
void setrunnable(struct proc *);
void unsleep(struct proc *);
void reaper(void);
+void reduce_threads(struct proc *, int);
void exit1(struct proc *, int, int);
void exit2(struct proc *);
void cpu_exit(struct proc *);