PhysicalPage.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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 <AK/NonnullRefPtr.h>
  8. #include <Kernel/PhysicalAddress.h>
  9. namespace Kernel::Memory {
  10. enum class MayReturnToFreeList : bool {
  11. No,
  12. Yes
  13. };
  14. class PhysicalPage {
  15. AK_MAKE_NONCOPYABLE(PhysicalPage);
  16. AK_MAKE_NONMOVABLE(PhysicalPage);
  17. friend class MemoryManager;
  18. public:
  19. PhysicalAddress paddr() const;
  20. void ref()
  21. {
  22. m_ref_count.fetch_add(1, AK::memory_order_acq_rel);
  23. }
  24. void unref()
  25. {
  26. if (m_ref_count.fetch_sub(1, AK::memory_order_acq_rel) == 1)
  27. free_this();
  28. }
  29. static NonnullRefPtr<PhysicalPage> create(PhysicalAddress, MayReturnToFreeList may_return_to_freelist = MayReturnToFreeList::Yes);
  30. u32 ref_count() const { return m_ref_count.load(AK::memory_order_consume); }
  31. bool is_shared_zero_page() const;
  32. bool is_lazy_committed_page() const;
  33. private:
  34. explicit PhysicalPage(MayReturnToFreeList may_return_to_freelist);
  35. ~PhysicalPage() = default;
  36. void free_this();
  37. Atomic<u32> m_ref_count { 1 };
  38. MayReturnToFreeList m_may_return_to_freelist { MayReturnToFreeList::Yes };
  39. };
  40. struct PhysicalPageEntry {
  41. union {
  42. // If it's a live PhysicalPage object:
  43. struct {
  44. PhysicalPage physical_page;
  45. } allocated;
  46. // If it's an entry in a PhysicalZone::Bucket's freelist.
  47. struct {
  48. i16 next_index;
  49. i16 prev_index;
  50. } freelist;
  51. };
  52. };
  53. }