From 362b9ceb7cc3c7564d62006f58d32b2d82fd7cc9 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 17 Jan 2022 14:33:34 +0000 Subject: [PATCH] inc: fsctl.h: atomics --- inc/winfsp/fsctl.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 11c8dff7..62a15091 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -699,6 +699,93 @@ FSP_API NTSTATUS FspMountSet(FSP_MOUNT_DESC *Desc); FSP_API NTSTATUS FspMountRemove(FSP_MOUNT_DESC *Desc); #endif +/* + * Atomics + * + * See https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html (https://archive.is/mJfFX) + */ +#if _MSC_VER >= 1920 /* VS2019 or later */ +__int32 __iso_volatile_load32(const volatile __int32 *); +void __iso_volatile_store32(volatile __int32 *, __int32); +__int64 __iso_volatile_load64(const volatile __int64 *); +void __iso_volatile_store64(volatile __int64 *, __int64); +#define FSP_ATOMIC_VOLATILE_LOAD32(p) __iso_volatile_load32(p) +#define FSP_ATOMIC_VOLATILE_STORE32(p,v)__iso_volatile_store32(p,v) +#define FSP_ATOMIC_VOLATILE_LOAD64(p) __iso_volatile_load64(p) +#define FSP_ATOMIC_VOLATILE_STORE64(p,v)__iso_volatile_store64(p,v) +#else +#define FSP_ATOMIC_VOLATILE_LOAD32(p) (*(p)) +#define FSP_ATOMIC_VOLATILE_STORE32(p,v)(*(p) = (v)) +#define FSP_ATOMIC_VOLATILE_LOAD64(p) (*(p)) +#define FSP_ATOMIC_VOLATILE_STORE64(p,v)(*(p) = (v)) +#endif +static inline INT32 FspAtomicLoad32(INT32 volatile *p) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); + __dmb(0xb); + return v; + +#elif defined(_M_X64) || defined(_M_IX86) + void _ReadWriteBarrier(void); + INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); + _ReadWriteBarrier(); + return v; + +#endif +} +static inline VOID FspAtomicStore32(INT32 volatile *p, INT32 v) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + __dmb(0xb); + FSP_ATOMIC_VOLATILE_STORE32(p, v); + __dmb(0xb); + +#elif defined(_M_X64) || defined(_M_IX86) + long _InterlockedExchange(long volatile *, long); + _InterlockedExchange((long volatile *)p, v); + +#endif +} +static inline VOID *FspAtomicLoadPointer(VOID *volatile *p) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); + __dmb(0xb); + return v; + +#elif defined(_M_X64) + void _ReadWriteBarrier(void); + VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); + _ReadWriteBarrier(); + return v; + +#elif defined(_M_IX86) + void _ReadWriteBarrier(void); + VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD32((__int32 volatile *)(p)); + _ReadWriteBarrier(); + return v; + +#endif +} +static inline VOID FspAtomicStorePointer(VOID *volatile *p, VOID *v) +{ +#if defined(_M_ARM64) + void __dmb(unsigned int); + __dmb(0xb); + FSP_ATOMIC_VOLATILE_STORE64((__int64 volatile *)(p), (__int64)(v)); + __dmb(0xb); + +#elif defined(_M_X64) || defined(_M_IX86) + void *_InterlockedExchangePointer(void *volatile *, void *); + _InterlockedExchangePointer(p, v); + +#endif +} + #ifdef __cplusplus } #endif