示例#1
0
        public long UnmapProcessCodeMemory(long Dst, long Src, long Size)
        {
            lock (Blocks)
            {
                long PagesCount = Size / PageSize;

                bool Success = CheckRange(
                    Dst,
                    Size,
                    MemoryState.Mask,
                    MemoryState.CodeStatic,
                    MemoryPermission.None,
                    MemoryPermission.None,
                    MemoryAttribute.Mask,
                    MemoryAttribute.None,
                    MemoryAttribute.IpcAndDeviceMapped,
                    out _,
                    out _,
                    out _);

                Success &= CheckRange(
                    Src,
                    Size,
                    MemoryState.Mask,
                    MemoryState.Heap,
                    MemoryPermission.Mask,
                    MemoryPermission.None,
                    MemoryAttribute.Mask,
                    MemoryAttribute.None,
                    MemoryAttribute.IpcAndDeviceMapped,
                    out _,
                    out _,
                    out _);

                if (Success)
                {
                    InsertBlock(Dst, PagesCount, MemoryState.Unmapped);
                    InsertBlock(Src, PagesCount, MemoryState.Heap, MemoryPermission.ReadAndWrite);

                    CpuMemory.Unmap(Dst, Size);

                    return(0);
                }
            }

            return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
        }
示例#2
0
        public long TrySetHeapSize(long Size, out long Position)
        {
            Position = 0;

            if ((ulong)Size > (ulong)(HeapRegionEnd - HeapRegionStart))
            {
                return(MakeError(ErrorModule.Kernel, KernelErr.OutOfMemory));
            }

            bool Success = false;

            long CurrentHeapSize = GetHeapSize();

            if ((ulong)CurrentHeapSize <= (ulong)Size)
            {
                //Expand.
                long DiffSize = Size - CurrentHeapSize;

                lock (Blocks)
                {
                    if (Success = IsUnmapped(CurrentHeapAddr, DiffSize))
                    {
                        if (!Allocator.TryAllocate(DiffSize, out long PA))
                        {
                            return(MakeError(ErrorModule.Kernel, KernelErr.OutOfMemory));
                        }

                        long PagesCount = DiffSize / PageSize;

                        InsertBlock(CurrentHeapAddr, PagesCount, MemoryState.Heap, MemoryPermission.ReadAndWrite);

                        CpuMemory.Map(CurrentHeapAddr, PA, DiffSize);
                    }
                }
            }
            else
            {
                //Shrink.
                long FreeAddr = HeapRegionStart + Size;
                long DiffSize = CurrentHeapSize - Size;

                lock (Blocks)
                {
                    Success = CheckRange(
                        FreeAddr,
                        DiffSize,
                        MemoryState.Mask,
                        MemoryState.Heap,
                        MemoryPermission.Mask,
                        MemoryPermission.ReadAndWrite,
                        MemoryAttribute.Mask,
                        MemoryAttribute.None,
                        MemoryAttribute.IpcAndDeviceMapped,
                        out _,
                        out _,
                        out _);

                    if (Success)
                    {
                        long PagesCount = DiffSize / PageSize;

                        InsertBlock(FreeAddr, PagesCount, MemoryState.Unmapped);

                        FreePages(FreeAddr, PagesCount);

                        CpuMemory.Unmap(FreeAddr, DiffSize);
                    }
                }
            }

            CurrentHeapAddr = HeapRegionStart + Size;

            if (Success)
            {
                Position = HeapRegionStart;

                return(0);
            }

            return(MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm));
        }