public PosixPageFileBackedMemoryMapPager(string file, long?initialFileSize = null) { var instanceId = Interlocked.Increment(ref _counter); _file = "/" + Syscall.getpid() + "-" + instanceId + "-" + file; _fd = Rt.shm_open(_file, OpenFlags.O_RDWR | OpenFlags.O_CREAT, (int)FilePermissions.ALLPERMS); if (_fd == -1) { PosixHelper.ThrowLastError(Marshal.GetLastWin32Error()); } SysPageSize = Syscall.sysconf(SysconfName._SC_PAGESIZE); if (initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToPageSize(initialFileSize.Value); } _totalAllocationSize = NearestSizeToPageSize(_totalAllocationSize); var result = Syscall.ftruncate(_fd, _totalAllocationSize); if (result != 0) { PosixHelper.ThrowLastError(result); } NumberOfAllocatedPages = _totalAllocationSize / PageSize; PagerState.Release(); PagerState = CreatePagerState(); }
public PosixMemoryMapPager(string file, long?initialFileSize = null) { _file = file; //todo, do we need O_SYNC here? //todo, ALLPERMS ? _fd = Syscall.open(file, OpenFlags.O_RDWR | OpenFlags.O_CREAT | OpenFlags.O_SYNC, FilePermissions.ALLPERMS); if (_fd == -1) { PosixHelper.ThrowLastError(Marshal.GetLastWin32Error()); } SysPageSize = Syscall.sysconf(SysconfName._SC_PAGESIZE); _totalAllocationSize = GetFileSize(); if (_totalAllocationSize == 0 && initialFileSize.HasValue) { _totalAllocationSize = NearestSizeToPageSize(initialFileSize.Value); } if (_totalAllocationSize == 0 || _totalAllocationSize % SysPageSize != 0) { _totalAllocationSize = NearestSizeToPageSize(_totalAllocationSize); var result = Syscall.ftruncate(_fd, _totalAllocationSize); if (result != 0) { PosixHelper.ThrowLastError(result); } } NumberOfAllocatedPages = _totalAllocationSize / PageSize; PagerState.Release(); PagerState = CreatePagerState(); }
public override void AllocateMorePages(Transaction tx, long newLength) { ThrowObjectDisposedIfNeeded(); var newLengthAfterAdjustment = NearestSizeToPageSize(newLength); if (newLengthAfterAdjustment < _totalAllocationSize) { throw new ArgumentException("Cannot set the length to less than the current length"); } if (newLengthAfterAdjustment == _totalAllocationSize) { return; } var allocationSize = newLengthAfterAdjustment - _totalAllocationSize; Syscall.ftruncate(_fd, (_totalAllocationSize + allocationSize)); if (TryAllocateMoreContinuousPages(allocationSize) == false) { PagerState newPagerState = CreatePagerState(); if (newPagerState == null) { var errorMessage = string.Format( "Unable to allocate more pages - unsuccessfully tried to allocate continuous block of virtual memory with size = {0:##,###;;0} bytes", (_totalAllocationSize + allocationSize)); throw new OutOfMemoryException(errorMessage); } newPagerState.DebugVerify(newLengthAfterAdjustment); if (tx != null) { newPagerState.AddRef(); tx.AddPagerState(newPagerState); } var tmp = PagerState; PagerState = newPagerState; tmp.Release(); //replacing the pager state --> so one less reference for it } _totalAllocationSize += allocationSize; NumberOfAllocatedPages = _totalAllocationSize / PageSize; }
public void Truncate(long size) { var result = Syscall.ftruncate(_fd, (IntPtr)size); if (result == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when truncating " + _filename); } result = Syscall.FSync(_fd); if (result == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when fsycning " + _filename); } if (Syscall.CheckSyncDirectoryAllowed(_filename.FullPath) && Syscall.SyncDirectory(_filename.FullPath) == -1) { var err = Marshal.GetLastWin32Error(); Syscall.ThrowLastError(err, "when syncing dir for " + _filename); } }