// Fixed-width atomic operations for nt-lite-owned storage. #pragma once #include #include _Static_assert(sizeof(long) == sizeof(int32_t), "MSVC long must be 32-bit"); _Static_assert(sizeof(__int64) == sizeof(int64_t), "MSVC __int64 must be 64-bit"); // Atomically compares and exchanges a signed 32-bit value. static __forceinline int32_t NtlAtomicCompareExchange32(volatile int32_t* destination, int32_t exchange, int32_t comparand) { return (int32_t)_InterlockedCompareExchange((volatile long*)destination, (long)exchange, (long)comparand); } // Atomically loads a signed 32-bit value. static __forceinline int32_t NtlAtomicLoad32(const volatile int32_t* source) { return (int32_t)_InterlockedCompareExchange((volatile long*)source, 0, 0); } // Atomically compares and exchanges an unsigned 32-bit value. static __forceinline uint32_t NtlAtomicCompareExchangeU32(volatile uint32_t* destination, uint32_t exchange, uint32_t comparand) { return (uint32_t)_InterlockedCompareExchange((volatile long*)destination, (long)exchange, (long)comparand); } // Atomically loads an unsigned 32-bit value. static __forceinline uint32_t NtlAtomicLoadU32(const volatile uint32_t* source) { return (uint32_t)_InterlockedCompareExchange((volatile long*)source, 0, 0); } // Atomically exchanges an unsigned 32-bit value. static __forceinline uint32_t NtlAtomicExchangeU32(volatile uint32_t* destination, uint32_t value) { return (uint32_t)_InterlockedExchange((volatile long*)destination, (long)value); } // Atomically exchanges a signed 32-bit value. static __forceinline int32_t NtlAtomicExchange32(volatile int32_t* destination, int32_t value) { return (int32_t)_InterlockedExchange((volatile long*)destination, (long)value); } // Atomically increments a signed 32-bit value. static __forceinline int32_t NtlAtomicIncrement32(volatile int32_t* destination) { return (int32_t)_InterlockedIncrement((volatile long*)destination); } // Atomically decrements a signed 32-bit value. static __forceinline int32_t NtlAtomicDecrement32(volatile int32_t* destination) { return (int32_t)_InterlockedDecrement((volatile long*)destination); } // Atomically compares and exchanges a signed 64-bit value. static __forceinline int64_t NtlAtomicCompareExchange64(volatile int64_t* destination, int64_t exchange, int64_t comparand) { return (int64_t)_InterlockedCompareExchange64((volatile __int64*)destination, (__int64)exchange, (__int64)comparand); } // Atomically loads a signed 64-bit value. static __forceinline int64_t NtlAtomicLoad64(const volatile int64_t* source) { return (int64_t)_InterlockedCompareExchange64((volatile __int64*)source, 0, 0); } // Atomically increments a signed 64-bit value. static __forceinline int64_t NtlAtomicIncrement64(volatile int64_t* destination) { return (int64_t)_InterlockedIncrement64((volatile __int64*)destination); } // Atomically decrements a signed 64-bit value. static __forceinline int64_t NtlAtomicDecrement64(volatile int64_t* destination) { return (int64_t)_InterlockedDecrement64((volatile __int64*)destination); } // Atomically adds to a signed 64-bit value and returns the previous value. static __forceinline int64_t NtlAtomicExchangeAdd64(volatile int64_t* destination, int64_t value) { return (int64_t)_InterlockedExchangeAdd64((volatile __int64*)destination, (__int64)value); } // Atomically compares and exchanges a pointer value. static __forceinline void* NtlAtomicCompareExchangePointer(void* volatile* destination, void* exchange, void* comparand) { return _InterlockedCompareExchangePointer((void* volatile*)destination, exchange, comparand); } // Atomically exchanges a pointer value. static __forceinline void* NtlAtomicExchangePointer(void* volatile* destination, void* value) { return _InterlockedExchangePointer((void* volatile*)destination, value); }