From owner-p4-projects Sat Aug 31 14:53:58 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6B07237B401; Sat, 31 Aug 2002 14:53: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 B942337B400 for ; Sat, 31 Aug 2002 14:53:35 -0700 (PDT) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id DA1A643E3B for ; Sat, 31 Aug 2002 14:53:34 -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 g7VLrYJU023543 for ; Sat, 31 Aug 2002 14:53:34 -0700 (PDT) (envelope-from mini@freebsd.org) Received: (from perforce@localhost) by freefall.freebsd.org (8.12.4/8.12.4/Submit) id g7VLrYd9023540 for perforce@freebsd.org; Sat, 31 Aug 2002 14:53:34 -0700 (PDT) Date: Sat, 31 Aug 2002 14:53:34 -0700 (PDT) Message-Id: <200208312153.g7VLrYd9023540@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to mini@freebsd.org using -f From: Jonathan Mini Subject: PERFORCE change 16871 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=16871 Change 16871 by mini@mini_stylus on 2002/08/31 14:53:33 - Make ke_mailbox a pointer to the right type, so we can use -> instead of offsetof() to perform address calculations. - Add a UCF_CRITICAL flag to denote critical sections in a ucontext. - Split flags in to options and states, and add the option UCF_CLEARSTATE to request that setcontext() clear the state flags when entering the context. - Change the context-switch method from the UTS to a thread to mark itself as a critical section, swap into the section, and unset the critical flag at the last moment before jumping into the new context's code. Now we needn't fear entering the kernel at any time during the UTS's operation, including swapping contexts. Affected files ... .. //depot/projects/kse/lib/libc/i386/gen/getcontext.S#5 edit .. //depot/projects/kse/sys/kern/kern_thread.c#95 edit .. //depot/projects/kse/sys/sys/proc.h#124 edit .. //depot/projects/kse/sys/sys/ucontext.h#5 edit .. //depot/projects/kse/tools/KSE/uts/uts.c#3 edit Differences ... ==== //depot/projects/kse/lib/libc/i386/gen/getcontext.S#5 (text+ko) ==== @@ -40,8 +40,14 @@ #define MC_FP_REGS_OFFSET 96 /* offset to FP regs from mcontext */ #define MC_FP_CW_OFFSET 96 /* offset to FP control word */ #define MC_OWNEDFP_OFFSET 88 /* offset to mc_ownedfp from mcontext */ -#define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ -#define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ +#define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ +#define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ +#define UCF_CLEARSTATE 0x00000004 /* Clear UCF_STATE in setcontext. */ +#define UCF_SWAPPED 0x00000100 /* Used by swapcontext(3). */ +#define UCF_CRITICAL 0x00000200 /* In a critical section. */ +#define UCF_STATE 0x0000ff00 /* State-related flags. */ +#define UCF_OPTIONS 0x000000ff /* Behaviour-related flags. */ + /* * int setcontext(ucontext_t *ucp); @@ -57,11 +63,11 @@ cmpl $0, %eax /* check for null pointer */ jne 1f movl $-1, %eax - jmp 7f + jmp 8f 1: cmpl $MC_SIZE, UC_MC_LEN_OFFSET(%eax) /* is context valid? */ je 2f movl $-1, %eax /* bzzzt, invalid context */ - jmp 7f + jmp 8f 2: testl $UCF_SKIPSIGMASK, UC_FLAGS_OFFSET(%eax) /* Restore sigmask? */ jnz 3f PIC_PROLOGUE @@ -72,7 +78,7 @@ addl $12, %esp PIC_EPILOGUE testl %eax, %eax /* check for error */ - jnz 7f + jnz 8f 3: movl 4(%esp), %edx /* get address of context */ addl $UC_MC_OFFSET, %edx /* add offset to mcontext */ movl 4(%edx), %gs @@ -98,12 +104,15 @@ movl 44(%edx), %ecx pushl 68(%edx) /* flags on stack */ pushl 40(%edx) /* %edx on stack */ - testl $UCF_OBEYBUSY, MC_FLAGS_OFFSET(%edx) /* set uc_busy? */ + testl $UCF_CLEARSTATE, MC_FLAGS_OFFSET(%edx) /* clear flag state? */ jz 6f + andl $UCF_OPTIONS, MX_FLAGS_OFFSET(%edx) +6: testl $UCF_OBEYBUSY, MC_FLAGS_OFFSET(%edx) /* set uc_busy? */ + jz 7f movl $1, MC_BUSY_OFFSET(%edx) /* set uc_busy */ -6: popl %edx /* %edx off stack */ +7: popl %edx /* %edx off stack */ popf /* flags off stack */ -7: ret +8: ret /* * int getcontext(ucontext_t *ucp); ==== //depot/projects/kse/sys/kern/kern_thread.c#95 (text+ko) ==== @@ -501,6 +501,15 @@ struct thread *td, struct trapframe *frame) { int discard, error; + struct thread_mailbox *tmp; + + /* + * If we are in a critical section, return to this thread. + */ + tmp = (struct thread_mailbox *)fuword(&ke->ke_mailbox->km_curthread); + if ((tmp != NULL) && + (fuword(&tmp->tm_context.uc_flags) & UCF_CRITICAL)) + return (0); /* * Save the thread's context, and link it @@ -517,7 +526,7 @@ return (error); /* - * Second, decide whether to perfom an upcall now. + * Decide whether to perfom an upcall now. */ discard = 0; @@ -540,9 +549,7 @@ discard = 1; /* Make sure the KSE's UTS context is free for use. */ - if (fuword((caddr_t)ke->ke_mailbox + - offsetof(struct kse_mailbox, km_context) + - offsetof(ucontext_t, uc_busy)) != 0) + 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 @@ -597,22 +604,19 @@ struct thread *td, struct trapframe *frame) { int error; - caddr_t ucp; ucontext_t uc; /* * Ensure that we have a spare thread available. */ - if (ke->ke_tdspare == NULL) { + if (ke->ke_tdspare == NULL) ke->ke_tdspare = thread_alloc(); - } /* * Bound threads need no additional work. */ - if ((td->td_flags & TDF_UNBOUND) == 0) { + if ((td->td_flags & TDF_UNBOUND) == 0) return (0); - } error = 0; /* @@ -639,9 +643,8 @@ /* * Fetch the current UTS context from userland. */ - ucp = (caddr_t)ke->ke_mailbox + - offsetof(struct kse_mailbox, km_context); - error = copyin(ucp, &uc, sizeof(ucontext_t)); + error = copyin(&ke->ke_mailbox->km_context, &uc, + sizeof(ucontext_t)); if (error) /* * Failing to do the KSE operation just defaults @@ -655,8 +658,15 @@ * * XXX - Add the busy marker to thread_setcontext(). */ - thread_setcontext(td, &uc); - suword(ucp + offsetof(ucontext_t, uc_busy), (intptr_t)td); + 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. ==== //depot/projects/kse/sys/sys/proc.h#124 (text+ko) ==== @@ -372,7 +372,7 @@ KES_UNQUEUED, /* in transit */ KES_THREAD /* slaved to thread state */ } ke_state; /* (j) S* process status. */ - void *ke_mailbox; /* the userland mailbox address */ + struct kse_mailbox *ke_mailbox; /* the userland mailbox address */ struct thread *ke_tdspare; /* spare thread for upcalls */ #define ke_endzero ke_dummy char ke_dummy; ==== //depot/projects/kse/sys/sys/ucontext.h#5 (text+ko) ==== @@ -51,7 +51,11 @@ int uc_flags; #define UCF_SKIPSIGMASK 0x00000001 /* Don't set/restore signal mask. */ #define UCF_OBEYBUSY 0x00000002 /* Respect uc_busy marker. */ -#define UCF_SWAPPED 0x00000004 /* Used by swapcontext(3). */ +#define UCF_CLEARSTATE 0x00000004 /* Clear UCF_STATE in setcontext. */ +#define UCF_SWAPPED 0x00000100 /* Used by swapcontext(3). */ +#define UCF_CRITICAL 0x00000200 /* In a critical section. */ +#define UCF_STATE 0x0000ff00 /* State-related flags. */ +#define UCF_OPTIONS 0x000000ff /* Behaviour-related flags. */ int __spare__[4]; } ucontext_t; ==== //depot/projects/kse/tools/KSE/uts/uts.c#3 (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#2 $ + * $P4: //depot/projects/kse/tools/KSE/uts/uts.c#3 $ */ #include @@ -287,6 +287,10 @@ pfmt("-- uts() scheduling 0x%x--\n", p); pfmt("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; pstr("curthread set\n"); ret = myswapcontext(&uts_mb.km_context, &p->tm_context, p); @@ -344,7 +348,6 @@ ret = getcontext(oucp); if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) { oucp->uc_flags |= UCF_SWAPPED; - uts_mb.km_curthread = p; oucp->uc_busy = 0; ret = setcontext(ucp); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message