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 AddRange(long Start, long End, NvGpuBufferType BufferType) { List <Range> BtRegions = Regions[(int)BufferType]; for (int Index = 0; Index < BtRegions.Count; Index++) { Range Rg = BtRegions[Index]; if (Start >= Rg.Start && End <= Rg.End) { return(false); } if (Start <= Rg.End && Rg.Start <= End) { long MinStart = Math.Min(Rg.Start, Start); long MaxEnd = Math.Max(Rg.End, End); BtRegions[Index] = new Range(MinStart, MaxEnd); Timestamp = Environment.TickCount; return(true); } } BtRegions.Add(new Range(Start, End)); Timestamp = Environment.TickCount; return(true); }
public CachedPage(long PABase, NvGpuBufferType BufferType) { this.PABase = PABase; this.BufferType = BufferType; Regions = new List <(long, long)>(); }
public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType) { long va = position; long pa = _memory.GetPhysicalAddress(va); long endAddr = (va + size + PageMask) & ~PageMask; long addrTruncated = va & ~PageMask; bool modified = _memory.IsRegionModified(addrTruncated, endAddr - addrTruncated); int newBuffMask = 1 << (int)bufferType; long cachedPagesCount = 0; while (va < endAddr) { long page = _memory.GetPhysicalAddress(va) >> PageBits; ConcurrentDictionary <long, int> dictionary = _cachedPages[page]; if (dictionary == null) { dictionary = new ConcurrentDictionary <long, int>(); _cachedPages[page] = dictionary; } else if (modified) { _cachedPages[page].Clear(); } if (dictionary.TryGetValue(pa, out int currBuffMask)) { if ((currBuffMask & newBuffMask) != 0) { cachedPagesCount++; } else { dictionary[pa] |= newBuffMask; } } else { dictionary[pa] = newBuffMask; } va += PageSize; } return(cachedPagesCount != (endAddr - addrTruncated) >> PageBits); }
public bool MemoryRegionModified(NvGpuVmm Vmm, long Position, long Size, NvGpuBufferType Type) { HashSet <long> Uploaded = UploadedKeys[(int)Type]; if (!Uploaded.Add(Position)) { return(false); } return(Vmm.IsRegionModified(Position, Size, Type)); }
public bool MemoryRegionModified(NvGpuVmm vmm, long position, long size, NvGpuBufferType type) { HashSet <long> uploaded = _uploadedKeys[(int)type]; if (!uploaded.Add(position)) { return(false); } return(vmm.IsRegionModified(position, size, type)); }
private bool QueryKeyUpload(NvGpuVmm Vmm, long Key, long Size, NvGpuBufferType Type) { List <long> Uploaded = UploadedKeys[(int)Type]; if (Uploaded.Contains(Key)) { return(false); } Uploaded.Add(Key); return(Vmm.IsRegionModified(Key, Size, Type)); }
public bool IsRegionModified(long position, long size, NvGpuBufferType bufferType) { long pa = _memory.GetPhysicalAddress(position); long addr = pa; long endAddr = (addr + size + PageMask) & ~PageMask; int newBuffMask = 1 << (int)bufferType; _memory.StartObservingRegion(position, size); long cachedPagesCount = 0; while (addr < endAddr) { long page = addr >> PageBits; ConcurrentDictionary <long, int> dictionary = CachedPages[page]; if (dictionary == null) { dictionary = new ConcurrentDictionary <long, int>(); CachedPages[page] = dictionary; } if (dictionary.TryGetValue(pa, out int currBuffMask)) { if ((currBuffMask & newBuffMask) != 0) { cachedPagesCount++; } else { dictionary[pa] |= newBuffMask; } } else { dictionary[pa] = newBuffMask; } addr += PageSize; } return(cachedPagesCount != (endAddr - pa + PageMask) >> PageBits); }
public bool IsRegionModified(long pa, long size, NvGpuBufferType bufferType) { return(_cache.IsRegionModified(pa, size, bufferType)); }
public bool IsRegionModified(long PA, long Size, NvGpuBufferType BufferType) { return(Cache.IsRegionModified(Memory, BufferType, PA, Size)); }
public void ClearPbCache(NvGpuBufferType Type) { UploadedKeys[(int)Type].Clear(); }
public bool IsRegionModified(MemoryManager Memory, NvGpuBufferType BufferType, long Start, long Size) { (bool[] Modified, long ModifiedCount) = Memory.IsRegionModified(Start, Size); //Remove all modified ranges. int Index = 0; long Position = Start & ~NvGpuVmm.PageMask; while (ModifiedCount > 0) { if (Modified[Index++]) { CachedRanges.Remove(new ValueRange <CachedResource>(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. //The physical address of the resource is used as key, those keys are used to keep //track of resources that are already on the cache. A resource may be inside another //resource, and in this case we should return true if the "sub-resource" was not //yet cached. int Mask = 1 << (int)BufferType; CachedResource NewCachedValue = new CachedResource(Start, Mask); ValueRange <CachedResource> NewCached = new ValueRange <CachedResource>(Start, Start + Size); ValueRange <CachedResource>[] Ranges = CachedRanges.GetAllIntersections(NewCached); bool IsKeyCached = Ranges.Length > 0 && Ranges[0].Value.Key == Start; long LastEnd = NewCached.Start; long Coverage = 0; for (Index = 0; Index < Ranges.Length; Index++) { ValueRange <CachedResource> Current = Ranges[Index]; CachedResource Cached = Current.Value; long RgStart = Math.Max(Current.Start, NewCached.Start); long RgEnd = Math.Min(Current.End, NewCached.End); if ((Cached.Mask & Mask) != 0) { Coverage += RgEnd - RgStart; } //Highest key value has priority, this prevents larger resources //for completely invalidating smaller ones on the cache. For example, //consider that a resource in the range [100, 200) was added, and then //another one in the range [50, 200). We prevent the new resource from //completely replacing the old one by spliting it like this: //New resource key is added at [50, 100), old key is still present at [100, 200). if (Cached.Key < Start) { Cached.Key = Start; } Cached.Mask |= Mask; CachedRanges.Add(new ValueRange <CachedResource>(RgStart, RgEnd, Cached)); if (RgStart > LastEnd) { CachedRanges.Add(new ValueRange <CachedResource>(LastEnd, RgStart, NewCachedValue)); } LastEnd = RgEnd; } if (LastEnd < NewCached.End) { CachedRanges.Add(new ValueRange <CachedResource>(LastEnd, NewCached.End, NewCachedValue)); } return(!IsKeyCached || Coverage != Size); }
public void ClearPbCache(NvGpuBufferType type) { _uploadedKeys[(int)type].Clear(); }
public bool IsRegionModified(long Position, long Size, NvGpuBufferType BufferType) { long PA = GetPhysicalAddress(Position); return(Cache.IsRegionModified(Memory, BufferType, Position, PA, Size)); }
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); }