Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }