VMObject.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/FixedArray.h>
  8. #include <AK/IntrusiveList.h>
  9. #include <AK/RefPtr.h>
  10. #include <AK/Weakable.h>
  11. #include <Kernel/Forward.h>
  12. #include <Kernel/Library/ListedRefCounted.h>
  13. #include <Kernel/Locking/Mutex.h>
  14. #include <Kernel/Memory/Region.h>
  15. namespace Kernel::Memory {
  16. class VMObject
  17. : public ListedRefCounted<VMObject>
  18. , public Weakable<VMObject> {
  19. friend class MemoryManager;
  20. friend class Region;
  21. public:
  22. virtual ~VMObject();
  23. virtual KResultOr<NonnullRefPtr<VMObject>> try_clone() = 0;
  24. virtual bool is_anonymous() const { return false; }
  25. virtual bool is_inode() const { return false; }
  26. virtual bool is_shared_inode() const { return false; }
  27. virtual bool is_private_inode() const { return false; }
  28. size_t page_count() const { return m_physical_pages.size(); }
  29. Span<RefPtr<PhysicalPage> const> physical_pages() const { return m_physical_pages.span(); }
  30. Span<RefPtr<PhysicalPage>> physical_pages() { return m_physical_pages.span(); }
  31. size_t size() const { return m_physical_pages.size() * PAGE_SIZE; }
  32. virtual StringView class_name() const = 0;
  33. ALWAYS_INLINE void add_region(Region& region)
  34. {
  35. SpinlockLocker locker(m_lock);
  36. m_regions.append(region);
  37. }
  38. ALWAYS_INLINE void remove_region(Region& region)
  39. {
  40. SpinlockLocker locker(m_lock);
  41. m_regions.remove(region);
  42. }
  43. protected:
  44. explicit VMObject(size_t);
  45. explicit VMObject(VMObject const&);
  46. template<typename Callback>
  47. void for_each_region(Callback);
  48. IntrusiveListNode<VMObject> m_list_node;
  49. FixedArray<RefPtr<PhysicalPage>> m_physical_pages;
  50. mutable RecursiveSpinlock m_lock;
  51. private:
  52. VMObject& operator=(VMObject const&) = delete;
  53. VMObject& operator=(VMObject&&) = delete;
  54. VMObject(VMObject&&) = delete;
  55. Region::ListInVMObject m_regions;
  56. public:
  57. using AllInstancesList = IntrusiveList<VMObject, RawPtr<VMObject>, &VMObject::m_list_node>;
  58. static SpinlockProtected<VMObject::AllInstancesList>& all_instances();
  59. };
  60. template<typename Callback>
  61. inline void VMObject::for_each_region(Callback callback)
  62. {
  63. SpinlockLocker lock(m_lock);
  64. for (auto& region : m_regions) {
  65. callback(region);
  66. }
  67. }
  68. inline PhysicalPage const* Region::physical_page(size_t index) const
  69. {
  70. VERIFY(index < page_count());
  71. return vmobject().physical_pages()[first_page_index() + index];
  72. }
  73. inline RefPtr<PhysicalPage>& Region::physical_page_slot(size_t index)
  74. {
  75. VERIFY(index < page_count());
  76. return vmobject().physical_pages()[first_page_index() + index];
  77. }
  78. }