Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Aug 2002 15:02:02 -0700 (PDT)
From:      Julian Elischer <julian@elischer.org>
To:        Jonathan Mini <mini@FreeBSD.org>
Cc:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   Re: PERFORCE change 16871 for review
Message-ID:  <Pine.BSF.4.21.0208311500150.5605-100000@InterJet.elischer.org>
In-Reply-To: <200208312153.g7VLrYd9023540@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
sounds good, but I'd apreciate a 3 or 4 paragraph description of what you
are doing as it varies a little from what we discussed..

pitty you aren't in the bay area any more..
A whiteboard would be good... 

On Sat, 31 Aug 2002, Jonathan Mini wrote:

> 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?Pine.BSF.4.21.0208311500150.5605-100000>