/// <summary> /// Reserves a heap's chunk and returns a pointer to this area. /// </summary> /// <param name="newPointer">Number of bytes to reserve.</param> /// <returns>An handle to the reserved area.</returns> protected virtual MemoryPointer Alloc(MemoryPointer newPointer) { // - Iterate over the free spaces for (int i = FreeSpace.Count - 1; i >= 0; --i) { var freeChunk = FreeSpace[i]; // - If we found a suitable free space if (freeChunk.Size >= newPointer.Size) { // - Set the position to the current free chunk newPointer.ChangeOffsetAndSize(freeChunk.Offset, newPointer.Size); // - Calculates the remaining space uint remainingSpace = freeChunk.Size - newPointer.Size; // - If no memory remains in the free space pointer we must delete it if (remainingSpace <= 0) { FreeSpace.Remove(freeChunk); } else { freeChunk.ChangeOffsetAndSize(newPointer.Offset + newPointer.Size, remainingSpace); } // - Adds the new pointer to the used space UsedSpace.Add(newPointer); // - Sort used space UsedSpace.OrderBy(x => x.Offset); // - Update fragmentation factor FragmentationFactor = CalculateFragmentationRate(); return(newPointer); } } // - Expand the heap if (!Grow(newPointer.Size)) { Defrag(); if (FreeSpace.Count > 0 && FreeSpace.Last().Size > newPointer.Size) { return(Alloc(newPointer)); } return(null); } return(Alloc(newPointer)); }
/* * If ContinueOnError argument is 'true', return the exception else nope. * Used storage space size will return in bytes */ private void GetUsedSpaceOfAzureStorage(CodeActivityContext context) { try { AzureParamHelper azureStorageHelper = new AzureParamHelper(StorageConnectionString.Get(context), StorageBlobContainer.Get(context)); UsedSpace.Set(context, AzureHelper.GetUsedSpaceOfAzureStorage(FileExtension.Get(context))); } catch (Exception ex) { if (Convert.ToBoolean((int)ContinueOnError)) { } else { throw ex; } } }
public bool IsCorr(int startedlength, int stoppedlength, int heigth) { for (int component = startedlength; component <= stoppedlength - 1; component++) { if (!UsedSpace.Any(item => item.Contains($"{ShipStart[0].Name}{component + 1}{heigth}"))) { TemporaryPlaces.Add($"{ShipStart[0].Name}{component}{heigth}"); } else { TemporaryPlaces.Clear(); return(false); } } foreach (var Model in TemporaryPlaces) { UsedSpace.Add($"{Model}"); ShipPlaces.Add($"{Model}"); } TemporaryPlaces.Clear(); return(true); }
/// <summary> /// Upload the vertexs to the VRAM. /// </summary> public void Upload(CommandBuffer commands, int maxBytes) { if (StagingVRAM != null && VertexVRAM != null && IndexBuffer != null && StagingBuffer != null) { List <BufferCopy> uploadQueue = new List <BufferCopy>(); // - Order invalidated chunks by priority var invalidated = UsedSpace.Where(x => (x as BufferResource).Invalidated) .OrderByDescending(x => (x as BufferResource).UploadPriority); // - Keep track of the upload zone var uploadRange = (start : 0L, end : 0L); foreach (BufferResource chunk in invalidated) { if (chunk.UploadPriority == int.MaxValue || maxBytes > 0) { uploadQueue.Add(new BufferCopy(chunk.Offset, chunk.Offset, chunk.Size)); maxBytes -= (int)chunk.Size; chunk.Invalidated = false; chunk.UploadPriority = 0; uploadRange = ( start : Math.Min(uploadRange.start, chunk.Offset), end : Math.Max(uploadRange.end, chunk.Offset + chunk.Size) ); } } // - No invalidated chunks if (uploadQueue.Count <= 0) { return; } // - Calculate upload range int uploadOffset = (int)uploadRange.start; int uploadSize = (int)(uploadRange.end - uploadRange.start); // TODO: This can be improved by splitting large upload areas // - Gets the pointer to the staging memory IntPtr vram = StagingVRAM.Map(uploadOffset, uploadSize, MemoryMapFlags.None); unsafe { // - Perform the copy System.Buffer.MemoryCopy ( IntPtr.Add(RawMemory, uploadOffset).ToPointer(), vram.ToPointer(), uploadSize, uploadSize ); } // - Unmap the staging memory pointer StagingVRAM.Unmap(); // - Send the upload message to the GPU commands.CopyBuffer(StagingBuffer, IndexBuffer, uploadQueue.ToArray()); } }
private void OpenFile_Click(object sender, RoutedEventArgs e) { OpenFileDialog d = new OpenFileDialog(); if (d.ShowDialog() == true) { string lowerFilename = System.IO.Path.GetExtension(d.FileName).ToLower(); if (d.FileName.EndsWith(".pcc") || d.FileName.EndsWith(".u") || d.FileName.EndsWith(".sfm") || d.FileName.EndsWith(".upk")) { pcc = MEPackageHandler.OpenMEPackage(d.FileName); } bytes = File.ReadAllBytes(d.FileName); Interpreter_Hexbox.ByteProvider = new DynamicByteProvider(bytes); MemoryStream inStream = new MemoryStream(bytes); UnusedSpaceList.ClearEx(); if (pcc != null) { List <UsedSpace> used = new List <UsedSpace>(); used.Add(new UsedSpace { UsedFor = "Package Header", UsedSpaceStart = 0, UsedSpaceEnd = pcc.getHeader().Length }); inStream.Seek(pcc.NameOffset, SeekOrigin.Begin); for (int i = 0; i < pcc.NameCount; i++) { int strLength = inStream.ReadValueS32(); inStream.ReadString(strLength * -2, true, Encoding.Unicode); } used.Add(new UsedSpace { UsedFor = "Name Table", UsedSpaceStart = pcc.NameOffset, UsedSpaceEnd = (int)inStream.Position }); for (int i = 0; i < pcc.ImportCount; i++) { inStream.Position += 28; } used.Add(new UsedSpace { UsedFor = "Import Table", UsedSpaceStart = pcc.ImportOffset, UsedSpaceEnd = (int)inStream.Position }); inStream.Seek(pcc.ExportOffset, SeekOrigin.Begin); for (int i = 0; i < pcc.ExportCount; i++) { inStream.Position += pcc.Exports[i].Header.Length; } used.Add(new UsedSpace { UsedFor = "Export Metadata Table", UsedSpaceStart = pcc.ExportOffset, UsedSpaceEnd = (int)inStream.Position }); used.Add(new UsedSpace { UsedFor = "Dependency Table (Unused)", UsedSpaceStart = BitConverter.ToInt32(pcc.getHeader(), 0x3A), UsedSpaceEnd = BitConverter.ToInt32(pcc.getHeader(), 0x3E) }); List <UsedSpace> usedExportsSpaces = new List <UsedSpace>(); inStream.Seek(pcc.ExportOffset, SeekOrigin.Begin); for (int i = 0; i < pcc.ExportCount; i++) { IExportEntry exp = pcc.Exports[i]; usedExportsSpaces.Add(new UsedSpace { UsedFor = $"Export {exp.UIndex}", UsedSpaceStart = exp.DataOffset, UsedSpaceEnd = exp.DataOffset + exp.DataSize }); } usedExportsSpaces = usedExportsSpaces.OrderBy(x => x.UsedSpaceStart).ToList(); List <UsedSpace> continuousBlocks = new List <UsedSpace>(); UsedSpace continuous = new UsedSpace { UsedFor = "Continuous Export Data", UsedSpaceStart = usedExportsSpaces[0].UsedSpaceStart, UsedSpaceEnd = usedExportsSpaces[0].UsedSpaceEnd }; for (int i = 1; i < usedExportsSpaces.Count; i++) { UsedSpace u = usedExportsSpaces[i]; if (continuous.UsedSpaceEnd == u.UsedSpaceStart) { continuous.UsedSpaceEnd = u.UsedSpaceEnd; } else { continuousBlocks.Add(continuous); continuous = new UsedSpace { UsedFor = "Continuous Export Data", UsedSpaceStart = u.UsedSpaceStart, UsedSpaceEnd = u.UsedSpaceEnd }; } } continuousBlocks.Add(continuous); UnusedSpaceList.AddRange(used); UnusedSpaceList.AddRange(continuousBlocks); } } }
/// <summary> /// This method will re-arrange the array in a way that /// all the used memory is contiguous when possible. /// </summary> /// <param name="limitSwaps">Limits the number of chunk swaps for a partial defragmentation.</param> /// <param name="movedCallback">Callback invoked on each swap.</param> public virtual void Defrag(int limitSwaps = int.MaxValue, Action <MemoryPointer> movedCallback = null) { // - No fragmentation if (FreeSpace.Count <= 1) { return; } int lastOffset = 0; MemoryPointer nextChunk = null; // - Foreach chunk we move the block to the left foreach (var chunk in UsedSpace) { // - Limits the number of adjustments if (limitSwaps <= 0) { nextChunk = chunk; break; } if (chunk.Offset > lastOffset) { unsafe { void *source = chunk.Handler.ToPointer(); void *dest = IntPtr.Add(RawMemory, lastOffset).ToPointer(); Buffer.MemoryCopy(source, dest, chunk.Size, chunk.Size); } movedCallback?.Invoke(chunk); // - Update handler offset chunk.ChangeOffsetAndSize((uint)lastOffset, chunk.Size); limitSwaps--; } lastOffset += (int)chunk.Size; } if (nextChunk != null) { // - Remove remaining spaces before next chunk FreeSpace.RemoveAll(x => x.Offset <= nextChunk.Offset); if (lastOffset < nextChunk.Offset) { uint newSize = (uint)(nextChunk.Offset - lastOffset); FreeSpace.Insert(0, new MemoryPointer(this, newSize, (uint)lastOffset)); } } else { FreeSpace.Clear(); var lastElement = UsedSpace.LastOrDefault(); uint newOffset = lastElement.Offset + lastElement.Size; uint newSize = HeapSize - newOffset; FreeSpace.Add(new MemoryPointer(this, newSize, newOffset)); } // - Update fragmentation factor FragmentationFactor = CalculateFragmentationRate(); }
/// <summary> /// Release a portion of heap described by the provided handler. /// </summary> /// <param name="handler">Handler to the memory chunk you want to free.</param> public virtual void Free(MemoryPointer handler) { // - Assure that handler is valid if (handler == null) { return; } // - Assure that handler is valid if (!UsedSpace.Contains(handler)) { return; } MemoryPointer previousFree = null; MemoryPointer nextFree = null; // - Iterate over the free spaces for (int i = FreeSpace.Count - 1; i >= 0; --i) { var freeChunk = FreeSpace[i]; // - Check if there's a free block before the handler if (freeChunk.Offset + freeChunk.Size == handler.Offset) { previousFree = freeChunk; } // - Check if there's a free block after the handler if (handler.Offset + handler.Size == freeChunk.Offset) { nextFree = freeChunk; } } if (previousFree != null && nextFree != null) { uint newSize = previousFree.Size + handler.Size + nextFree.Size; // - Remove last free space FreeSpace.Remove(nextFree); // - Expand the first free space previousFree.ChangeOffsetAndSize(previousFree.Offset, newSize); } else if (previousFree != null) { uint newSize = previousFree.Size + handler.Size; // - Expand the first free space previousFree.ChangeOffsetAndSize(previousFree.Offset, newSize); } else if (nextFree != null) { uint newSize = nextFree.Size + handler.Size; // - Expand the first free space previousFree.ChangeOffsetAndSize(handler.Offset, newSize); } else { // - Adds the removed space to the FreeSpace list FreeSpace.Add(handler); // - Sort free space FreeSpace.OrderBy(x => x.Offset); } // - Remove the deleted handler UsedSpace.Remove(handler); }