Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Aug 2002 14:53:34 -0700 (PDT)
From:      Jonathan Mini <mini@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 16871 for review
Message-ID:  <200208312153.g7VLrYd9023540@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/types.h>
@@ -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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208312153.g7VLrYd9023540>