From owner-p4-projects Fri Jun 28 15: 6:36 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 32A1D37B409; Fri, 28 Jun 2002 15:03:36 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AC04437B411 for ; Fri, 28 Jun 2002 15:03:21 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id A574943E16 for ; Fri, 28 Jun 2002 15:02:48 -0700 (PDT) (envelope-from julian@freebsd.org) Received: from freefall.freebsd.org (perforce@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.4/8.12.4) with ESMTP id g5SM2mJU024810 for ; Fri, 28 Jun 2002 15:02:48 -0700 (PDT) (envelope-from julian@freebsd.org) Received: (from perforce@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g5SM2mNN024806 for perforce@freebsd.org; Fri, 28 Jun 2002 15:02:48 -0700 (PDT) Date: Fri, 28 Jun 2002 15:02:48 -0700 (PDT) Message-Id: <200206282202.g5SM2mNN024806@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to julian@freebsd.org using -f From: Julian Elischer Subject: PERFORCE change 13537 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 . * 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