summaryrefslogtreecommitdiffstats
path: root/src/util/u_atomic.h
diff options
context:
space:
mode:
authorJose Fonseca <[email protected]>2015-02-11 15:30:39 +0000
committerJose Fonseca <[email protected]>2015-02-12 19:32:21 +0000
commit531d47baa8f755a688c77aec488742ee7d491014 (patch)
tree9ed9e4d29d418d619b908914b082388bebe81bc0 /src/util/u_atomic.h
parentd2438f5920b95a880e9146882a58bf37ec57bad5 (diff)
util/u_atomic: Add _InterlockedExchangeAdd8/16 for older MSVC.
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 <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]>
Diffstat (limited to 'src/util/u_atomic.h')
-rw-r--r--src/util/u_atomic.h37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/util/u_atomic.h b/src/util/u_atomic.h
index e123e171d30..728322bfe50 100644
--- a/src/util/u_atomic.h
+++ b/src/util/u_atomic.h
@@ -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