util/u_atomic: Add _InterlockedExchangeAdd8/16 for older MSVC.
authorJose Fonseca <jfonseca@vmware.com>
Wed, 11 Feb 2015 15:30:39 +0000 (15:30 +0000)
committerJose Fonseca <jfonseca@vmware.com>
Thu, 12 Feb 2015 19:32:21 +0000 (19:32 +0000)
We need to build certain parts of Mesa (namely gallium, llvmpipe, and
therefore util) with Windows SDK 7.0.7600, which includes MSVC 2008.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/util/u_atomic.h

index e123e17..728322b 100644 (file)
@@ -88,9 +88,9 @@
 
 #if _MSC_VER < 1600
 
-/* Implement _InterlockedCompareExchange8 in terms of InterlockedCompareExchange16 */
-static __inline
-char _InterlockedCompareExchange8(char volatile *Destination8, char Exchange8, char Comparand8)
+/* Implement _InterlockedCompareExchange8 in terms of _InterlockedCompareExchange16 */
+static __inline char
+_InterlockedCompareExchange8(char volatile *Destination8, char Exchange8, char Comparand8)
 {
    INT_PTR DestinationAddr = (INT_PTR)Destination8;
    short volatile *Destination16 = (short volatile *)(DestinationAddr & ~1);
@@ -103,7 +103,7 @@ char _InterlockedCompareExchange8(char volatile *Destination8, char Exchange8, c
        * neighboring byte untouched */
       short Exchange16 = (Initial16 & ~Mask8) | ((short)Exchange8 << Shift8);
       short Comparand16 = Initial16;
-      short Initial16 = InterlockedCompareExchange16(Destination16, Exchange16, Comparand16);
+      short Initial16 = _InterlockedCompareExchange16(Destination16, Exchange16, Comparand16);
       if (Initial16 == Comparand16) {
          /* succeeded */
          return Comparand8;
@@ -114,6 +114,35 @@ char _InterlockedCompareExchange8(char volatile *Destination8, char Exchange8, c
    return Initial8;
 }
 
+/* Implement _InterlockedExchangeAdd16 in terms of _InterlockedCompareExchange16 */
+static __inline short
+_InterlockedExchangeAdd16(short volatile *Addend, short Value)
+{
+   short Initial = *Addend;
+   short Comparand;
+   do {
+      short Exchange = Initial + Value;
+      Comparand = Initial;
+      /* if *Addend==Comparand then *Addend=Exchange, return original *Addend */
+      Initial = _InterlockedCompareExchange16(Addend, Exchange, Comparand);
+   } while(Initial != Comparand);
+   return Comparand;
+}
+
+/* Implement _InterlockedExchangeAdd8 in terms of _InterlockedCompareExchange8 */
+static __inline char
+_InterlockedExchangeAdd8(char volatile *Addend, char Value)
+{
+   char Initial = *Addend;
+   char Comparand;
+   do {
+      char Exchange = Initial + Value;
+      Comparand = Initial;
+      Initial = _InterlockedCompareExchange8(Addend, Exchange, Comparand);
+   } while(Initial != Comparand);
+   return Comparand;
+}
+
 #endif /* _MSC_VER < 1600 */
 
 /* MSVC supports decltype keyword, but it's only supported on C++ and doesn't