Beispiel #1
0
        public override unsafe void ReleaseAllocationInfo(byte *baseAddress, long size)
        {
            base.ReleaseAllocationInfo(baseAddress, size);

            if (_supportsUnmapping == false)
            {
                return;
            }

            var ptr = new IntPtr(baseAddress);

            if (DeleteOnClose)
            {
                if (Syscall.madvise(ptr, new UIntPtr((ulong)size), MAdvFlags.MADV_DONTNEED) != 0)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info($"Failed to madvise MDV_DONTNEED for {FileName?.FullPath}");
                    }
                }
            }

            var result = Syscall.munmap(ptr, (UIntPtr)size);

            if (result == -1)
            {
                var err = Marshal.GetLastWin32Error();
                Syscall.ThrowLastError(err, "munmap " + FileName);
            }
            NativeMemory.UnregisterFileMapping(FileName.FullPath, ptr, size);
        }
        public override void ReleaseAllocationInfo(byte *baseAddress, long size)
        {
            var result = Syscall.munmap(new IntPtr(baseAddress), (ulong)size);

            if (result == -1)
            {
                PosixHelper.ThrowLastError(Marshal.GetLastWin32Error());
            }
        }
Beispiel #3
0
        public override void ReleaseAllocationInfo(byte *baseAddress, long size)
        {
            var ptr    = new IntPtr(baseAddress);
            var result = Syscall.munmap(ptr, (UIntPtr)size);

            if (result == -1)
            {
                var err = Marshal.GetLastWin32Error();
                PosixHelper.ThrowLastError(err);
            }
            NativeMemory.UnregisterFileMapping(FileName, ptr, size);
        }
Beispiel #4
0
        private void CleanupMemory(TransactionState txState)
        {
            _globalMemory.EnterWriteLock();
            try
            {
                foreach (var addr in txState.AddressesToUnload)
                {
                    if (addr.Usages != 0)
                    {
                        continue;
                    }

                    ConcurrentSet <MappedAddresses> set;
                    if (!_globalMapping.TryGetValue(addr.StartPage, out set))
                    {
                        continue;
                    }

                    if (!set.TryRemove(addr))
                    {
                        continue;
                    }

                    Interlocked.Add(ref _totalMapped, -addr.Size);
                    Syscall.munmap(addr.Address, (UIntPtr)addr.Size);
                    NativeMemory.UnregisterFileMapping(addr.File, addr.Address, addr.Size);

                    if (set.Count == 0)
                    {
                        _globalMapping.TryRemove(addr.StartPage, out set);
                    }
                }
            }
            finally
            {
                _globalMemory.ExitWriteLock();
            }
        }
        public override int CopyPage(I4KbBatchWrites destI4KbBatchWrites, long pageNumber, PagerState pagerState)
        {
            long sizeToMap               = AllocationGranularity;
            var  distanceFromStart       = (pageNumber % NumberOfPagesInAllocationGranularity);
            var  allocationStartPosition = pageNumber - distanceFromStart;

            var offset  = allocationStartPosition * Constants.Storage.PageSize;
            var mmflags = _copyOnWriteMode ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED;

            var result = Syscall.mmap64(IntPtr.Zero, (UIntPtr)sizeToMap,
                                        MmapProts.PROT_READ | MmapProts.PROT_WRITE,
                                        mmflags, _fd, offset);

            try
            {
                if (result.ToInt64() == -1) //system didn't succeed in mapping the address where we wanted
                {
                    var err = Marshal.GetLastWin32Error();
                    Syscall.ThrowLastError(err,
                                           $"Unable to map (default view size) {sizeToMap / Constants.Size.Kilobyte:#,#0} kb for page {pageNumber} starting at {allocationStartPosition} on {FileName}");
                }

                var pageHeader = (PageHeader *)(result.ToInt64() + distanceFromStart * Constants.Storage.PageSize);

                int numberOfPages = 1;
                if ((pageHeader->Flags & PageFlags.Overflow) == PageFlags.Overflow)
                {
                    numberOfPages = VirtualPagerLegacyExtensions.GetNumberOfOverflowPages(pageHeader->OverflowSize);
                }


                if (numberOfPages + distanceFromStart > NumberOfPagesInAllocationGranularity)
                {
                    Syscall.munmap(result, (UIntPtr)sizeToMap);
                    result    = new IntPtr(-1);
                    sizeToMap = NearestSizeToAllocationGranularity((numberOfPages + distanceFromStart) *
                                                                   Constants.Storage.PageSize);
                    result = Syscall.mmap64(IntPtr.Zero, (UIntPtr)sizeToMap, MmapProts.PROT_READ | MmapProts.PROT_WRITE,
                                            mmflags, _fd, offset);

                    if (result.ToInt64() == -1)
                    {
                        var err = Marshal.GetLastWin32Error();
                        Syscall.ThrowLastError(err,
                                               $"Unable to map {sizeToMap / Constants.Size.Kilobyte:#,#0} kb for page {pageNumber} starting at {allocationStartPosition} on {FileName}");
                    }

                    pageHeader = (PageHeader *)(result.ToInt64() + (distanceFromStart * Constants.Storage.PageSize));
                }
                const int adjustPageSize = (Constants.Storage.PageSize) / (4 * Constants.Size.Kilobyte);

                destI4KbBatchWrites.Write(pageHeader->PageNumber * adjustPageSize, numberOfPages * adjustPageSize,
                                          (byte *)pageHeader);

                return(numberOfPages);
            }
            finally
            {
                if (result.ToInt64() != -1)
                {
                    Syscall.munmap(result, (UIntPtr)sizeToMap);
                }
            }
        }