From: Danny S. <dan...@cl...> - 2004-05-23 20:51:58
|
+inline long __gthr_i486_lock_cmp_xchg(long *dest, long xchg, long comperand) +{ + long result; + __asm__ __volatile__ ("\n\ + lock\n\ + cmpxchgl %4, (%1)\n" + : "=a" (result), "=r" (dest) + : "0" (comperand), "1" (dest), "r" (xchg) + : "memory"); + return result; +} + A couple of comments: Make static (we can't assume it won't always be used in C). Make -masm=intel compat: cmpxchg{l} {%4, (%1)|(%1), %4) \n" I don't like this in a public header: +#undef InterlockedCompareExchange +#define InterlockedCompareExchange __gthr_i486_lock_cmp_xchg What happens if windows.h is included after this file? Oh, "comperand" should probably be spelt "comparand" Have you tested the inline at different optimisation levels? I'm glad you didn't use the cygwin winbase.h inlines for increment and decrement. It turns out they are buggy. Try this at -O2: #include <windows.h> #include <stdio.h> /* copied from cygwin's winbase.h */ __inline__ long ilockincr (long *m) { register int __res; __asm__ __volatile__ ("\n\ movl $1,%0\n\ lock xadd %0,(%1)\n\ inc %0\n\ ": "=a" (__res), "=q" (m): "1" (m)); return __res; } void test1() { long x = 9; long y = ilockincr(&x); printf ("ilockincr: %ld\t%ld\n", x, y); } void test2() { long x = 9; long y =InterlockedIncrement(&x); printf ("InterlockedIncrement: %ld\t%ld\n", x, y); } int main() { test1(); test2(); return 0; } Danny |