Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Jun 2002 15:02:48 -0700 (PDT)
From:      Julian Elischer <julian@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 13537 for review
Message-ID:  <200206282202.g5SM2mNN024806@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=13537

Change 13537 by julian@julian_ref on 2002/06/28 15:02:33

	Extract some KSE specific code into a function for diff-reduction.

Affected files ...

.. //depot/projects/kse/sys/kern/kern_thread.c#80 edit
.. //depot/projects/kse/sys/kern/subr_trap.c#72 edit
.. //depot/projects/kse/sys/sys/proc.h#117 edit

Differences ...

==== //depot/projects/kse/sys/kern/kern_thread.c#80 (text+ko) ====

@@ -1,4 +1,4 @@
-/*
+/* 
  * Copyright (C) 2001 Julian Elischer <julian@freebsd.org>.
  *  All rights reserved.
  *
@@ -419,6 +419,138 @@
 }
 
 /*
+ * The extra work we go through if we are a threaded process when we 
+ * return to userland
+ */
+int
+thread_userret(struct proc *p, struct ksegrp *kg, struct kse *ke,
+    struct thread *td, struct trapframe *frame)
+{
+	int error = 0;
+
+	if (ke->ke_tdspare == NULL) {
+		mtx_lock(&Giant);
+		ke->ke_tdspare = thread_alloc();
+		mtx_unlock(&Giant);
+	}
+	if (td->td_flags & TDF_UNBOUND) {
+		/*
+		 * Are we returning from a thread that had a mailbox?
+		 *
+		 * XXX Maybe this should be in a separate function.
+		 */
+		if (((td->td_flags & TDF_UPCALLING) == 0) && td->td_mailbox) {
+			/*
+			 * [XXXKSE Future enhancement]
+			 * We could also go straight back to the syscall
+			 * if we never had to do an upcall since then.
+			 * If the KSE's copy is == the thread's copy..
+			 * AND there are no other completed threads.
+			 */
+			/*
+			 * We will go back as an upcall or go do another thread.
+			 * Either way we need to save the context back to
+			 * the user thread mailbox.
+			 * So the UTS can restart it later.
+			 */
+			error = thread_export_context(td);
+			td->td_mailbox = NULL;
+			if (error) {
+				/*
+				 * Failing to do the KSE
+				 * operation just defaults operation
+				 * back to synchonous operation.
+				 */
+				goto cont;
+			}
+
+			if (TAILQ_FIRST(&kg->kg_runq)) {
+				/*
+				 * Uh-oh.. don't return to the user.
+				 * Instead, switch to the thread that
+				 * needs to run. The question is:
+				 * What do we do with the thread we have now?
+				 * We have put the completion block
+				 * on the kse mailbox. If we had more energy,
+				 * we could lazily do so, assuming someone
+				 * else might get to userland earlier
+				 * and deliver it earlier than we could.
+				 * To do that we could save it off the KSEG.
+				 * An upcalling KSE would 'reap' all completed
+				 * threads.
+				 * Being in a hurry, we'll do nothing and
+				 * leave it on the current KSE for now.
+				 *
+				 * As for the other threads to run;
+				 * we COULD rush through all the threads
+				 * in this KSEG at this priority, or we
+				 * could throw the ball back into the court
+				 * and just run the highest prio kse available.
+				 * What is OUR priority?
+				 * the priority of the highest sycall waiting
+				 * to be returned?
+				 * For now, just let another KSE run (easiest).
+				 */
+				PROC_LOCK(p);
+				mtx_lock_spin(&sched_lock);
+				thread_exit(); /* Abandon current thread. */
+				/* NOTREACHED */
+			} else { /* if (number of returning syscalls = 1) */
+				/*
+				 * Swap our frame for the upcall frame.
+				 *
+				 * XXXKSE Assumes we are going to user land
+				 * and not nested in the kernel
+				 */
+				td->td_flags |= TDF_UPCALLING;
+			}
+		}
+		/*
+		 * This is NOT just an 'else' clause for the above test...
+		 */
+		if (td->td_flags & TDF_UPCALLING) {
+			CTR3(KTR_PROC, "userret: upcall thread %p (pid %d, %s)",
+			    td, p->p_pid, p->p_comm);
+			/*
+			 * Make sure that it has the correct frame loaded.
+			 * While we know that we are on the same KSEGRP
+			 * as we were created on, we could very easily
+			 * have come in on another KSE. We therefore need
+			 * to do the copy of the frame after the last
+			 * possible switch() (the one above).
+			 */
+			bcopy(ke->ke_frame, frame, sizeof(struct trapframe));
+
+			/*
+			 * Decide what we are sending to the user
+			 * upcall sets one argument. The address of the mbox.
+			 */
+			cpu_set_args(td, ke);
+
+			/*
+			 * There is no more work to do and we are going to ride
+			 * this thead/KSE up to userland. Make sure the user's
+			 * pointer to the thread mailbox is cleared before we
+			 * re-enter the kernel next time for any reason..
+			 * We might as well do it here.
+			 */
+			td->td_flags &= ~TDF_UPCALLING;	/* Hmmmm. */
+			error = suword((caddr_t)td->td_kse->ke_mailbox +
+			    offsetof(struct kse_mailbox, kmbx_current_thread),
+			    0);
+		}
+		/*
+		 * Stop any chance that we may be separated from
+		 * the KSE we are currently on. This is "biting the bullet",
+		 * we are committing to go to user space as as THIS KSE here.
+		 */
+cont:
+		td->td_flags &= ~TDF_UNBOUND;
+	}
+	return (error);
+}
+
+/*
  * Enforce single-threading.
  *
  * Returns 1 if the caller must abort (another thread is waiting to

==== //depot/projects/kse/sys/kern/subr_trap.c#72 (text+ko) ====

@@ -72,7 +72,6 @@
 	struct proc *p = td->td_proc;
 	struct kse *ke = td->td_kse; 
 	struct ksegrp *kg = td->td_ksegrp;
-	int error;
 
 	CTR3(KTR_SYSC, "userret: thread %p (pid %d, %s)", td, p->p_pid,
             p->p_comm);
@@ -82,7 +81,7 @@
 	PROC_LOCK(p);
 	mtx_lock_spin(&sched_lock);
 	if (SIGPENDING(p) && ((p->p_sflag & PS_NEEDSIGCHK) == 0 ||
-	    (p->p_kse.ke_flags & KEF_ASTPENDING) == 0))
+	    (ke->ke_flags & KEF_ASTPENDING) == 0))
 		printf("failed to set signal flags proprly for ast()\n");
 	mtx_unlock_spin(&sched_lock);
 	PROC_UNLOCK(p);
@@ -118,127 +117,10 @@
 	thread_suspend_check(0);	/* Can suspend or kill */
 	PROC_UNLOCK(p);
 	if (p->p_flag & P_KSES) {
-		if (ke->ke_tdspare == NULL) {
-			mtx_lock(&Giant);
-			ke->ke_tdspare = thread_alloc();
-			mtx_unlock(&Giant);
-		}
+		thread_userret(p, kg, ke, td, frame);
+		/* printf("KSE thread returned"); */
 	}
