static nuint SoftwareFallback(ref nuint p, mi_memory_order_t mo) { nuint x = p; if (mo > mi_memory_order_relaxed) { while (!mi_atomic_compare_exchange_weak_explicit(ref p, ref x, x, mo, mi_memory_order_relaxed)) { /* nothing */ } } return(x); }
private static nuint mi_atomic_fetch_add_explicit([NativeTypeName("std::atomic<uintptr_t>*")] ref nuint p, [NativeTypeName("uintptr_t")] nuint add, mi_memory_order_t mo) { nuint value = p; if (Environment.Is64BitProcess) { _ = Interlocked.Add(ref Unsafe.As <nuint, ulong>(ref p), add); } else { _ = Interlocked.Add(ref Unsafe.As <nuint, uint>(ref p), (uint)add); } return(value); }
private static bool mi_atomic_cas_strong(ref nuint p, ref nuint expected, nuint desired, mi_memory_order_t mem_success, mi_memory_order_t mem_fail) => mi_atomic_compare_exchange_strong_explicit(ref p, ref expected, desired, mem_success, mem_fail);
private static nuint mi_atomic_load_explicit([NativeTypeName("std::atomic<uintptr_t> const*")] ref nuint p, mi_memory_order_t mo) { if (X86Base.IsSupported) { return(p); } else { return(SoftwareFallback(ref p, mo)); }
private static void mi_atomic_thread_fence(mi_memory_order_t mo) { nuint x = 0; _ = mi_atomic_exchange_explicit(ref x, 1, mo); }
private static nuint mi_atomic_exchange_explicit([NativeTypeName("std::atomic<uintptr_t>*")] ref nuint p, [NativeTypeName("uintptr_t")] nuint exchange, mi_memory_order_t mo) { if (Environment.Is64BitProcess) { return((nuint)Interlocked.Exchange(ref Unsafe.As <nuint, ulong>(ref p), exchange)); } else { return(Interlocked.Exchange(ref Unsafe.As <nuint, uint>(ref p), (uint)exchange)); } }
private static bool mi_atomic_compare_exchange_weak_explicit([NativeTypeName("std::atomic<uintptr_t>*")] ref nuint p, [NativeTypeName("uintptr_t*")] ref nuint expected, [NativeTypeName("uintptr_t")] nuint desired, mi_memory_order_t mo1, mi_memory_order_t mo2) => mi_atomic_compare_exchange_strong_explicit(ref p, ref expected, desired, mo1, mo2);
private static bool mi_atomic_compare_exchange_strong_explicit([NativeTypeName("std::atomic<uintptr_t>*")] ref nuint p, [NativeTypeName("uintptr_t*")] ref nuint expected, [NativeTypeName("uintptr_t")] nuint desired, mi_memory_order_t mo1, mi_memory_order_t mo2) { nuint read; if (Environment.Is64BitProcess) { read = (nuint)Interlocked.CompareExchange(ref Unsafe.As <nuint, ulong>(ref p), desired, expected); } else { read = Interlocked.CompareExchange(ref Unsafe.As <nuint, uint>(ref p), (uint)desired, (uint)expected); } if (read == expected) { return(true); } else { expected = read; return(false); } }
private static nuint mi_atomic_fetch_sub_explicit([NativeTypeName("std::atomic<uintptr_t>*")] ref nuint p, [NativeTypeName("uintptr_t")] nuint sub, mi_memory_order_t mo) => mi_atomic_fetch_add_explicit(ref p, (nuint)(-(nint)sub), mo);