Dave Korn wrote:
>   The attached patch implements ilockexch and ilockcmpexch, using the inline
> asm definition from __arch_compare_and_exchange_val_32_acq in
> glibc-2.10.1/sysdeps/i386/i486/bits/atomic.h, trivially expanded inline rather
> than in its original preprocessor macro form.

  The attached patch does likewise, but adds a "memory" clobber.  It generates
correct code:

L186:
        .loc 3 127 0
        movl    __ZN13pthread_mutex7mutexesE+8, %eax     # mutexes.head, D.28599
        movl    %eax, 36(%ebx)   # D.28599, <variable>.next
        .loc 2 60 0
/APP
 # 60 "/gnu/winsup/src/winsup/cygwin/winbase.h" 1
        lock cmpxchgl %ebx, __ZN13pthread_mutex7mutexesE+8       # this,
 # 0 "" 2
/NO_APP
        movl    %eax, -12(%ebp)  # tmp68, ret
        .loc 2 61 0
        movl    -12(%ebp), %eax  # ret, D.28596
        .loc 3 126 0
        cmpl    %eax, 36(%ebx)   # D.28596, <variable>.next
        jne     L186     #,


although as you see it has some needless register motion as it stores %eax to
the stack slot for ret and reloads it.  Still, this is now almost as good as
the code generated by my original patch.

winsup/cygwin/ChangeLog

        * winbase.h (ilockexch):  Fix asm constraints.
        (ilockcmpexch):  Likewise.


  Ok-ish?

    cheers,
      DaveK

Index: winsup/cygwin/winbase.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/winbase.h,v
retrieving revision 1.14
diff -p -u -r1.14 winbase.h
--- winsup/cygwin/winbase.h	12 Jul 2008 18:09:17 -0000	1.14
+++ winsup/cygwin/winbase.h	3 Jun 2009 23:28:02 -0000
@@ -38,22 +38,28 @@ ilockdecr (volatile long *m)
 extern __inline__ long
 ilockexch (volatile long *t, long v)
 {
-  register int __res;
-  __asm__ __volatile__ ("\n\
-1:	lock	cmpxchgl %3,(%1)\n\
-	jne 1b\n\
- 	": "=a" (__res), "=q" (t): "1" (t), "q" (v), "0" (*t): "cc");
-  return __res;
+  return ({
+		__typeof (*t) ret;
+		__asm __volatile ("1:	lock cmpxchgl %2, %1\n"
+				"	jne 1b\n"
+			: "=a" (ret), "=m" (*t)
+			: "r" (v), "m" (*t), "0" (*t)
+			: "memory");
+		ret;
+	});
 }
 
 extern __inline__ long
 ilockcmpexch (volatile long *t, long v, long c)
 {
-  register int __res;
-  __asm__ __volatile__ ("\n\
-	lock cmpxchgl %3,(%1)\n\
-	": "=a" (__res), "=q" (t) : "1" (t), "q" (v), "0" (c): "cc");
-  return __res;
+  return ({
+		__typeof (*t) ret;
+		__asm __volatile ("lock cmpxchgl %2, %1"
+			: "=a" (ret), "=m" (*t)
+			: "r" (v), "m" (*t), "0" (c)
+			: "memory");
+		ret;
+	});
 }
 
 #undef InterlockedIncrement

Reply via email to