Skip site navigation (1)Skip section navigation (2)
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>