AnonymousVMObject.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <Kernel/Memory/AllocationStrategy.h>
  8. #include <Kernel/Memory/MemoryManager.h>
  9. #include <Kernel/Memory/PageFaultResponse.h>
  10. #include <Kernel/Memory/VMObject.h>
  11. #include <Kernel/PhysicalAddress.h>
  12. namespace Kernel::Memory {
  13. class AnonymousVMObject final : public VMObject {
  14. public:
  15. virtual ~AnonymousVMObject() override;
  16. static KResultOr<NonnullRefPtr<AnonymousVMObject>> try_create_with_size(size_t, AllocationStrategy);
  17. static KResultOr<NonnullRefPtr<AnonymousVMObject>> try_create_for_physical_range(PhysicalAddress paddr, size_t size);
  18. static KResultOr<NonnullRefPtr<AnonymousVMObject>> try_create_with_physical_pages(Span<NonnullRefPtr<PhysicalPage>>);
  19. static KResultOr<NonnullRefPtr<AnonymousVMObject>> try_create_purgeable_with_size(size_t, AllocationStrategy);
  20. static KResultOr<NonnullRefPtr<AnonymousVMObject>> try_create_physically_contiguous_with_size(size_t);
  21. virtual KResultOr<NonnullRefPtr<VMObject>> try_clone() override;
  22. [[nodiscard]] NonnullRefPtr<PhysicalPage> allocate_committed_page(Badge<Region>);
  23. PageFaultResponse handle_cow_fault(size_t, VirtualAddress);
  24. size_t cow_pages() const;
  25. bool should_cow(size_t page_index, bool) const;
  26. void set_should_cow(size_t page_index, bool);
  27. bool is_purgeable() const { return m_purgeable; }
  28. bool is_volatile() const { return m_volatile; }
  29. KResult set_volatile(bool is_volatile, bool& was_purged);
  30. size_t purge();
  31. private:
  32. class SharedCommittedCowPages;
  33. explicit AnonymousVMObject(size_t, AllocationStrategy, Optional<CommittedPhysicalPageSet>);
  34. explicit AnonymousVMObject(PhysicalAddress, size_t);
  35. explicit AnonymousVMObject(Span<NonnullRefPtr<PhysicalPage>>);
  36. explicit AnonymousVMObject(AnonymousVMObject const&, NonnullRefPtr<SharedCommittedCowPages>);
  37. virtual StringView class_name() const override { return "AnonymousVMObject"sv; }
  38. AnonymousVMObject& operator=(AnonymousVMObject const&) = delete;
  39. AnonymousVMObject& operator=(AnonymousVMObject&&) = delete;
  40. AnonymousVMObject(AnonymousVMObject&&) = delete;
  41. virtual bool is_anonymous() const override { return true; }
  42. Bitmap& ensure_cow_map();
  43. void ensure_or_reset_cow_map();
  44. Optional<CommittedPhysicalPageSet> m_unused_committed_pages;
  45. Bitmap m_cow_map;
  46. // AnonymousVMObject shares committed COW pages with cloned children (happens on fork)
  47. class SharedCommittedCowPages : public RefCounted<SharedCommittedCowPages> {
  48. AK_MAKE_NONCOPYABLE(SharedCommittedCowPages);
  49. public:
  50. SharedCommittedCowPages() = delete;
  51. explicit SharedCommittedCowPages(CommittedPhysicalPageSet&&);
  52. ~SharedCommittedCowPages();
  53. [[nodiscard]] bool is_empty() const { return m_committed_pages.is_empty(); }
  54. [[nodiscard]] NonnullRefPtr<PhysicalPage> take_one();
  55. void uncommit_one();
  56. public:
  57. Spinlock<u8> m_lock;
  58. CommittedPhysicalPageSet m_committed_pages;
  59. };
  60. RefPtr<SharedCommittedCowPages> m_shared_committed_cow_pages;
  61. bool m_purgeable { false };
  62. bool m_volatile { false };
  63. bool m_was_purged { false };
  64. };
  65. }