diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-02-18 20:52:06 -0300 |
|---|---|---|
| committer | jduncanator <1518948+jduncanator@users.noreply.github.com> | 2019-02-19 10:52:06 +1100 |
| commit | 932224f05112180aa5f52162cbbc3a17c339075f (patch) | |
| tree | eed53f37bfd78db97d6f8301c021b7de9dd3becf /ChocolArm64/Memory/MemoryAlloc.cs | |
| parent | dd00a4b62d48b7d55a6e66a69a83f09267d34143 (diff) | |
ARM exclusive monitor and multicore fixes (#589)
* Implement ARM exclusive load/store with compare exchange insts, and enable multicore by default
* Fix comment typo
* Support Linux and OSX on MemoryAlloc and CompareExchange128, some cleanup
* Use intel syntax on assembly code
* Adjust identation
* Add CPUID check and fix exclusive reservation granule size
* Update schema multicore scheduling default value
* Make the cpu id check code lower case aswell
Diffstat (limited to 'ChocolArm64/Memory/MemoryAlloc.cs')
| -rw-r--r-- | ChocolArm64/Memory/MemoryAlloc.cs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/ChocolArm64/Memory/MemoryAlloc.cs b/ChocolArm64/Memory/MemoryAlloc.cs new file mode 100644 index 00000000..a24299cd --- /dev/null +++ b/ChocolArm64/Memory/MemoryAlloc.cs @@ -0,0 +1,114 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace ChocolArm64.Memory +{ + public static class MemoryAlloc + { + public static bool HasWriteWatchSupport => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + + public static IntPtr Allocate(ulong size) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + IntPtr sizeNint = new IntPtr((long)size); + + return MemoryAllocWindows.Allocate(sizeNint); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return MemoryAllocUnix.Allocate(size); + } + else + { + throw new PlatformNotSupportedException(); + } + } + + public static IntPtr AllocateWriteTracked(ulong size) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + IntPtr sizeNint = new IntPtr((long)size); + + return MemoryAllocWindows.AllocateWriteTracked(sizeNint); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return MemoryAllocUnix.Allocate(size); + } + else + { + throw new PlatformNotSupportedException(); + } + } + + public static void Reprotect(IntPtr address, ulong size, MemoryProtection permission) + { + bool result; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + IntPtr sizeNint = new IntPtr((long)size); + + result = MemoryAllocWindows.Reprotect(address, sizeNint, permission); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + result = MemoryAllocUnix.Reprotect(address, size, permission); + } + else + { + throw new PlatformNotSupportedException(); + } + + if (!result) + { + throw new MemoryProtectionException(permission); + } + } + + public static bool Free(IntPtr address) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return MemoryAllocWindows.Free(address); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return MemoryAllocUnix.Free(address); + } + else + { + throw new PlatformNotSupportedException(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool GetModifiedPages( + IntPtr address, + IntPtr size, + IntPtr[] addresses, + out ulong count) + { + //This is only supported on windows, but returning + //false (failed) is also valid for platforms without + //write tracking support on the OS. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return MemoryAllocWindows.GetModifiedPages(address, size, addresses, out count); + } + else + { + count = 0; + + return false; + } + } + } +}
\ No newline at end of file |
