public static byte *Allocate4KbAlignedMemory(long size, out ThreadStats thread) { Debug.Assert(size >= 0); thread = ThreadAllocations.Value; thread.Allocations += size; if (PlatformDetails.RunningOnPosix) { byte *ptr; var rc = Syscall.posix_memalign(&ptr, (IntPtr)4096, (IntPtr)size); if (rc != 0) { Syscall.ThrowLastError(rc, "Could not allocate memory"); } return(ptr); } var allocate4KbAllignedMemory = Win32MemoryProtectMethods.VirtualAlloc(null, (UIntPtr)size, Win32MemoryProtectMethods.AllocationType.COMMIT, Win32MemoryProtectMethods.MemoryProtection.READWRITE); if (allocate4KbAllignedMemory == null) { ThrowFailedToAllocate(); } return(allocate4KbAllignedMemory); }
byte *AllocateMemoryAtEndOfPager(long totalAllocationSize) { if (StorageEnvironmentOptions.RunningOnPosix) { var p = Syscall.mmap64(new IntPtr(Env.Options.DataPager.PagerState.MapBase + totalAllocationSize), (UIntPtr)16, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_ANONYMOUS, -1, 0L); if (p.ToInt64() == -1) { return(null); } return((byte *)p.ToPointer()); } return(Win32MemoryProtectMethods.VirtualAlloc(Env.Options.DataPager.PagerState.MapBase + totalAllocationSize, new UIntPtr(16), Win32MemoryProtectMethods.AllocationType.RESERVE, Win32MemoryProtectMethods.MemoryProtection.EXECUTE_READWRITE)); }
public static byte *Allocate(int size) { var remaining = size % 4096; var sizeInPages = (size / 4096) + (remaining == 0 ? 0 : 1); var allocatedSize = ((sizeInPages + 2) * 4096); var virtualAlloc = Win32MemoryProtectMethods.VirtualAlloc(null, (UIntPtr)allocatedSize, Win32MemoryProtectMethods.AllocationType.COMMIT, Win32MemoryProtectMethods.MemoryProtection.READWRITE); if (virtualAlloc == null) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to VirtualAlloc (ElectricFence) size=" + size); } *(int *)virtualAlloc = allocatedSize; Win32MemoryProtectMethods.MemoryProtection protect; if (Win32MemoryProtectMethods.VirtualProtect(virtualAlloc, (UIntPtr)(4096), Win32MemoryProtectMethods.MemoryProtection.NOACCESS, out protect) == false) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to VirtualProtect (ElectricFence) at address=" + new IntPtr(virtualAlloc)); } if (Win32MemoryProtectMethods.VirtualProtect(virtualAlloc + (sizeInPages + 1) * 4096, (UIntPtr)(4096), Win32MemoryProtectMethods.MemoryProtection.NOACCESS, out protect) == false) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to VirtualProtect (ElectricFence) at address=" + new IntPtr(virtualAlloc + (sizeInPages + 1) * 4096)); } var firstWritablePage = virtualAlloc + 4096; Win32UnmanagedMemory.Set(firstWritablePage, 0xED, 4096 * sizeInPages); // don't assume zero'ed mem if (remaining == 0) { return(firstWritablePage); } // give the memory out so its end would be at the 2nd guard page return(firstWritablePage + (4096 - remaining)); }
public static byte *Allocate4KbAlignedMemory(long size, out Sparrow.Utils.NativeMemory.ThreadStats thread) { Debug.Assert(size >= 0); thread = Sparrow.Utils.NativeMemory.ThreadAllocations.Value; thread.Allocations += size; Interlocked.Add(ref Sparrow.Utils.NativeMemory._totalAllocatedMemory, size); if (PlatformDetails.RunningOnPosix) { // we pass NULL (IntPtr.Zero) as the first parameter (address / start) so the kernel chooses the(page-aligned) address at which to create the mapping var pageAlignedMemory = Syscall.mmap64(IntPtr.Zero, (UIntPtr)size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS, -1, 0L); if (pageAlignedMemory.ToInt64() == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, $"Could not allocate memory (allocation size: {size / Constants.Size.Kilobyte:#,#0} kb)"); } return((byte *)pageAlignedMemory); } var allocate4KbAlignedMemory = Win32MemoryProtectMethods.VirtualAlloc(null, (UIntPtr)size, Win32MemoryProtectMethods.AllocationType.COMMIT, Win32MemoryProtectMethods.MemoryProtection.READWRITE); if (allocate4KbAlignedMemory == null) { ThrowFailedToAllocate(); } return(allocate4KbAlignedMemory); }