michael@0: /* michael@0: * Copyright 2013 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef SkAtomics_win_DEFINED michael@0: #define SkAtomics_win_DEFINED michael@0: michael@0: /** Windows Interlocked atomics. */ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: //MSDN says in order to declare an interlocked function for use as an michael@0: //intrinsic, include intrin.h and put the function in a #pragma intrinsic michael@0: //directive. michael@0: //The pragma appears to be unnecessary, but doesn't hurt. michael@0: #pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDecrement) michael@0: #pragma intrinsic(_InterlockedCompareExchange) michael@0: michael@0: static inline int32_t sk_atomic_inc(int32_t* addr) { michael@0: // InterlockedIncrement returns the new value, we want to return the old. michael@0: return _InterlockedIncrement(reinterpret_cast(addr)) - 1; michael@0: } michael@0: michael@0: static inline int32_t sk_atomic_add(int32_t* addr, int32_t inc) { michael@0: return _InterlockedExchangeAdd(reinterpret_cast(addr), static_cast(inc)); michael@0: } michael@0: michael@0: static inline int32_t sk_atomic_dec(int32_t* addr) { michael@0: // InterlockedDecrement returns the new value, we want to return the old. michael@0: return _InterlockedDecrement(reinterpret_cast(addr)) + 1; michael@0: } michael@0: michael@0: static inline void sk_membar_acquire__after_atomic_dec() { } michael@0: michael@0: static inline int32_t sk_atomic_conditional_inc(int32_t* addr) { michael@0: long value = *addr; michael@0: while (true) { michael@0: if (value == 0) { michael@0: return 0; michael@0: } michael@0: michael@0: long before = _InterlockedCompareExchange(reinterpret_cast(addr), value + 1, value); michael@0: michael@0: if (before == value) { michael@0: return value; michael@0: } else { michael@0: value = before; michael@0: } michael@0: } michael@0: } michael@0: michael@0: static inline bool sk_atomic_cas(int32_t* addr, int32_t before, int32_t after) { michael@0: return _InterlockedCompareExchange(reinterpret_cast(addr), after, before) == before; michael@0: } michael@0: michael@0: static inline void sk_membar_acquire__after_atomic_conditional_inc() { } michael@0: michael@0: #endif