Files

99 lines
4.5 KiB
C

// Fixed-width atomic operations for nt-lite-owned storage.
#pragma once
#include <stdint.h>
#include <intrin.h>
_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);
}