> 2/ Split the i386 atomic_ucas_32 into two, one that's pcb aware and one
> that's not. And use the pcb aware one for the futex and the other one
> for the acpi locking. And of course the amd64 function in the diff
> bellow will match the non-pcb one from i386.

With the convention that the 'u' in ucas stands for userland (i.e. pcb
check needed) this would look something like this:

diff --git sys/arch/amd64/include/atomic.h sys/arch/amd64/include/atomic.h
index effbb04..4cf6563 100644
--- sys/arch/amd64/include/atomic.h
+++ sys/arch/amd64/include/atomic.h
@@ -90,6 +90,17 @@ x86_atomic_clearbits_u32(volatile u_int32_t *ptr, u_int32_t 
bits)
        __asm __volatile(LOCK " andl %1,%0" :  "=m" (*ptr) : "ir" (~bits));
 }
 
+static __inline int
+x86_atomic_cas_int32(volatile int32_t *ptr, int32_t expect, int32_t set)
+{
+       int res;
+
+       __asm volatile(LOCK " cmpxchgl %2, %1" : "=a" (res), "=m" (*ptr)
+           : "r" (set), "a" (expect), "m" (*ptr) : "memory");
+
+       return (res);
+}
+
 static __inline u_long
 x86_atomic_cas_ul(volatile u_long *ptr, u_long expect, u_long set)
 {
diff --git sys/arch/i386/include/atomic.h sys/arch/i386/include/atomic.h
index fc5408c..d96959c 100644
--- sys/arch/i386/include/atomic.h
+++ sys/arch/i386/include/atomic.h
@@ -99,8 +99,19 @@ i486_atomic_cas_int(volatile u_int *ptr, u_int expect, u_int 
set)
        return (res);
 }
 
+static __inline int
+i386_atomic_cas_int32(volatile int32_t *ptr, int32_t expect, int32_t set)
+{
+       int res;
+
+       __asm volatile(LOCK " cmpxchgl %2, %1" : "=a" (res), "=m" (*ptr)
+           : "r" (set), "a" (expect), "m" (*ptr) : "memory");
+
+       return (res);
+}
+
 int ucas_32(volatile int32_t *, int32_t, int32_t);
-#define atomic_ucas_32 ucas_32
+#define i386_atomic_ucas_int32 ucas_32
 
 #define atomic_setbits_int i386_atomic_setbits_l
 #define atomic_clearbits_int i386_atomic_clearbits_l
diff --git sys/compat/linux/linux_futex.c sys/compat/linux/linux_futex.c
index c8eb1cc..7039be6 100644
--- sys/compat/linux/linux_futex.c
+++ sys/compat/linux/linux_futex.c
@@ -634,7 +634,7 @@ futex_atomic_op(struct proc *p, int encoded_op, void *uaddr)
                }
 
                oldval = nval;
-               error = atomic_ucas_32(uaddr, cval, nval);
+               error = i386_atomic_ucas_int32(uaddr, cval, nval);
                if (oldval == cval || error) {
                        break;
                }

Reply via email to