On 05/20/2013 03:57 AM, dw wrote:
> There is a bug in the InterlockedOr function (as well as InterlockedAnd,
> InterlockedXor, InterlockedOr64, InterlockedAnd64, InterlockedXor64)
> where they do not return the "old" value as expected, but instead return
> (sort of) the new value.  This code illustrates the problem:
> 
> #include <stdio.h>
> #include <windows.h>
> 
> #ifndef _AMD64_
> #error Must be compiled for x64
> #endif
> 
> int main()
> {
>    volatile LONG x = 0;
>    LONG y = InterlockedXor(&x, 3);
> 
>    printf("old: %u new: %u\n", y, x); // Should print 0 3, prints 3 3
> }
> 
> The attached patch resolves this issue.
> 
> In summary, this patch:
> 
> 1) Correctly returns the "old" value.
> 2) Uses builtin function instead of inline asm.
I think your implementation is less efficient than it could be. I think
it would be more efficient if you used GCC's __sync_fetch_and_OP()
built-ins instead of hand crafted compare exchange loop
(http://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/_005f_005fsync-Builtins.html#_005f_005fsync-Builtins).

Even if you decide to go with the hand crafted compare exchange loop, it
can still be made more efficient, I believe:

+#define __buildlogicali(x, y, o) __CRT_INLINE y x(volatile y
*Destination, y Value) \
+{ \
+   y lPrev; \
+   do { \
+      lPrev = *Destination; \
+   } while (__sync_val_compare_and_swap(Destination, lPrev, lPrev o
Value) != lPrev); \
+   return lPrev; \
+}

Here you are reading the *Destination memory each loop iteration once
more than should be necessary. You could leverage the
__sync_val_compare_and_swap() built-in and use its return value.
Something like this should be better:

#define __mybuildlogicali(x, y, o) \
__CRT_INLINE y x(volatile y *Destination, y Value) \
{ \
    y lPrev = *Destination; \
    y lTmp; \
    while ((lTmp = __sync_val_compare_and_swap(Destination, \
                       lPrev, lPrev o Value)) != lPrev) \
        lPrev = lTmp; \
    return lPrev; \
}

-- 
VZ

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to