PERFORCE change 106386 for review
Roman Divacky
rdivacky at FreeBSD.org
Wed Sep 20 04:16:42 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=106386
Change 106386 by rdivacky at rdivacky_witten on 2006/09/20 11:16:38
Futex patch by kib@
- implement futex_op for amd64
- remove critical section
- make orl/andl/xorl MI and remove its implementations
from i386
Affected files ...
.. //depot/projects/linuxolator/src/sys/amd64/amd64/support.S#2 edit
.. //depot/projects/linuxolator/src/sys/compat/linux/linux_futex.c#2 edit
.. //depot/projects/linuxolator/src/sys/i386/i386/support.s#2 edit
Differences ...
==== //depot/projects/linuxolator/src/sys/amd64/amd64/support.S#2 (text+ko) ====
@@ -689,3 +689,48 @@
movq %rax,32(%rdi)
movq %rdi,bbhead
NON_GPROF_RET
+
+#if defined(SMP) || !defined(_KERNEL)
+#define MPLOCKED lock ;
+#else
+#define MPLOCKED
+#endif
+
+ .text
+
+futex_fault:
+ movq PCPU(CURPCB), %rdx
+ movq $0, PCB_ONFAULT(%rdx)
+ movq $-EFAULT, %rax
+ ret
+
+/* int futex_xchgl(int oparg, caddr_t uaddr, int *oldval); */
+ENTRY(futex_xchgl)
+ movq PCPU(CURPCB), %r11
+ movq $futex_fault, PCB_ONFAULT(%r11)
+
+ movq $VM_MAXUSER_ADDRESS-4, %rax
+ cmpq %rax, %rsi
+ ja futex_fault
+
+ MPLOCKED xchgl %edi, (%rsi)
+ movl %edi, (%rdx)
+ xorl %eax, %eax
+ movq %rax, PCB_ONFAULT(%r11)
+ ret
+
+/* int futex_addl(int oparg, caddr_t uaddr, int *oldval); */
+ENTRY(futex_addl)
+ movq PCPU(CURPCB), %r11
+ movq $futex_fault, PCB_ONFAULT(%r11)
+
+ movq $VM_MAXUSER_ADDRESS-4, %rax
+ cmpq %rax, %rsi
+ ja futex_fault
+
+ MPLOCKED xaddl %edi, (%rsi)
+ movl %edi, (%rdx)
+ xorl %eax, %eax
+ movq %rax, PCB_ONFAULT(%r11)
+ ret
+
==== //depot/projects/linuxolator/src/sys/compat/linux/linux_futex.c#2 (text+ko) ====
@@ -89,16 +89,14 @@
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 *);
-#ifdef __i386__
static int futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr);
-#endif
+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_andnl(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)
@@ -429,7 +427,6 @@
return count;
}
-#ifdef __i386__
static int
futex_atomic_op(struct thread *td, int encoded_op, caddr_t uaddr)
{
@@ -448,8 +445,6 @@
#endif
/* XXX: linux verifies access here and returns EFAULT */
- critical_enter();
-
switch (op) {
case FUTEX_OP_SET:
ret = futex_xchgl(oparg, uaddr, &oldval);
@@ -461,7 +456,7 @@
ret = futex_orl(oparg, uaddr, &oldval);
break;
case FUTEX_OP_ANDN:
- ret = futex_andnl(oparg, uaddr, &oldval);
+ ret = futex_andl(~oparg, uaddr, &oldval);
break;
case FUTEX_OP_XOR:
ret = futex_xorl(oparg, uaddr, &oldval);
@@ -470,8 +465,6 @@
ret = -ENOSYS;
}
- critical_exit();
-
if (!ret)
switch (cmp) {
case FUTEX_OP_CMP_EQ:
@@ -497,4 +490,42 @@
return (ret);
}
-#endif
+
+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 (casuptr((intptr_t *)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 (casuptr((intptr_t *)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 (casuptr((intptr_t *)uaddr, ua_old, ua) == ua_old)
+ return ua_old;
+ }
+}
==== //depot/projects/linuxolator/src/sys/i386/i386/support.s#2 (text+ko) ====
@@ -1549,8 +1549,7 @@
ret
/* int futex_xchgl(int oparg, caddr_t uaddr, int *oldval); */
- .globl futex_xchgl
-futex_xchgl:
+ENTRY(futex_xchgl)
movl PCPU(CURPCB), %eax
movl $futex_fault, PCB_ONFAULT(%eax)
movl 4(%esp), %eax
@@ -1568,8 +1567,7 @@
ret
/* int futex_addl(int oparg, caddr_t uaddr, int *oldval); */
- .globl futex_addl
-futex_addl:
+ENTRY(futex_addl)
movl PCPU(CURPCB), %eax
movl $futex_fault, PCB_ONFAULT(%eax)
movl 4(%esp), %eax
@@ -1586,60 +1584,3 @@
movl $0, PCB_ONFAULT(%edx)
ret
-/* int futex_orl(int oparg, caddr_t uaddr, int *oldval); */
- .globl futex_orl
-futex_orl:
- movl PCPU(CURPCB), %eax
- movl $futex_fault, PCB_ONFAULT(%eax)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- cmpl $VM_MAXUSER_ADDRESS,%edx
- ja futex_fault
-
- MPLOCKED orl %eax, (%edx)
- movl 0xc(%esp), %edx
- movl %eax, (%edx)
- xorl %eax, %eax
-
- movl PCPU(CURPCB), %edx
- movl $0, PCB_ONFAULT(%edx)
- ret
-
-/* int futex_andnl(int oparg, caddr_t uaddr, int *oldval); */
- .globl futex_andnl
-futex_andnl:
- movl PCPU(CURPCB), %eax
- movl $futex_fault, PCB_ONFAULT(%eax)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- cmpl $VM_MAXUSER_ADDRESS,%edx
- ja futex_fault
-
- notl (%edx)
- MPLOCKED andl %eax, (%edx)
- movl 0xc(%esp), %edx
- movl %eax, (%edx)
- xorl %eax, %eax
-
- movl PCPU(CURPCB), %edx
- movl $0, PCB_ONFAULT(%edx)
- ret
-
-/* int futex_xorl(int oparg, caddr_t uaddr, int *oldval); */
- .globl futex_xorl
-futex_xorl:
- movl PCPU(CURPCB), %eax
- movl $futex_fault, PCB_ONFAULT(%eax)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- cmpl $VM_MAXUSER_ADDRESS,%edx
- ja futex_fault
-
- MPLOCKED xorl %eax, (%edx)
- movl 0xc(%esp), %edx
- movl %eax, (%edx)
- xorl %eax, %eax
-
- movl PCPU(CURPCB), %edx
- movl $0, PCB_ONFAULT(%edx)
- ret
More information about the p4-projects
mailing list