public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) { bool[] Modified = Memory.IsRegionModified(PA, Size); if (Modified == null) { return(true); } ClearCachedPagesIfNeeded(); long PageSize = Memory.GetHostPageSize(); long Mask = PageSize - 1; long PAEnd = PA + Size; bool RegMod = false; int Index = 0; while (PA < PAEnd) { long Key = PA & ~Mask; long PAPgEnd = Math.Min((PA + PageSize) & ~Mask, PAEnd); bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); if (IsCached) { CpCount -= Cp.GetTotalCount(); SortedCache.Remove(Cp.Node); } else { Cp = new CachedPage(); Cache.Add(Key, Cp); } if (Modified[Index++] && IsCached) { Cp = new CachedPage(); Cache[Key] = Cp; } Cp.Node = SortedCache.AddLast(Key); RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType); CpCount += Cp.GetTotalCount(); PA = PAPgEnd; } return(RegMod); }
public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) { (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size); PA = Memory.GetPhysicalAddress(PA); ClearCachedPagesIfNeeded(); long PageSize = AMemory.PageSize; EnsureResidencyInitialized(PageSize); bool HasResidents = AddResidency(PA, Size); if (!HasResidents && ModifiedCount == 0) { return(false); } long Mask = PageSize - 1; long ResidencyKey = PA; long PAEnd = PA + Size; bool RegMod = false; int Index = 0; while (PA < PAEnd) { long Key = PA & ~AMemory.PageMask; long PAPgEnd = Math.Min((PA + AMemory.PageSize) & ~AMemory.PageMask, PAEnd); bool IsCached = Cache.TryGetValue(Key, out CachedPage Cp); if (IsCached) { CpCount -= Cp.GetTotalCount(); SortedCache.Remove(Cp.Node); } else { Cp = new CachedPage(); Cache.Add(Key, Cp); } if (Modified[Index++] && IsCached) { Cp = new CachedPage(); Cache[Key] = Cp; } Cp.AddResidency(ResidencyKey); Cp.Node = SortedCache.AddLast(Key); RegMod |= Cp.AddRange(PA, PAPgEnd, BufferType); CpCount += Cp.GetTotalCount(); PA = PAPgEnd; } return(RegMod); }
public bool IsRegionModified(AMemory Memory, NvGpuBufferType BufferType, long PA, long Size) { (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(PA, Size); //Remove all modified ranges. int Index = 0; long Position = PA & ~NvGpuVmm.PageMask; while (ModifiedCount > 0) { if (Modified[Index++]) { CachedRanges.Remove(new ValueRange <int>(Position, Position + NvGpuVmm.PageSize)); ModifiedCount--; } Position += NvGpuVmm.PageSize; } //Mask has the bit set for the current resource type. //If the region is not yet present on the list, then a new ValueRange //is directly added with the current resource type as the only bit set. //Otherwise, it just sets the bit for this new resource type on the current mask. int Mask = 1 << (int)BufferType; ValueRange <int> NewCached = new ValueRange <int>(PA, PA + Size); ValueRange <int>[] Ranges = CachedRanges.GetAllIntersections(NewCached); long LastEnd = NewCached.Start; long Coverage = 0; for (Index = 0; Index < Ranges.Length; Index++) { ValueRange <int> Current = Ranges[Index]; long RgStart = Math.Max(Current.Start, NewCached.Start); long RgEnd = Math.Min(Current.End, NewCached.End); if ((Current.Value & Mask) == 0) { CachedRanges.Add(new ValueRange <int>(RgStart, RgEnd, Current.Value | Mask)); } else { Coverage += RgEnd - RgStart; } if (RgStart > LastEnd) { CachedRanges.Add(new ValueRange <int>(LastEnd, RgStart, Mask)); } LastEnd = RgEnd; } if (LastEnd < NewCached.End) { CachedRanges.Add(new ValueRange <int>(LastEnd, NewCached.End, Mask)); } return(Coverage != Size); }