From owner-p4-projects Wed Sep 4 3:42:11 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id EBA0C37B401; Wed, 4 Sep 2002 03:41:34 -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 2723F37B400 for ; Wed, 4 Sep 2002 03:41:34 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id A91E943E3B for ; Wed, 4 Sep 2002 03:41:33 -0700 (PDT) (envelope-from mini@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 g84AfUJU017964 for ; Wed, 4 Sep 2002 03:41:31 -0700 (PDT) (envelope-from mini@freebsd.org) Received: (from perforce@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g84AfU1q017939 for perforce@freebsd.org; Wed, 4 Sep 2002 03:41:30 -0700 (PDT) Date: Wed, 4 Sep 2002 03:41:30 -0700 (PDT) Message-Id: <200209041041.g84AfU1q017939@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to mini@freebsd.org using -f From: Jonathan Mini Subject: PERFORCE change 17036 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=17036 Change 17036 by mini@mini_stylus on 2002/09/04 03:41:30 - Convert back from a ucontext_t for UTS context in the kse_mailbox to a function pointer and a stack_t. - Synthesize machine state from scratch on each upcall, but only set up the minimum amount of state. - Discard the UTS state in kse_yield(). - Use a custom MI wrapper function to handle the user context switch into a thread from the UTS. - Once again, only kse_mailbox.ke_curthread acts as a critical section marker. - Move tm_context and km_curthread to the top of their structs, because it makes the assembly less messy when switching user contexts. - The UTS is now a run-once-per-upcall flow, instead of a loop around swapcontext(). - Clarify a few comments. Affected files ... .. //depot/projects/kse/sys/i386/i386/vm_machdep.c#64 edit .. //depot/projects/kse/sys/kern/kern_proc.c#81 edit .. //depot/projects/kse/sys/kern/kern_thread.c#100 edit .. //depot/projects/kse/sys/sys/kse.h#18 edit .. //depot/projects/kse/sys/sys/proc.h#126 edit .. //depot/projects/kse/tools/KSE/uts/Makefile#2 edit .. //depot/projects/kse/tools/KSE/uts/context.S#1 add .. //depot/projects/kse/tools/KSE/uts/uts.c#6 edit Differences ... ==== //depot/projects/kse/sys/i386/i386/vm_machdep.c#64 (text+ko) ==== @@ -368,6 +368,30 @@ pcb2->pcb_ext = NULL; } +/* + * Set the machine state for performing an upcall that had to + * wait until we selected a KSE to perform the upcall on. + */ +void +cpu_set_upcall_kse(struct thread *td, struct kse *ke) +{ + + /* + * Set the trap frame to point at the beginning of the uts + * function. + */ + td->td_frame->tf_esp = + (int)ke->ke_stack.ss_sp + ke->ke_stack.ss_size - 16; + td->td_frame->tf_eip = (int)ke->ke_upcall; + + /* + * Pass the address of the mailbox for this kse to the uts + * function as a parameter on the stack. + */ + suword((void *)(td->td_frame->tf_esp + sizeof(void *)), + (int)ke->ke_mailbox); +} + void cpu_wait(p) struct proc *p; ==== //depot/projects/kse/sys/kern/kern_proc.c#81 (text+ko) ==== @@ -279,22 +279,6 @@ int kse_yield(struct thread *td, struct kse_yield_args *uap) { - int error; - ucontext_t uc; - struct kse *ke; - - /* Save UTS context. */ - ke = td->td_kse; - if (ke == NULL) - return (EFAULT); - error = copyin(&ke->ke_mailbox->km_context, &uc, sizeof(ucontext_t)); - if (error) - return (error); - thread_getcontext(td, &uc); - uc.uc_busy = 0; - error = copyout(&uc, &ke->ke_mailbox->km_context, sizeof(ucontext_t)); - if (error) - return (error); /* Abandon thread. */ PROC_LOCK(td->td_proc); @@ -363,6 +347,8 @@ mi_switch(); /* Save current registers to PCB. */ mtx_unlock_spin(&sched_lock); newkse->ke_mailbox = uap->mbx; + newkse->ke_upcall = mbx.km_func; + bcopy(&mbx.km_stack, &newkse->ke_stack, sizeof(stack_t)); /* Note that we are the returning syscall */ td->td_retval[0] = 0; td->td_retval[1] = 0; ==== //depot/projects/kse/sys/kern/kern_thread.c#100 (text+ko) ==== @@ -549,16 +549,6 @@ */ discard = 1; - /* Make sure the KSE's UTS context is free for use. */ - if (fuword(&ke->ke_mailbox->km_context.uc_busy) != 0) - /* - * The KSE's UTS context is currently marked busy. This - * means the UTS is currently running, so switch to it - * instead of performing another upcall (abandon this - * thread). - */ - discard = 1; - /* Discard thread or mark for upcall. */ if (discard) { /* @@ -605,7 +595,6 @@ struct thread *td, struct trapframe *frame) { int error; - ucontext_t uc; /* * Ensure that we have a spare thread available. @@ -642,10 +631,9 @@ td, p->p_pid, p->p_comm); /* - * Fetch the current UTS context from userland. + * Set user context to the UTS. */ - error = copyin(&ke->ke_mailbox->km_context, &uc, - sizeof(ucontext_t)); + cpu_set_upcall_kse(td, ke); if (error) /* * Failing to do the KSE operation just defaults @@ -655,21 +643,6 @@ goto cont; /* - * Set user context to the UTS's. - * - * XXX - Add the busy marker to thread_setcontext(). - */ - error = thread_setcontext(td, &uc); - if (error) - /* - * Failing to do the KSE operation just defaults - * back to synchonous operation, so just return from - * the syscall. - */ - goto cont; - suword(&ke->ke_mailbox->km_context.uc_busy, (intptr_t)td); - - /* * Set state and mailbox. */ td->td_flags &= ~TDF_UPCALLING; ==== //depot/projects/kse/sys/sys/kse.h#18 (text+ko) ==== @@ -47,12 +47,12 @@ /* * Thread mailbox. * - * This describes a user thread ot the kernel scheduler. + * This describes a user thread to the kernel scheduler. */ struct thread_mailbox { + ucontext_t tm_context; /* User and machine context */ unsigned int tm_flags; /* Thread flags */ struct thread_mailbox *tm_next; /* Next thread in list */ - ucontext_t tm_context; /* User and machine context */ void *tm_udata; /* For use by the UTS */ int tm_spare[8]; }; @@ -64,12 +64,12 @@ * a single KSE. */ struct kse_mailbox { - unsigned int km_flags; /* KSE flags */ -#define KSEKMF_CRITICAL 0x00000001 - ucontext_t km_context; /* UTS context */ struct thread_mailbox *km_curthread; /* Currently running thread */ struct thread_mailbox *km_completed; /* Threads back from kernel */ sigset_t km_sigscaught; /* Caught signals */ + unsigned int km_flags; /* KSE flags */ + void *km_func; /* UTS function */ + stack_t km_stack; /* UTS context */ void *km_udata; /* For use by the UTS */ int tm_spare[8]; }; ==== //depot/projects/kse/sys/sys/proc.h#126 (text+ko) ==== @@ -373,6 +373,8 @@ KES_THREAD /* slaved to thread state */ } ke_state; /* (j) S* process status. */ struct kse_mailbox *ke_mailbox; /* the userland mailbox address */ + stack_t ke_stack; + void *ke_upcall; struct thread *ke_tdspare; /* spare thread for upcalls */ #define ke_endzero ke_dummy char ke_dummy; @@ -835,6 +837,7 @@ struct thread *thread_alloc(void); void thread_free(struct thread *td); void cpu_set_upcall(struct thread *td, void *pcb); +void cpu_set_upcall_kse(struct thread *td, struct kse *ke); void cpu_thread_exit(struct thread *); void cpu_thread_setup(struct thread *td); void kse_reassign(struct kse *ke); ==== //depot/projects/kse/tools/KSE/uts/Makefile#2 (text+ko) ==== @@ -1,5 +1,6 @@ PROG= uts NOMAN= CFLAGS+= -g +SRCS= context.S uts.c .include ==== //depot/projects/kse/tools/KSE/uts/uts.c#6 (text+ko) ==== @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/kse/tools/KSE/uts/uts.c#5 $ + * $P4: //depot/projects/kse/tools/KSE/uts/uts.c#6 $ */ #include @@ -39,10 +39,12 @@ #include #include +#undef TRACE_UTS + #ifdef TRACE_UTS #define UPFMT(fmt...) pfmt(#fmt) #define UPSTR(s) pstr(s) -#define UPCHAR(c) pchar(s) +#define UPCHAR(c) pchar(c) #else #define UPFMT(fmt...) /* Nothing. */ #define UPSTR(s) /* Nothing. */ @@ -54,6 +56,7 @@ static struct kse_mailbox uts_mb; static struct thread_mailbox *run_queue; +static struct thread_mailbox *aa; static int progress = 0; @@ -64,12 +67,19 @@ static void runq_insert(struct thread_mailbox *tm); static struct thread_mailbox *runq_remove(void); static void thread_start(const void *func); -static void uts(void); +static void uts(struct kse_mailbox *km); + +extern int uts_to_thread(struct thread_mailbox *tdp, struct thread_mailbox **curthreadp); + +static void +foof(int sig) +{ + pfmt("%d", sig); +} void aaaa(void) { - progress++; for (;;) { pchar('.'); sleep(1); @@ -94,7 +104,7 @@ // thread_start(spin); init_uts(); for (i = 0;1;i++) { - progress++; + if (i) progress++; pchar('a' + (i % 26)); sleep(5); } @@ -120,7 +130,7 @@ /* Throw us into its context. */ getcontext(&tm->tm_context); - tm->tm_context.uc_flags = UCF_SKIPSIGMASK | UCF_OBEYBUSY; + tm->tm_context.uc_flags = UCF_SKIPSIGMASK; /* Find our stack. */ mib[0] = CTL_KERN; @@ -134,19 +144,15 @@ tm->tm_context.uc_stack.ss_size = MAIN_STACK_SIZE; /* - * Create UTS context. + * Create KSE mailbox. */ + p = (char *)malloc(THREAD_STACK_SIZE); bzero(&uts_mb, sizeof(struct kse_mailbox)); - getcontext(&uts_mb.km_context); - p = (char *)malloc(THREAD_STACK_SIZE); - uts_mb.km_context.uc_stack.ss_sp = p; - uts_mb.km_context.uc_stack.ss_size = THREAD_STACK_SIZE; - makecontext(&uts_mb.km_context, uts, 1); - uts_mb.km_context.uc_flags = UCF_SKIPSIGMASK | UCF_OBEYBUSY; - pfmt("ucontext at : 0x%x\n", &uts_mb.km_context); - pfmt("mcontext mc_len : %d (%d)\n", - uts_mb.km_context.uc_mcontext.mc_len, sizeof(mcontext_t)); + uts_mb.km_stack.ss_sp = p; + uts_mb.km_stack.ss_size = THREAD_STACK_SIZE; + uts_mb.km_func = (void *)uts; pfmt("uts() at : 0x%x\n", uts); + pfmt("uts stack at : 0x%x - 0x%x\n", p, p + THREAD_STACK_SIZE); /* * Start KSE scheduling. @@ -270,53 +276,60 @@ * Userland thread scheduler. */ static void -uts(void) +uts(struct kse_mailbox *km) { struct thread_mailbox *tm, *p; int ret; UPSTR("\n--uts() start--\n"); - for (;;) { - UPFMT("km_curthread -> 0x%x\n", uts_mb.km_curthread); + UPFMT("mailbox -> %x\n", km); + + /* + * Insert any processes back from being blocked + * in the kernel into the run queue. + */ + p = km->km_completed; + uts_mb.km_completed = NULL; + UPFMT("km_completed -> 0x%x", p); + while ((tm = p) != NULL) { + p = tm->tm_next; + UPFMT(" 0x%x", p); + runq_insert(tm); + } + UPCHAR('\n'); + + /* + * Process any signals we've recieved. + */ + /* XXX: Not yet. */ - /* - * Insert any processes back from being blocked - * in the kernel into the run queue. - */ - p = uts_mb.km_completed; - uts_mb.km_completed = NULL; - UPFMT("km_completed -> 0x%x", p); - while ((tm = p) != NULL) { - p = tm->tm_next; - UPFMT(" 0x%x", p); - runq_insert(tm); - } - UPCHAR('\n'); + /* + * Pull a thread off the run queue. + */ + p = runq_remove(); +#if 0 + if ((p == aa) && (progress > 0)) { + --progress; + signalcontext(&p->tm_context, 1, foof); + } +#endif - /* - * Pull a process off the run queue. - */ - p = runq_remove(); - if (p != NULL) { - UPFMT("\n-- uts() scheduling 0x%x--\n", p); - UPFMT("eip -> 0x%x progress -> %d\n", - p->tm_context.uc_mcontext.mc_eip, progress); - if ((p->tm_context.uc_flags & UCF_CRITICAL) == 0) - p->tm_context.uc_flags |= - UCF_CRITICAL | UCF_CLEARSTATE; - uts_mb.km_curthread = p; - UPSTR("curthread set\n"); - ret = swapcontext(&uts_mb.km_context, &p->tm_context); - UPFMT("\n-- uts() back from swapcontext() [%d] --\n", - ret); - if (ret) - /* - * Invalid thread context. Exit. - */ - exit(ret); - } else - kse_yield(); + /* + * Either schedule a thread, or idle if none ready to run. + */ + if (p != NULL) { + UPFMT("\n-- uts() scheduling 0x%x--\n", p); + UPFMT("eip -> 0x%x progress -> %d\n", + p->tm_context.uc_mcontext.mc_eip, progress); + if ((p->tm_context.uc_flags & UCF_CRITICAL) == 0) + p->tm_context.uc_flags |= + UCF_CRITICAL | UCF_CLEARSTATE; + uts_mb.km_curthread = p; + UPSTR("curthread set\n"); + uts_to_thread(p, &km->km_curthread); + UPSTR("\n-- uts_to_thread() failed --\n"); } + kse_yield(); pstr("** uts() exiting **\n"); exit(EX_SOFTWARE); } @@ -330,13 +343,14 @@ struct thread_mailbox *tm; char *p; - tm = (struct thread_mailbox *)calloc(1, sizeof(struct thread_mailbox)); - pfmt("thread_start() : 0x%x\n", tm); + aa = tm = (struct thread_mailbox *)calloc(1, sizeof(struct thread_mailbox)); + pfmt("thread_start() : 0x%x %x\n", tm, &aa->tm_context); getcontext(&tm->tm_context); p = (char *)malloc(THREAD_STACK_SIZE); tm->tm_context.uc_stack.ss_sp = p; tm->tm_context.uc_stack.ss_size = THREAD_STACK_SIZE; makecontext(&tm->tm_context, func, 1); - tm->tm_context.uc_flags = UCF_SKIPSIGMASK | UCF_OBEYBUSY; + tm->tm_context.uc_flags = UCF_SKIPSIGMASK; + // setcontext(&tm->tm_context); runq_insert(tm); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message