99 lines
4.5 KiB
C
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);
|
|
}
|