/* * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace Kernel::Memory { enum class RandomizeVirtualAddress { No, Yes, }; // RegionTree represents a virtual address space. // It is used by MemoryManager for kernel VM and by AddressSpace for user VM. // Regions are stored in an intrusive data structure and there are no allocations when interacting with it. class RegionTree { AK_MAKE_NONCOPYABLE(RegionTree); AK_MAKE_NONMOVABLE(RegionTree); public: explicit RegionTree(VirtualRange total_range) : m_total_range(total_range) { } ~RegionTree(); auto& regions() { return m_regions; } auto const& regions() const { return m_regions; } VirtualRange total_range() const { return m_total_range; } ErrorOr place_anywhere(Region&, RandomizeVirtualAddress, size_t size, size_t alignment = PAGE_SIZE); ErrorOr place_specifically(Region&, VirtualRange const&); void delete_all_regions_assuming_they_are_unmapped(); // FIXME: Access the region tree through a SpinlockProtected or similar. RecursiveSpinlock& get_lock() const { return m_lock; } bool remove(Region&); Region* find_region_containing(VirtualAddress); Region* find_region_containing(VirtualRange); private: ErrorOr allocate_range_anywhere(size_t size, size_t alignment = PAGE_SIZE); ErrorOr allocate_range_specific(VirtualAddress base, size_t size); ErrorOr allocate_range_randomized(size_t size, size_t alignment = PAGE_SIZE); RecursiveSpinlock mutable m_lock; IntrusiveRedBlackTree<&Region::m_tree_node> m_regions; VirtualRange const m_total_range; }; }