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 *);

Reply via email to