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