slab_helpers.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <atomic>
  6. #include "common/assert.h"
  7. #include "common/common_funcs.h"
  8. #include "common/common_types.h"
  9. #include "common/intrusive_red_black_tree.h"
  10. #include "core/hle/kernel/k_auto_object.h"
  11. #include "core/hle/kernel/k_auto_object_container.h"
  12. #include "core/hle/kernel/k_light_lock.h"
  13. #include "core/hle/kernel/k_slab_heap.h"
  14. #include "core/hle/kernel/kernel.h"
  15. namespace Kernel {
  16. template <class Derived>
  17. class KSlabAllocated {
  18. private:
  19. static inline KSlabHeap<Derived> s_slab_heap;
  20. public:
  21. constexpr KSlabAllocated() = default;
  22. size_t GetSlabIndex() const {
  23. return s_slab_heap.GetIndex(static_cast<const Derived*>(this));
  24. }
  25. public:
  26. static void InitializeSlabHeap(void* memory, size_t memory_size) {
  27. s_slab_heap.Initialize(memory, memory_size);
  28. }
  29. static Derived* Allocate() {
  30. return s_slab_heap.Allocate();
  31. }
  32. static void Free(Derived* obj) {
  33. s_slab_heap.Free(obj);
  34. }
  35. static size_t GetObjectSize() {
  36. return s_slab_heap.GetObjectSize();
  37. }
  38. static size_t GetSlabHeapSize() {
  39. return s_slab_heap.GetSlabHeapSize();
  40. }
  41. static size_t GetPeakIndex() {
  42. return s_slab_heap.GetPeakIndex();
  43. }
  44. static uintptr_t GetSlabHeapAddress() {
  45. return s_slab_heap.GetSlabHeapAddress();
  46. }
  47. static size_t GetNumRemaining() {
  48. return s_slab_heap.GetNumRemaining();
  49. }
  50. };
  51. template <typename Derived, typename Base>
  52. class KAutoObjectWithSlabHeapAndContainer : public Base {
  53. static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
  54. private:
  55. static inline KSlabHeap<Derived> s_slab_heap;
  56. KernelCore& m_kernel;
  57. private:
  58. static Derived* Allocate() {
  59. return s_slab_heap.Allocate();
  60. }
  61. static Derived* AllocateWithKernel(KernelCore& kernel) {
  62. return s_slab_heap.AllocateWithKernel(kernel);
  63. }
  64. static void Free(Derived* obj) {
  65. s_slab_heap.Free(obj);
  66. }
  67. public:
  68. class ListAccessor : public KAutoObjectWithListContainer::ListAccessor {
  69. public:
  70. ListAccessor()
  71. : KAutoObjectWithListContainer::ListAccessor(m_kernel.ObjectListContainer()) {}
  72. ~ListAccessor() = default;
  73. };
  74. public:
  75. KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel) : Base(kernel), m_kernel(kernel) {}
  76. virtual ~KAutoObjectWithSlabHeapAndContainer() {}
  77. virtual void Destroy() override {
  78. const bool is_initialized = this->IsInitialized();
  79. uintptr_t arg = 0;
  80. if (is_initialized) {
  81. m_kernel.ObjectListContainer().Unregister(this);
  82. arg = this->GetPostDestroyArgument();
  83. this->Finalize();
  84. }
  85. Free(static_cast<Derived*>(this));
  86. if (is_initialized) {
  87. Derived::PostDestroy(arg);
  88. }
  89. }
  90. virtual bool IsInitialized() const {
  91. return true;
  92. }
  93. virtual uintptr_t GetPostDestroyArgument() const {
  94. return 0;
  95. }
  96. size_t GetSlabIndex() const {
  97. return s_slab_heap.GetObjectIndex(static_cast<const Derived*>(this));
  98. }
  99. public:
  100. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  101. s_slab_heap.Initialize(memory, memory_size);
  102. kernel.ObjectListContainer().Initialize();
  103. }
  104. static Derived* Create() {
  105. Derived* obj = Allocate();
  106. if (obj != nullptr) {
  107. KAutoObject::Create(obj);
  108. }
  109. return obj;
  110. }
  111. static Derived* CreateWithKernel(KernelCore& kernel) {
  112. Derived* obj = AllocateWithKernel(kernel);
  113. if (obj != nullptr) {
  114. KAutoObject::Create(obj);
  115. }
  116. return obj;
  117. }
  118. static void Register(KernelCore& kernel, Derived* obj) {
  119. return kernel.ObjectListContainer().Register(obj);
  120. }
  121. static size_t GetObjectSize() {
  122. return s_slab_heap.GetObjectSize();
  123. }
  124. static size_t GetSlabHeapSize() {
  125. return s_slab_heap.GetSlabHeapSize();
  126. }
  127. static size_t GetPeakIndex() {
  128. return s_slab_heap.GetPeakIndex();
  129. }
  130. static uintptr_t GetSlabHeapAddress() {
  131. return s_slab_heap.GetSlabHeapAddress();
  132. }
  133. static size_t GetNumRemaining() {
  134. return s_slab_heap.GetNumRemaining();
  135. }
  136. };
  137. } // namespace Kernel