Move futex support code from <arch>/support.s into linux compat directory.
Implement all futex atomic operations in assembler to not depend on the fuword() that does not allow to distinguish between -1 and failure return. Correctly return 0 from atomic operations on success. In collaboration with: rdivacky Tested by: Scot Hetzel <swhetzel gmail com>, Milos Vyletel <mvyletel mzm cz> Sponsored by: Google SoC 2007
This commit is contained in:
parent
253a9fb8b6
commit
cdee790df9
@ -671,49 +671,6 @@ ENTRY(longjmp)
|
||||
incl %eax
|
||||
ret
|
||||
|
||||
/*****************************************************************************/
|
||||
/* linux_futex support */
|
||||
/*****************************************************************************/
|
||||
|
||||
futex_fault:
|
||||
movq $0,PCB_ONFAULT(%rcx)
|
||||
movq $-EFAULT,%rax
|
||||
ret
|
||||
|
||||
ENTRY(futex_xchgl)
|
||||
movq PCPU(CURPCB),%rcx
|
||||
movq $futex_fault,PCB_ONFAULT(%rcx)
|
||||
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xchgl %edi,(%rsi)
|
||||
movl %edi,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%rcx)
|
||||
ret
|
||||
|
||||
ENTRY(futex_addl)
|
||||
movq PCPU(CURPCB),%rcx
|
||||
movq $futex_fault,PCB_ONFAULT(%rcx)
|
||||
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xaddl %edi,(%rsi)
|
||||
movl %edi,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%rcx)
|
||||
ret
|
||||
|
||||
/*
|
||||
* Support for BB-profiling (gcc -a). The kernbb program will extract
|
||||
* the data from the kernel.
|
||||
|
124
sys/amd64/linux32/linux32_support.s
Normal file
124
sys/amd64/linux32/linux32_support.s
Normal file
@ -0,0 +1,124 @@
|
||||
/*-
|
||||
* Copyright (c) 2007 Konstantin Belousov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "linux32_assym.h" /* system definitions */
|
||||
#include <machine/asmacros.h> /* miscellaneous asm macros */
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
futex_fault:
|
||||
movq $0,PCB_ONFAULT(%r8)
|
||||
movl $-EFAULT,%eax
|
||||
ret
|
||||
|
||||
ENTRY(futex_xchgl)
|
||||
movq PCPU(CURPCB),%r8
|
||||
movq $futex_fault,PCB_ONFAULT(%r8)
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
xchgl %edi,(%rsi)
|
||||
movl %edi,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%r8)
|
||||
ret
|
||||
|
||||
ENTRY(futex_addl)
|
||||
movq PCPU(CURPCB),%r8
|
||||
movq $futex_fault,PCB_ONFAULT(%r8)
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xaddl %edi,(%rsi)
|
||||
movl %edi,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%r8)
|
||||
ret
|
||||
|
||||
ENTRY(futex_orl)
|
||||
movq PCPU(CURPCB),%r8
|
||||
movq $futex_fault,PCB_ONFAULT(%r8)
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
movl (%rsi),%eax
|
||||
1: movl %eax,%ecx
|
||||
orl %edi,%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%rsi)
|
||||
jnz 1b
|
||||
movl %eax,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%r8)
|
||||
ret
|
||||
|
||||
ENTRY(futex_andl)
|
||||
movq PCPU(CURPCB),%r8
|
||||
movq $futex_fault,PCB_ONFAULT(%r8)
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
movl (%rsi),%eax
|
||||
1: movl %eax,%ecx
|
||||
andl %edi,%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%rsi)
|
||||
jnz 1b
|
||||
movl %eax,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%r8)
|
||||
ret
|
||||
|
||||
ENTRY(futex_xorl)
|
||||
movq PCPU(CURPCB),%r8
|
||||
movq $futex_fault,PCB_ONFAULT(%r8)
|
||||
movq $VM_MAXUSER_ADDRESS-4,%rax
|
||||
cmpq %rax,%rsi
|
||||
ja futex_fault
|
||||
movl (%rsi),%eax
|
||||
1: movl %eax,%ecx
|
||||
xorl %edi,%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%rsi)
|
||||
jnz 1b
|
||||
movl %eax,(%rdx)
|
||||
xorl %eax,%eax
|
||||
movq %rax,PCB_ONFAULT(%r8)
|
||||
ret
|
@ -90,13 +90,13 @@ static void futex_put(struct futex *);
|
||||
static int futex_sleep(struct futex *, struct thread *, unsigned long);
|
||||
static int futex_wake(struct futex *, int, struct futex *, int);
|
||||
static int futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr);
|
||||
static int futex_orl(int oparg, caddr_t uaddr, int *oldval);
|
||||
static int futex_andl(int oparg, caddr_t uaddr, int *oldval);
|
||||
static int futex_xorl(int oparg, caddr_t uaddr, int *oldval);
|
||||
|
||||
/* support.s */
|
||||
int futex_xchgl(int oparg, caddr_t uaddr, int *oldval);
|
||||
int futex_addl(int oparg, caddr_t uaddr, int *oldval);
|
||||
int futex_orl(int oparg, caddr_t uaddr, int *oldval);
|
||||
int futex_andl(int oparg, caddr_t uaddr, int *oldval);
|
||||
int futex_xorl(int oparg, caddr_t uaddr, int *oldval);
|
||||
|
||||
int
|
||||
linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
@ -114,8 +114,8 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(sys_futex))
|
||||
printf(ARGS(futex, "%p, %i, %i"), args->uaddr, args->op,
|
||||
args->val);
|
||||
printf(ARGS(futex, "%p, %i, %i, *, %p, %i"), args->uaddr, args->op,
|
||||
args->val, args->uaddr2, args->val3);
|
||||
#endif
|
||||
|
||||
switch (args->op) {
|
||||
@ -274,7 +274,7 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
#ifdef DEBUG
|
||||
if (ldebug(sys_futex))
|
||||
printf("FUTEX_WAKE_OP: %d: uaddr = %p, op = %d, "
|
||||
"val = %d, uaddr2 = %p, val3 = %d\n",
|
||||
"val = %x, uaddr2 = %p, val3 = %x\n",
|
||||
td->td_proc->p_pid, args->uaddr, args->op,
|
||||
args->val, args->uaddr2, args->val3);
|
||||
#endif
|
||||
@ -286,8 +286,11 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
* negative as errors
|
||||
*/
|
||||
op_ret = futex_atomic_op(td, args->val3, args->uaddr2);
|
||||
#ifdef DEBUG
|
||||
if (ldebug(sys_futex))
|
||||
printf("futex_atomic_op ret %d\n", op_ret);
|
||||
#endif
|
||||
if (op_ret < 0) {
|
||||
|
||||
/* XXX: We don't handle the EFAULT yet. */
|
||||
if (op_ret != -EFAULT) {
|
||||
futex_put(f);
|
||||
@ -301,7 +304,6 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
|
||||
FUTEX_SYSTEM_UNLOCK;
|
||||
return (EFAULT);
|
||||
|
||||
}
|
||||
|
||||
ret = futex_wake(f, args->val, NULL, 0);
|
||||
@ -327,7 +329,7 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
|
||||
args->op);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct futex *
|
||||
@ -401,9 +403,12 @@ futex_sleep(struct futex *f, struct thread *td, unsigned long timeout)
|
||||
TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list);
|
||||
FUTEX_UNLOCK;
|
||||
|
||||
/* if we got woken up in futex_wake */
|
||||
if ((ret == 0) && (wp->wp_new_futex != NULL)) {
|
||||
/* suspend us on the new futex */
|
||||
ret = futex_sleep(wp->wp_new_futex, td, timeout);
|
||||
futex_put(wp->wp_new_futex); /* futex_get called in wakeup */
|
||||
/* and release the old one */
|
||||
futex_put(wp->wp_new_futex);
|
||||
}
|
||||
|
||||
free(wp, M_LINUX);
|
||||
@ -458,8 +463,10 @@ futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr)
|
||||
oparg = 1 << oparg;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("futex_atomic_op: op = %d, cmp = %d, oparg = %d, cmparg = %d, "
|
||||
"uaddr = %p\n", op, cmp, oparg, cmparg, uaddr);
|
||||
if (ldebug(sys_futex))
|
||||
printf("futex_atomic_op: op = %d, cmp = %d, oparg = %x, "
|
||||
"cmparg = %x, uaddr = %p\n",
|
||||
op, cmp, oparg, cmparg, uaddr);
|
||||
#endif
|
||||
/* XXX: linux verifies access here and returns EFAULT */
|
||||
|
||||
@ -481,70 +488,26 @@ futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr)
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
ret = (oldval == cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_NE:
|
||||
ret = (oldval != cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LT:
|
||||
ret = (oldval < cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GE:
|
||||
ret = (oldval >= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_LE:
|
||||
ret = (oldval <= cmparg);
|
||||
break;
|
||||
case FUTEX_OP_CMP_GT:
|
||||
ret = (oldval > cmparg);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
}
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
futex_orl(int oparg, caddr_t uaddr, int *oldval)
|
||||
{
|
||||
uint32_t ua, ua_old;
|
||||
|
||||
for (;;) {
|
||||
ua = ua_old = fuword32(uaddr);
|
||||
ua |= oparg;
|
||||
if (casuword32((void *)uaddr, ua_old, ua) == ua_old)
|
||||
return ua_old;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
futex_andl(int oparg, caddr_t uaddr, int *oldval)
|
||||
{
|
||||
uint32_t ua, ua_old;
|
||||
|
||||
for (;;) {
|
||||
ua = ua_old = fuword32(uaddr);
|
||||
ua &= oparg;
|
||||
if (casuword32((void *)uaddr, ua_old, ua) == ua_old)
|
||||
return ua_old;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
futex_xorl(int oparg, caddr_t uaddr, int *oldval)
|
||||
{
|
||||
uint32_t ua, ua_old;
|
||||
|
||||
for (;;) {
|
||||
ua = ua_old = fuword32(uaddr);
|
||||
ua ^= oparg;
|
||||
if (casuword32((void *)uaddr, ua_old, ua) == ua_old)
|
||||
return ua_old;
|
||||
switch (cmp) {
|
||||
case FUTEX_OP_CMP_EQ:
|
||||
return (oldval == cmparg);
|
||||
case FUTEX_OP_CMP_NE:
|
||||
return (oldval != cmparg);
|
||||
case FUTEX_OP_CMP_LT:
|
||||
return (oldval < cmparg);
|
||||
case FUTEX_OP_CMP_GE:
|
||||
return (oldval >= cmparg);
|
||||
case FUTEX_OP_CMP_LE:
|
||||
return (oldval <= cmparg);
|
||||
case FUTEX_OP_CMP_GT:
|
||||
return (oldval > cmparg);
|
||||
default:
|
||||
return (-ENOSYS);
|
||||
}
|
||||
}
|
||||
|
@ -231,9 +231,10 @@ amd64/linux32/linux32_dummy.c optional compat_linux32
|
||||
amd64/linux32/linux32_locore.s optional compat_linux32 \
|
||||
dependency "linux32_assym.h"
|
||||
amd64/linux32/linux32_machdep.c optional compat_linux32
|
||||
amd64/linux32/linux32_support.s optional compat_linux32
|
||||
amd64/linux32/linux32_sysent.c optional compat_linux32
|
||||
amd64/linux32/linux32_sysvec.c optional compat_linux32
|
||||
compat/linux/linux_emul.c optional compat_linux32
|
||||
compat/linux/linux_emul.c optional compat_linux32
|
||||
compat/linux/linux_file.c optional compat_linux32
|
||||
compat/linux/linux_futex.c optional compat_linux32
|
||||
compat/linux/linux_getcwd.c optional compat_linux32
|
||||
|
@ -345,6 +345,7 @@ i386/linux/linux_locore.s optional compat_linux \
|
||||
dependency "linux_assym.h"
|
||||
i386/linux/linux_machdep.c optional compat_linux
|
||||
i386/linux/linux_ptrace.c optional compat_linux
|
||||
i386/linux/linux_support.s optional compat_linux
|
||||
i386/linux/linux_sysent.c optional compat_linux
|
||||
i386/linux/linux_sysvec.c optional compat_linux
|
||||
i386/pci/pci_bus.c optional pci
|
||||
|
@ -221,6 +221,7 @@ i386/linux/linux_locore.s optional compat_linux \
|
||||
dependency "linux_assym.h"
|
||||
i386/linux/linux_machdep.c optional compat_linux
|
||||
i386/linux/linux_ptrace.c optional compat_linux
|
||||
i386/linux/linux_support.s optional compat_linux
|
||||
i386/linux/linux_sysent.c optional compat_linux
|
||||
i386/linux/linux_sysvec.c optional compat_linux
|
||||
i386/pci/pci_bus.c optional pci
|
||||
|
@ -1513,51 +1513,6 @@ ENTRY(longjmp)
|
||||
incl %eax
|
||||
ret
|
||||
|
||||
/*****************************************************************************/
|
||||
/* linux_futex support */
|
||||
/*****************************************************************************/
|
||||
|
||||
futex_fault:
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
movl $-EFAULT,%eax
|
||||
ret
|
||||
|
||||
ENTRY(futex_xchgl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xchgl %eax,(%edx)
|
||||
movl 12(%esp),%edx
|
||||
movl %eax,(%edx)
|
||||
xorl %eax,%eax
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
|
||||
ENTRY(futex_addl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xaddl %eax,(%edx)
|
||||
movl 12(%esp),%edx
|
||||
movl %eax,(%edx)
|
||||
xorl %eax,%eax
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
|
||||
/*
|
||||
* Support for BB-profiling (gcc -a). The kernbb program will extract
|
||||
* the data from the kernel.
|
||||
|
127
sys/i386/linux/linux_support.s
Normal file
127
sys/i386/linux/linux_support.s
Normal file
@ -0,0 +1,127 @@
|
||||
/*-
|
||||
* Copyright (c) 2006,2007 Konstantin Belousov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "linux_assym.h" /* system definitions */
|
||||
#include <machine/asmacros.h> /* miscellaneous asm macros */
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
futex_fault_decx:
|
||||
movl PCPU(CURPCB),%ecx
|
||||
futex_fault:
|
||||
movl $0,PCB_ONFAULT(%ecx)
|
||||
movl $-EFAULT,%eax
|
||||
ret
|
||||
|
||||
ENTRY(futex_xchgl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
xchgl %eax,(%edx)
|
||||
movl 12(%esp),%edx
|
||||
movl %eax,(%edx)
|
||||
xorl %eax,%eax
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
|
||||
ENTRY(futex_addl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault,PCB_ONFAULT(%ecx)
|
||||
movl 4(%esp),%eax
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
xaddl %eax,(%edx)
|
||||
movl 12(%esp),%edx
|
||||
movl %eax,(%edx)
|
||||
xorl %eax,%eax
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
|
||||
ENTRY(futex_orl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
movl (%edx),%eax
|
||||
1: movl %eax,%ecx
|
||||
orl 4(%esp),%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%edx)
|
||||
jnz 1b
|
||||
futex_tail:
|
||||
movl 12(%esp),%edx
|
||||
movl %eax,(%edx)
|
||||
xorl %eax,%eax
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl %eax,PCB_ONFAULT(%ecx)
|
||||
ret
|
||||
|
||||
ENTRY(futex_andl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
movl (%edx),%eax
|
||||
1: movl %eax,%ecx
|
||||
andl 4(%esp),%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%edx)
|
||||
jnz 1b
|
||||
jmp futex_tail
|
||||
|
||||
ENTRY(futex_xorl)
|
||||
movl PCPU(CURPCB),%ecx
|
||||
movl $futex_fault_decx,PCB_ONFAULT(%ecx)
|
||||
movl 8(%esp),%edx
|
||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||
ja futex_fault
|
||||
movl (%edx),%eax
|
||||
1: movl %eax,%ecx
|
||||
xorl 4(%esp),%ecx
|
||||
#ifdef SMP
|
||||
lock
|
||||
#endif
|
||||
cmpxchgl %ecx,(%edx)
|
||||
jnz 1b
|
||||
jmp futex_tail
|
@ -14,8 +14,12 @@ SRCS= linux${SFX}_dummy.c linux_emul.c linux_file.c \
|
||||
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
|
||||
linux${SFX}_sysvec.c linux_uid16.c linux_util.c linux_time.c \
|
||||
opt_inet6.h opt_mac.h opt_compat.h opt_posix.h vnode_if.h \
|
||||
device_if.h bus_if.h
|
||||
OBJS= linux${SFX}_locore.o
|
||||
device_if.h bus_if.h assym.s
|
||||
|
||||
# XXX: for assym.s
|
||||
SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_compat.h
|
||||
|
||||
OBJS= linux${SFX}_locore.o linux${SFX}_support.o
|
||||
|
||||
.if ${MACHINE_ARCH} == "i386"
|
||||
SRCS+= linux_ptrace.c imgact_linux.c opt_cpu.h
|
||||
@ -41,6 +45,10 @@ linux${SFX}_locore.o: linux${SFX}_locore.s linux${SFX}_assym.h
|
||||
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
|
||||
${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
linux${SFX}_support.o: linux${SFX}_support.s assym.s
|
||||
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
|
||||
${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
linux${SFX}_genassym.o: linux${SFX}_genassym.c linux.h @ machine
|
||||
${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user