On Thu, 10 Apr 2014, Philip Guenther wrote:
> I'll float a diff later when I have a chance to test things, but I think 
> the solution for now will be to change the condition on the 
> while()tsleep() loop that the main thread blocks on and to move the 
> wakeup().

Here's the diff I'm poking at, though I haven't had a chance to do 
systrace and other tests yet.

Philip


Index: kern/kern_exit.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.138
diff -u -p -r1.138 kern_exit.c
--- kern/kern_exit.c    30 Mar 2014 21:54:48 -0000      1.138
+++ kern/kern_exit.c    11 Apr 2014 06:42:28 -0000
@@ -158,12 +158,10 @@ exit1(struct proc *p, int rv, int flags)
        TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
        if ((p->p_flag & P_THREAD) == 0) {
                /* main thread gotta wait because it has the pid, et al */
-               while (!TAILQ_EMPTY(&pr->ps_threads))
+               while (pr->ps_refcnt > 1)
                        tsleep(&pr->ps_threads, PUSER, "thrdeath", 0);
                if (pr->ps_flags & PS_PROFIL)
                        stopprofclock(pr);
-       } else if (TAILQ_EMPTY(&pr->ps_threads)) {
-               wakeup(&pr->ps_threads);
        }
 
        rup = pr->ps_ru;
@@ -356,7 +354,8 @@ exit1(struct proc *p, int rv, int flags)
        /* just a thread? detach it from its process */
        if (p->p_flag & P_THREAD) {
                /* scheduler_wait_hook(pr->ps_mainproc, p); XXX */
-               --pr->ps_refcnt;
+               if (--pr->ps_refcnt == 1)
+                       wakeup(&pr->ps_threads);
                KASSERT(pr->ps_refcnt > 0);
        }

Reply via email to