MSVC is horrendous

This commit is contained in:
2026-04-02 15:19:51 +02:00
parent 19cfedc112
commit ac2a05efdb
3 changed files with 36 additions and 6 deletions

View File

@@ -15,7 +15,6 @@
// to use the numerical accuracy better
#define NN_COMPONENT_CALLBUDGET 10000
// NN_ATOMIC_NONE accepts 1 args, others 2
#ifdef NN_ATOMIC_NONE
typedef size_t nn_refc_t;
@@ -27,6 +26,32 @@ bool nn_decRef(nn_refc_t *refc, size_t n) {
(*refc) -= n;
return (*refc) == 0;
}
#elif defined(NN_ATOMIC_MSVC)
// MSVC lacks C11 <stdatomic.h> in C mode, but has interlocked intrinsics.
// _InterlockedExchangeAdd operates on long (32-bit),
// _InterlockedExchangeAdd64 operates on __int64 (64-bit).
// We pick the right one based on pointer size since size_t matches that.
#include <intrin.h>
typedef volatile size_t nn_refc_t;
void nn_incRef(nn_refc_t *refc, size_t n) {
#if defined(_WIN64)
_InterlockedExchangeAdd64((__int64 volatile *)refc, (__int64)n);
#else
_InterlockedExchangeAdd((long volatile *)refc, (long)n);
#endif
}
bool nn_decRef(nn_refc_t *refc, size_t n) {
#if defined(_WIN64)
__int64 old = _InterlockedExchangeAdd64((__int64 volatile *)refc, -(__int64)n);
return (size_t)old == n;
#else
long old = _InterlockedExchangeAdd((long volatile *)refc, -(long)n);
return (size_t)old == n;
#endif
}
#else
// we need atomics for thread-safe reference counting that will be used
// for managing the lifetimes of various resources

View File

@@ -37,8 +37,8 @@ extern "C" {
#if defined(_MSC_VER) && !defined(__cplusplus)
#ifndef NN_ATOMIC_NONE
#define NN_ATOMIC_NONE
#ifndef NN_ATOMIC_MSVC
#define NN_ATOMIC_MSVC
#endif
#endif