dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.98k stars 4.66k forks source link

API Proposal: Marshal.AllocHGlobal like API that map to VirtualAlloc/mmap and support specifying Large Pages #40892

Open mjsabby opened 4 years ago

mjsabby commented 4 years ago

Background and Motivation

Marshal.AllocHGlobal supports allocating native memory via C#. If a user wants to allocate native memory in a more specific way they have to write platform specific code that targets the underlying VirtualAlloc (on Windows) or mmap on *nix API call.

This is not ideal. While the code is not a lot, with proper error handling which are platform specific, not to mention a PInvokes in general is hard to get right with bitness, etc.

Proposed API

namespace System.Runtime.InteropServices
{
     public class Marshal
     {
         public static IntPtr NativeAlloc(long size, MemoryProtection protection, AllocationOptions options)
         {
         }
     }

     [Flags]
     public enum MemoryProtection
     {
         Read,
         Write,
         Execute,
         NoAccess
     }

     [Flags]
     public enum AllocationOptions
     {
         LargePagesAny,
         LargePages2MB,
         LargePages1GB,
         Reserve,
         Commit
     }
}

Usage Examples

Marshal.NativeAlloc(2 * 1024 * 1024, MemoryProtection.Read | MemoryProtection.Write, AllocationOptions.LargePagesAny | AllocationOptions.Reserve | AllocationOptions.Commit);

Other thoughts

We would throw PlatformNotSupportedException where these options or capability is not supported.

jkotas commented 4 years ago
jkotas commented 4 years ago

This has a lot of overlap with the existing MemoryMappedFile set of APIs. Would it make sense to piggy back on the existing APIs for this? E.g. https://docs.microsoft.com/en-us/dotnet/api/system.io.memorymappedfiles.memorymappedfilerights overlaps with MemoryProtection, etc.

mjsabby commented 4 years ago

@jkotas yes on both your comments. When you say piggy backing on the MemoryMappedFile set of APIs, are you proposing changing the namespace? I agree that the enums are valuable, but is there much more than that?

Perhaps you're thinking we could also support MAP_SHARED?

jkotas commented 4 years ago

This functionality has large overlap with memory mapped files, so I do not see a problem with having it the same namespace as memory mapped files.

wasabii commented 1 year ago

This is still open, but I want to throw another use case.

I am using VirtualAlloc by hand to generate executable code regions to which I can directly jump to. That use case doesn't really fit in 'memory mapped files'.

lindexi commented 1 month ago

Reference from Avalonia: https://github.com/AvaloniaUI/Avalonia/blob/dcae7568b1080ff69cab40697f8f7647140af340/src/Avalonia.Base/Platform/Internal/UnmanagedBlob.cs#L122-L139