Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Aug 2002 13:05:39 -0700 (PDT)
From:      Jonathan Mini <mini@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 16552 for review
Message-ID:  <200208252005.g7PK5d80064166@freefall.freebsd.org>

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

Change 16552 by mini@mini_stylus on 2002/08/25 13:04:59

	Add the concept of being busy (currently in use) to a ucontext_t,
	and make the userland functions obey its constraints.

Affected files ...

.. //depot/projects/kse/lib/libc/gen/swapcontext.c#2 edit
.. //depot/projects/kse/lib/libc/i386/gen/getcontext.S#3 edit
.. //depot/projects/kse/sys/sys/ucontext.h#4 edit

Differences ...

==== //depot/projects/kse/lib/libc/gen/swapcontext.c#2 (text+ko) ====

@@ -30,26 +30,29 @@
 #include <errno.h>
 #include <signal.h>
 #include <stddef.h>
-#include <ucontext.h>
+#include <sys/ucontext.h>
 
 __weak_reference(__swapcontext, swapcontext);
 
 int
 __swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
 {
-	volatile int swapping;
 	int ret;
 
-	if (oucp == NULL || ucp == NULL) {
+
+	if ((oucp == NULL) ||
+	    (oucp->uc_mcontext.mc_len != sizeof(mcontext_t)) ||
+	    (ucp == NULL) ||
+	    (ucp->uc_mcontext.mc_len != sizeof(mcontext_t))) {
 		errno = EINVAL;
-		ret = -1;
-	} else {
-		swapping = 0;
-		ret = getcontext(oucp);
-		if (ret == 0 && swapping == 0) {
-			swapping = 1;
-			ret = setcontext(ucp);
-		}
+		return (-1);
+	}
+	oucp->uc_flags &= ~UCF_SWAPPED;
+	ret = getcontext(oucp);
+	if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) {
+		oucp->uc_flags |= UCF_SWAPPED;
+		oucp->uc_busy = 0;
+		ret = setcontext(ucp);
 	}
 	return (ret);
 }

==== //depot/projects/kse/lib/libc/i386/gen/getcontext.S#3 (text+ko) ====

@@ -32,12 +32,15 @@
  */
 #define	MC_SIZE			640	/* sizeof mcontext_t */
 #define	UC_MC_OFFSET		16	/* offset to mcontext from ucontext */
-#define	UC_FLAGS_OFFSET		208	/* offset to flags from ucontext */
 #define	UC_MC_LEN_OFFSET	96	/* offset to mc_len from mcontext */
+#define	MC_FLAGS_OFFSET		660	/* offset to uc_flags from ucontext */
+#define	MC_BUSY_OFFSET		656	/* offset to uc_busy from ucontext */
 #define	MC_LEN_OFFSET		80	/* offset to mc_len from mcontext */
 #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. */
 
 /*
  * int setcontext(ucontext_t *ucp);
@@ -53,12 +56,14 @@
 	cmpl	$0, %eax		/* check for null pointer */
 	jne	1f
 	movl	$-1, %eax
-	jmp	5f
+	jmp	7f
 1:	cmpl	$MC_SIZE, UC_MC_LEN_OFFSET(%eax) /* is context valid? */
 	jnz	2f
 	movl	$-1, %eax		/* bzzzt, invalid context */
-	jmp	5f
-2:	PIC_PROLOGUE
+	jmp	7f
+2:	testl $UCF_SKIPSIGMASK, MC_FLAGS_OFFSET(%edx)	/* Restore sigmask? */
+	jnz 3f
+	PIC_PROLOGUE
 	pushl	$0			/* oset = NULL */
 	pushl	%eax			/* set = &ucp->uc_sigmask */
 	pushl	$3			/* how = SIG_SETMASK */
@@ -66,8 +71,8 @@
 	addl	$12, %esp
 	PIC_EPILOGUE
 	testl	%eax, %eax		/* check for error */
-	jnz	5f
-	movl	4(%esp), %edx		/* get address of context */
+	jnz	7f
+3:	movl	4(%esp), %edx		/* get address of context */
 	addl	$UC_MC_OFFSET, %edx	/* add offset to mcontext */
 	movl	4(%edx), %gs
 	movl	8(%edx), %fs
@@ -82,18 +87,22 @@
 	movl	60(%edx), %eax		/* put return address at top of stack */
 	movl	%eax, (%esp)
 	cmpl	$0, MC_OWNEDFP_OFFSET(%edx) /* are FP regs valid? */
-	jz	3f
+	jz	4f
 	frstor	MC_FP_REGS_OFFSET(%edx) /* restore FP regs */
-	jmp	4f
-3:	fninit
+	jmp	5f
+4:	fninit
 	fldcw	MC_FP_CW_OFFSET(%edx)
-4:	movl	68(%edx), %eax		/* restore flags register */
-	sahf
-	movl	48(%edx), %eax		/* restore ax, bx, cx, and dx last */
+5:	movl	48(%edx), %eax		/* restore ax, bx, cx */
 	movl	36(%edx), %ebx
 	movl	44(%edx), %ecx
-	movl	40(%edx), %edx
-5:	ret
+	pushl	68(%edx)		/* flags on stack */
+	pushl	40(%edx)		/* %edx on stack  */
+	testl $UCF_OBEYBUSY, MC_FLAGS_OFFSET(%edx)	/* set uc_busy? */
+	jz 6f
+	movl	$1, MC_BUSY_OFFSET(%edx)	/* set uc_busy */
+6:	popl	%edx			/* %edx off stack */
+	popf				/* flags off stack */
+7:	ret
 
 /*
  * int getcontext(ucontext_t *ucp);
@@ -139,24 +148,15 @@
 	movl	%eax, 60(%edx)		/* save return address */
 	movl	%ss, 76(%edx)
 	/*
-	 * XXX - Do we really need to save floating point registers?
+	 * Don't save floating point registers here.
 	 *
 	 * This is an explicit call to get the current context, so
-	 * shouldn't the caller be done with the floating point registers?
+	 * the caller is done with the floating point registers.
 	 * Contexts formed by involuntary switches, such as signal delivery,
-	 * should have floating point registers saved by the kernel.
-	 *
-	 * As of this writing, the kernel doesn't yet save the FPU state
-	 * on signal delivery, so a setcontext on the interrupted context
-	 * may yield incorrect results regardless.
+	 * have floating point registers saved by the kernel.
 	 */
-#if 1
 	fnstcw	MC_FP_CW_OFFSET(%edx)
 	movl	$0, MC_OWNEDFP_OFFSET(%edx) /* no FP */
-#else
-	fnsave	MC_FP_REGS_OFFSET(%edx) /* save FP regs */
-	movl	$MC_FP_VALID, MC_FLAGS_OFFSET(%edx) /* mcontext and FP valid */
-#endif
 	lahf				/* get eflags */
 	movl	%eax, 68(%edx)		/* store eflags */
 	movl	%esp, %eax		/* setcontext pushes the return  */

==== //depot/projects/kse/sys/sys/ucontext.h#4 (text+ko) ====

@@ -47,8 +47,12 @@
 
 	struct __ucontext *uc_link;
 	stack_t		uc_stack;
-	int		uc_busy;
-	int		__spare__[6];
+	intptr_t	uc_busy;
+	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). */
+	int		__spare__[4];
 } ucontext_t;
 
 #ifndef _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?200208252005.g7PK5d80064166>