Date: Tue, 18 Jun 2002 23:21:33 -0700 (PDT) From: Julian Elischer <julian@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 13136 for review Message-ID: <200206190621.g5J6LXi04319@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=13136 Change 13136 by julian@julian_jules1 on 2002/06/18 23:20:34 hey I forgot to check this out.. thus it wasn't checked in.. DOH! Affected files ... ... //depot/projects/kse/sys/kern/kern_thread.c#72 edit Differences ... ==== //depot/projects/kse/sys/kern/kern_thread.c#72 (text+ko) ==== @@ -327,22 +327,20 @@ TAILQ_REMOVE(&kg->kg_threads, td, td_kglist); kg->kg_numthreads--; } -#if 0 + /* + * The test below is NOT true if we are the + * sole exiting thread. P_STOPPED_SNGL is unset + * in exit1() after it is the only survivor. + */ if (P_SHOULDSTOP(p) == P_STOPPED_SNGL) { - if (p->p_numthreads == ((p->p_flag & P_SINGLE_EXIT) ? - 1 : p->p_suspcount)) { + if (p->p_numthreads == p->p_suspcount) { TAILQ_REMOVE(&p->p_suspended, p->p_singlethread, td_runq); setrunqueue(p->p_singlethread); p->suspcount--; } } -#else - thread_unsuspend(p); /* see if it is there yet */ -#endif } - if (kg != NULL) - kg->kg_numthreads--; td->td_state = TDS_SURPLUS; td->td_proc = NULL; td->td_ksegrp = NULL; @@ -426,7 +424,7 @@ * any sleeping threads that are interruptable. (PCATCH). */ int -thread_single(int how) +thread_single(int force_exit) { struct thread *td; struct thread *td2; @@ -447,20 +445,19 @@ return (1); } - if (how == SNGLE_WAIT) + if (force_exit == SNGLE_EXIT) + p->p_flag |= P_SINGLE_EXIT; + else p->p_flag &= ~P_SINGLE_EXIT; - else - p->p_flag |= P_SINGLE_EXIT; p->p_flag |= P_STOPPED_SNGL; p->p_singlethread = td; - while (p->p_numthreads != - ((how == SNGLE_WAIT) ? (p->p_suspcount + 1) : 1 )) { + while ((p->p_numthreads - p->p_suspcount) != 1) { FOREACH_THREAD_IN_PROC(p, td2) { if (td2 == td) continue; switch(td2->td_state) { case TDS_SUSPENDED: - if (how != SNGLE_WAIT) { + if (force_exit == SNGLE_EXIT) { TAILQ_REMOVE(&p->p_suspended, td, td_runq); setrunqueue(td); /* Should suicide. */ @@ -504,20 +501,38 @@ /* * Called in from locations that can safely check to see * whether we have to suspend or at least throttle for a - * single-thread event (e.g. fork), - * Such locations include userret(). The thread must be able to - * return 0 (caller may continue), or 1 (caller must abort). - * The 'how' argument tells the function if it may do a thread_exit() - * or suspend, or whether the caller must abort and back out instead. + * single-thread event (e.g. fork). + * + * Such locations include userret(). + * If the "return_instead" argument is non zero, the thread must be able to + * accept 0 (caller may continue), or 1 (caller must abort) as a result. + * + * The 'return_instead' argument tells the function if it may do a + * thread_exit() or suspend, or whether the caller must abort and back + * out instead. + * + * If the thread that set the single_threading request has set the + * P_SINGLE_EXIT bit in the process flags then this call will never return + * if 'return_instead' is false, but will exit. + * + * P_SINGLE_EXIT | return_instead == 0| return_instead != 0 + *---------------+--------------------+--------------------- + * 0 | returns 0 | returns 0 or 1 + * | when ST ends | immediatly + *---------------+--------------------+--------------------- + * 1 | thread exits | returns 1 + * | | immediatly * 0 = thread_exit() or suspension ok, * other = return error instead of stopping the thread. * * While a full suspension is under effect, even a single threading - * thread will be suspended. (if that makes sense). It may not even - * be possible, but best to define the semantics of what it would mean. + * thread would be suspended if it made this call (but it shouldn't). + * This call should only be made from places where + * thread_exit() would be safe as that may be the outcome unless + * return_instead is set. */ int -thread_suspend_check(int how) +thread_suspend_check(int return_instead) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -526,12 +541,10 @@ p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); while (P_SHOULDSTOP(p)) { - if (how && (td != p->p_singlethread)) { - return (1); - } if (P_SHOULDSTOP(p) == P_STOPPED_SNGL) { KASSERT(p->p_singlethread != NULL, ("singlethread not set")); + /* * The only suspension in action is * a single-threading. Treat it ever @@ -539,36 +552,27 @@ * in a special situation. */ if (p->p_singlethread == td) { - break; /* Exempt from stopping. */ + return (0); /* Exempt from stopping. */ } - /* - * We are called from somewhere that doesn't want - * us to sleep or exit, but to return an error - * instead. - */ - if (how) { - return (1); - } - /* - * If the process is waiting for us to exit, - * this thread should just suicide. - */ - if (p->p_flag & P_SINGLE_EXIT) { - mtx_lock_spin(&sched_lock); - while (mtx_owned(&Giant)) - mtx_unlock(&Giant); - thread_exit(); - } - /* - * Just an optimised version of thread_unsuspend(). - */ - if (p->p_numthreads == (p->p_suspcount + 1)) { - TAILQ_REMOVE(&p->p_suspended, - p->p_singlethread, td_runq); - p->p_suspcount--; - setrunqueue(p->p_singlethread); - } + + } + + if (return_instead) { + return (1); + } + + /* + * If the process is waiting for us to exit, + * this thread should just suicide. + * Assumes that P_SINGLE_EXIT implies P_STOPPED_SNGL. + */ + if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td) { + mtx_lock_spin(&sched_lock); + while (mtx_owned(&Giant)) + mtx_unlock(&Giant); + thread_exit(); } + /* * When a thread suspends, it just * moves to the processes's suspend queue @@ -606,6 +610,7 @@ if (!P_SHOULDSTOP(p)) { while (( td = TAILQ_FIRST(&p->p_suspended))) { TAILQ_REMOVE(&p->p_suspended, td, td_runq); + p->p_suspcount--; setrunqueue(td); } } else if ((P_SHOULDSTOP(p) == P_STOPPED_SNGL) && To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206190621.g5J6LXi04319>