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>