/// <summary> /// Given an input range, calls the given action with sub-ranges which exclude any of the modified regions. /// </summary> /// <param name="address">Start address of the query range</param> /// <param name="size">Size of the query range in bytes</param> /// <param name="action">Action to perform for each remaining sub-range of the input range</param> public void ExcludeModifiedRegions(ulong address, ulong size, Action <ulong, ulong> action) { lock (_lock) { // Slices a given region using the modified regions in the list. Calls the action for the new slices. ref var overlaps = ref ThreadStaticArray <BufferModifiedRange> .Get(); int count = FindOverlapsNonOverlapping(address, size, ref overlaps); for (int i = 0; i < count; i++) { BufferModifiedRange overlap = overlaps[i]; if (overlap.Address > address) { // The start of the remaining region is uncovered by this overlap. Call the action for it. action(address, overlap.Address - address); } // Remaining region is after this overlap. size -= overlap.EndAddress - address; address = overlap.EndAddress; } if ((long)size > 0) { // If there is any region left after removing the overlaps, signal it. action(address, size); } }
/// <summary> /// Indicate that a virtual region has been mapped, and which physical region it has been mapped to. /// Should be called after the mapping is complete. /// </summary> /// <param name="va">Virtual memory address</param> /// <param name="size">Size to be mapped</param> public void Map(ulong va, ulong size) { // A mapping may mean we need to re-evaluate each VirtualRegion's affected area. // Find all handles that overlap with the range, we need to recalculate their physical regions lock (TrackingLock) { ref var overlaps = ref ThreadStaticArray <VirtualRegion> .Get(); int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref overlaps); for (int i = 0; i < count; i++) { VirtualRegion region = overlaps[i]; // If the region has been fully remapped, signal that it has been mapped again. bool remapped = _memoryManager.IsRangeMapped(region.Address, region.Size); if (remapped) { region.SignalMappingChanged(true); } region.UpdateProtection(); } }