-	if (td->td_flags & TDF_UNBOUND) {
-		/*
-		 * Are we returning from a thread that had a mailbox?
-		 *
-		 * XXX Maybe this should be in a separate function.
-		 */
-		if (((td->td_flags & TDF_UPCALLING) == 0) && td->td_mailbox) {
-			/*
-			 * [XXXKSE Future enhancement]
-			 * We could also go straight back to the syscall
-			 * if we never had to do an upcall since then.
-			 * If the KSE's copy is == the thread's copy..
-			 * AND there are no other completed threads.
-			 */
-			/*
-			 * We will go back as an upcall or go do another thread.
-			 * Either way we need to save the context back to
-			 * the user thread mailbox.
-			 * So the UTS can restart it later.
-			 */
-			error = thread_export_context(td);
-			td->td_mailbox = NULL;
-			if (error) {
-				/*
-				 * Failing to do the KSE
-				 * operation just defaults operation
-				 * back to synchonous operation.
-				 */
-				goto cont;
-			}
 
-			if (TAILQ_FIRST(&kg->kg_runq)) {
-				/*
-				 * Uh-oh.. don't return to the user.
-				 * Instead, switch to the thread that
-				 * needs to run. The question is:
-				 * What do we do with the thread we have now?
-				 * We have put the completion block
-				 * on the kse mailbox. If we had more energy,
-				 * we could lazily do so, assuming someone
-				 * else might get to userland earlier
-				 * and deliver it earlier than we could.
-				 * To do that we could save it off the KSEG.
-				 * An upcalling KSE would 'reap' all completed
-				 * threads.
-				 * Being in a hurry, we'll do nothing and
-				 * leave it on the current KSE for now.
-				 *
-				 * As for the other threads to run;
-				 * we COULD rush through all the threads
-				 * in this KSEG at this priority, or we
-				 * could throw the ball back into the court
-				 * and just run the highest prio kse available.
-				 * What is OUR priority?
-				 * the priority of the highest sycall waiting
-				 * to be returned?
-				 * For now, just let another KSE run (easiest).
-				 */
-				PROC_LOCK(p);
-				mtx_lock_spin(&sched_lock);
-				thread_exit(); /* Abandon current thread. */
-				/* NOTREACHED */
-			} else { /* if (number of returning syscalls = 1) */
-				/*
-				 * Swap our frame for the upcall frame.
-				 *
-				 * XXXKSE Assumes we are going to user land
-				 * and not nested in the kernel
-				 */
-				td->td_flags |= TDF_UPCALLING;
-			}
-		}
-		/*
-		 * This is NOT just an 'else' clause for the above test...
-		 */
-		if (td->td_flags & TDF_UPCALLING) {
-			CTR3(KTR_PROC, "userret: upcall thread %p (pid %d, %s)",
-			    td, p->p_pid, p->p_comm);
-			/*
-			 * Make sure that it has the correct frame loaded.
-			 * While we know that we are on the same KSEGRP
-			 * as we were created on, we could very easily
-			 * have come in on another KSE. We therefore need
-			 * to do the copy of the frame after the last
-			 * possible switch() (the one above).
-			 */
-			bcopy(ke->ke_frame, frame, sizeof(struct trapframe));
-
-			/*
-			 * Decide what we are sending to the user
-			 * upcall sets one argument. The address of the mbox.
-			 */
-			cpu_set_args(td, ke);
-
-			/*
-			 * There is no more work to do and we are going to ride
-			 * this thead/KSE up to userland. Make sure the user's
-			 * pointer to the thread mailbox is cleared before we
-			 * re-enter the kernel next time for any reason..
-			 * We might as well do it here.
-			 */
-			td->td_flags &= ~TDF_UPCALLING;	/* Hmmmm. */
-			error = suword((caddr_t)td->td_kse->ke_mailbox +
-			    offsetof(struct kse_mailbox, kmbx_current_thread),
-			    0);
-		}
-		/*
-		 * Stop any chance that we may be separated from
-		 * the KSE we are currently on. This is "biting the bullet",
-		 * we are committing to go to user space as as THIS KSE here.
-		 */
-cont:
-		td->td_flags &= ~TDF_UNBOUND;
-	}
-
 	/*
 	 * Charge system time if profiling.
 	 *
@@ -261,8 +143,7 @@
  * This function will return with preemption disabled.
  */
 void
-ast(framep)
-	struct trapframe *framep;
+ast(struct trapframe *framep)
 {
 	struct thread *td = curthread;
 	struct proc *p = td->td_proc;

==== //depot/projects/kse/sys/sys/proc.h#117 (text+ko) ====

@@ -856,6 +856,8 @@
 void	thread_stash(struct thread *td);
 int	thread_suspend_check(int how);
 void	thread_unsuspend(struct proc *p);
+int	thread_userret(struct proc *p, struct ksegrp *kg, struct kse *ke,
+	    struct thread *td, struct trapframe *frame);
 
 void	thread_sanity_check(struct thread *td);
 #endif	/* _KERNEL */

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?200206282202.g5SM2mNN024806>