public void QueryModified(ulong address, ulong size, Action <ulong, ulong> modifiedAction) { int startHandle = (int)((address - Address) / Granularity); int lastHandle = (int)((address + (size - 1) - Address) / Granularity); ulong rgStart = _handles[startHandle].Address; ulong rgSize = 0; for (int i = startHandle; i <= lastHandle; i++) { RegionHandle handle = _handles[i]; if (handle.Dirty) { rgSize += handle.Size; handle.Reprotect(); } else { // Submit the region scanned so far as dirty if (rgSize != 0) { modifiedAction(rgStart, rgSize); rgSize = 0; } rgStart = handle.EndAddress; } } if (rgSize != 0) { modifiedAction(rgStart, rgSize); } }
public void QueryModified(ulong address, ulong size, Action <ulong, ulong> modifiedAction, int sequenceNumber) { int startHandle = (int)((address - _address) / _granularity); int lastHandle = (int)((address + (size - 1) - _address) / _granularity); ulong rgStart = _address + (ulong)startHandle * _granularity; ulong rgSize = 0; ulong endAddress = _address + ((ulong)lastHandle + 1) * _granularity; int i = startHandle; while (i <= lastHandle) { RegionHandle handle = _handles[i]; if (handle == null) { // Missing handle. A new handle must be created. CreateHandle(i, lastHandle); handle = _handles[i]; } if (handle.EndAddress > endAddress) { // End address of handle is beyond the end of the search. Force a split. SplitHandle(i, lastHandle + 1); handle = _handles[i]; } if (handle.Dirty && sequenceNumber != handle.SequenceNumber) { rgSize += handle.Size; handle.Reprotect(); } else { // Submit the region scanned so far as dirty if (rgSize != 0) { modifiedAction(rgStart, rgSize); rgSize = 0; } rgStart = handle.EndAddress; } handle.SequenceNumber = sequenceNumber; i += (int)(handle.Size / _granularity); } if (rgSize != 0) { modifiedAction(rgStart, rgSize); } }
internal MultiRegionHandle(MemoryTracking tracking, ulong address, ulong size, IEnumerable <IRegionHandle> handles, ulong granularity) { _handles = new RegionHandle[size / granularity]; Granularity = granularity; int i = 0; if (handles != null) { // Inherit from the handles we were given. Any gaps must be filled with new handles, // and old handles larger than our granularity must copy their state onto new granular handles and dispose. // It is assumed that the provided handles do not overlap, in order, are on page boundaries, // and don't extend past the requested range. foreach (RegionHandle handle in handles) { int startIndex = (int)((handle.Address - address) / granularity); // Fill any gap left before this handle. while (i < startIndex) { RegionHandle fillHandle = tracking.BeginTracking(address + (ulong)i * granularity, granularity); fillHandle.Parent = this; _handles[i++] = fillHandle; } if (handle.Size == granularity) { handle.Parent = this; _handles[i++] = handle; } else { int endIndex = (int)((handle.EndAddress - address) / granularity); while (i < endIndex) { RegionHandle splitHandle = tracking.BeginTracking(address + (ulong)i * granularity, granularity); splitHandle.Parent = this; splitHandle.Reprotect(handle.Dirty); RegionSignal signal = handle.PreAction; if (signal != null) { splitHandle.RegisterAction(signal); } _handles[i++] = splitHandle; } handle.Dispose(); } } } // Fill any remaining space with new handles. while (i < _handles.Length) { RegionHandle handle = tracking.BeginTracking(address + (ulong)i * granularity, granularity); handle.Parent = this; _handles[i++] = handle; } Address = address; Size = size; }