public KMemoryRegionManager(ulong address, ulong size, ulong endAddr) { Address = address; Size = size; _pageReferenceCounts = new ushort[size / KPageTableBase.PageSize]; _pageHeap = new KPageHeap(address, size); _pageHeap.Free(address, size / KPageTableBase.PageSize); _pageHeap.UpdateUsedSize(); }
private KernelResult AllocatePagesImpl(out KPageList pageList, ulong pagesCount, bool random) { pageList = new KPageList(); int heapIndex = KPageHeap.GetBlockIndex(pagesCount); if (heapIndex < 0) { return(KernelResult.OutOfMemory); } for (int index = heapIndex; index >= 0; index--) { ulong pagesPerAlloc = KPageHeap.GetBlockPagesCount(index); while (pagesCount >= pagesPerAlloc) { ulong allocatedBlock = _pageHeap.AllocateBlock(index, random); if (allocatedBlock == 0) { break; } KernelResult result = pageList.AddRange(allocatedBlock, pagesPerAlloc); if (result != KernelResult.Success) { FreePages(pageList); _pageHeap.Free(allocatedBlock, pagesPerAlloc); return(result); } pagesCount -= pagesPerAlloc; } } if (pagesCount != 0) { FreePages(pageList); return(KernelResult.OutOfMemory); } return(KernelResult.Success); }
private ulong AllocatePagesContiguousImpl(ulong pagesCount, ulong alignPages, bool random) { int heapIndex = KPageHeap.GetAlignedBlockIndex(pagesCount, alignPages); ulong allocatedBlock = _pageHeap.AllocateBlock(heapIndex, random); if (allocatedBlock == 0) { return(0); } ulong allocatedPages = KPageHeap.GetBlockPagesCount(heapIndex); if (allocatedPages > pagesCount) { _pageHeap.Free(allocatedBlock + pagesCount * KPageTableBase.PageSize, allocatedPages - pagesCount); } return(allocatedBlock); }