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.
dw
Index: winnt.h
===================================================================
--- winnt.h (revision 5867)
+++ winnt.h (working copy)
@@ -1416,37 +1416,22 @@
: "memory");
return prev;
}
- __CRT_INLINE LONG InterlockedAnd(LONG volatile *Destination,LONG Value) {
- __asm__ __volatile__("lock ; andl %0,%1"
- : :"r"(Value),"m"(*Destination)
- : "memory");
- return *Destination;
- }
- __CRT_INLINE LONG InterlockedOr(LONG volatile *Destination,LONG Value) {
- __asm__ __volatile__("lock ; orl %0,%1"
- : : "r"(Value),"m"(*Destination) : "memory");
- return *Destination;
- }
- __CRT_INLINE LONG InterlockedXor(LONG volatile *Destination,LONG Value) {
- __asm__ __volatile__("lock ; xorl %0,%1"
- : : "r"(Value),"m"(*Destination) : "memory");
- return *Destination;
- }
- __CRT_INLINE LONG64 InterlockedAnd64(LONG64 volatile *Destination,LONG64
Value) {
- __asm__ __volatile__("lock ; andq %0,%1"
- : : "r"(Value),"m"(*Destination) : "memory");
- return *Destination;
- }
- __CRT_INLINE LONG64 InterlockedOr64(LONG64 volatile *Destination,LONG64
Value) {
- __asm__ __volatile__("lock ; orq %0,%1"
- : : "r"(Value),"m"(*Destination) : "memory");
- return *Destination;
- }
- __CRT_INLINE LONG64 InterlockedXor64(LONG64 volatile *Destination,LONG64
Value) {
- __asm__ __volatile__("lock ; xorq %0,%1"
- : : "r"(Value),"m"(*Destination) : "memory");
- return *Destination;
- }
+#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; \
+}
+
+__buildlogicali(InterlockedAnd, LONG, &)
+__buildlogicali(InterlockedOr, LONG, |)
+__buildlogicali(InterlockedXor, LONG, ^)
+
+__buildlogicali(InterlockedAnd64, LONG64, &)
+__buildlogicali(InterlockedOr64, LONG64, |)
+__buildlogicali(InterlockedXor64, LONG64, ^)
#endif /* !__CRT__NO_INLINE */
LONG InterlockedExchangeAdd(LONG volatile *Addend,LONG Value);
------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public