diff --git a/src/LibHac/Os/Impl/MemoryFence.cs b/src/LibHac/Os/Impl/MemoryFence.cs new file mode 100644 index 00000000..725d188d --- /dev/null +++ b/src/LibHac/Os/Impl/MemoryFence.cs @@ -0,0 +1,128 @@ +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics.X86; + +namespace LibHac.Os.Impl; + +public static class MemoryFence +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryStoreStore() + { + if (Sse.IsSupported) + { + Sse.StoreFence(); + } + else + { + // This only needs to be a store barrier on aarch64 + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryStoreLoad() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryStoreAny() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryLoadStore() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + // This only needs to be a load barrier on aarch64 + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryLoadLoad() + { + if (Sse2.IsSupported) + { + Sse2.LoadFence(); + } + else + { + // This only needs to be a load barrier on aarch64 + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryLoadAny() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + // This only needs to be a load barrier on aarch64 + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryAnyStore() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryAnyLoad() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + System.Threading.Thread.MemoryBarrier(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void FenceMemoryAnyAny() + { + if (Sse2.IsSupported) + { + Sse2.MemoryFence(); + } + else + { + System.Threading.Thread.MemoryBarrier(); + } + } +} \ No newline at end of file diff --git a/src/LibHac/Os/MemoryFenceApi.cs b/src/LibHac/Os/MemoryFenceApi.cs new file mode 100644 index 00000000..35949014 --- /dev/null +++ b/src/LibHac/Os/MemoryFenceApi.cs @@ -0,0 +1,19 @@ +using System.Runtime.CompilerServices; +using LibHac.Os.Impl; + +namespace LibHac.Os; + +public static class MemoryFenceApi +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryStoreStore() => MemoryFence.FenceMemoryStoreStore(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryStoreLoad() => MemoryFence.FenceMemoryStoreLoad(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryStoreAny() => MemoryFence.FenceMemoryStoreAny(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryLoadStore() => MemoryFence.FenceMemoryLoadStore(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryLoadLoad() => MemoryFence.FenceMemoryLoadLoad(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryLoadAny() => MemoryFence.FenceMemoryLoadAny(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryAnyStore() => MemoryFence.FenceMemoryAnyStore(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryAnyLoad() => MemoryFence.FenceMemoryAnyLoad(); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void FenceMemoryAnyAny() => MemoryFence.FenceMemoryAnyAny(); +} \ No newline at end of file