slab_helpers.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include "core/hle/kernel/k_auto_object.h"
  5. #include "core/hle/kernel/k_auto_object_container.h"
  6. #include "core/hle/kernel/kernel.h"
  7. namespace Kernel {
  8. template <class Derived>
  9. class KSlabAllocated {
  10. public:
  11. constexpr KSlabAllocated() = default;
  12. size_t GetSlabIndex(KernelCore& kernel) const {
  13. return kernel.SlabHeap<Derived>().GetIndex(static_cast<const Derived*>(this));
  14. }
  15. public:
  16. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  17. kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
  18. }
  19. static Derived* Allocate(KernelCore& kernel) {
  20. return kernel.SlabHeap<Derived>().Allocate(kernel);
  21. }
  22. static void Free(KernelCore& kernel, Derived* obj) {
  23. kernel.SlabHeap<Derived>().Free(obj);
  24. }
  25. static size_t GetObjectSize(KernelCore& kernel) {
  26. return kernel.SlabHeap<Derived>().GetObjectSize();
  27. }
  28. static size_t GetSlabHeapSize(KernelCore& kernel) {
  29. return kernel.SlabHeap<Derived>().GetSlabHeapSize();
  30. }
  31. static size_t GetPeakIndex(KernelCore& kernel) {
  32. return kernel.SlabHeap<Derived>().GetPeakIndex();
  33. }
  34. static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
  35. return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
  36. }
  37. static size_t GetNumRemaining(KernelCore& kernel) {
  38. return kernel.SlabHeap<Derived>().GetNumRemaining();
  39. }
  40. };
  41. template <typename Derived, typename Base>
  42. class KAutoObjectWithSlabHeap : public Base {
  43. static_assert(std::is_base_of<KAutoObject, Base>::value);
  44. private:
  45. static Derived* Allocate(KernelCore& kernel) {
  46. return kernel.SlabHeap<Derived>().Allocate(kernel);
  47. }
  48. static void Free(KernelCore& kernel, Derived* obj) {
  49. kernel.SlabHeap<Derived>().Free(obj);
  50. }
  51. public:
  52. explicit KAutoObjectWithSlabHeap(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {}
  53. virtual ~KAutoObjectWithSlabHeap() = default;
  54. virtual void Destroy() override {
  55. const bool is_initialized = this->IsInitialized();
  56. uintptr_t arg = 0;
  57. if (is_initialized) {
  58. arg = this->GetPostDestroyArgument();
  59. this->Finalize();
  60. }
  61. Free(kernel, static_cast<Derived*>(this));
  62. if (is_initialized) {
  63. Derived::PostDestroy(arg);
  64. }
  65. }
  66. virtual bool IsInitialized() const {
  67. return true;
  68. }
  69. virtual uintptr_t GetPostDestroyArgument() const {
  70. return 0;
  71. }
  72. size_t GetSlabIndex() const {
  73. return SlabHeap<Derived>(kernel).GetObjectIndex(static_cast<const Derived*>(this));
  74. }
  75. public:
  76. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  77. kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
  78. }
  79. static Derived* Create(KernelCore& kernel) {
  80. Derived* obj = Allocate(kernel);
  81. if (obj != nullptr) {
  82. KAutoObject::Create(obj);
  83. }
  84. return obj;
  85. }
  86. static size_t GetObjectSize(KernelCore& kernel) {
  87. return kernel.SlabHeap<Derived>().GetObjectSize();
  88. }
  89. static size_t GetSlabHeapSize(KernelCore& kernel) {
  90. return kernel.SlabHeap<Derived>().GetSlabHeapSize();
  91. }
  92. static size_t GetPeakIndex(KernelCore& kernel) {
  93. return kernel.SlabHeap<Derived>().GetPeakIndex();
  94. }
  95. static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
  96. return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
  97. }
  98. static size_t GetNumRemaining(KernelCore& kernel) {
  99. return kernel.SlabHeap<Derived>().GetNumRemaining();
  100. }
  101. protected:
  102. KernelCore& kernel;
  103. };
  104. template <typename Derived, typename Base>
  105. class KAutoObjectWithSlabHeapAndContainer : public Base {
  106. static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
  107. private:
  108. static Derived* Allocate(KernelCore& kernel) {
  109. return kernel.SlabHeap<Derived>().Allocate(kernel);
  110. }
  111. static void Free(KernelCore& kernel, Derived* obj) {
  112. kernel.SlabHeap<Derived>().Free(obj);
  113. }
  114. public:
  115. KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {}
  116. virtual ~KAutoObjectWithSlabHeapAndContainer() {}
  117. virtual void Destroy() override {
  118. const bool is_initialized = this->IsInitialized();
  119. uintptr_t arg = 0;
  120. if (is_initialized) {
  121. kernel.ObjectListContainer().Unregister(this);
  122. arg = this->GetPostDestroyArgument();
  123. this->Finalize();
  124. }
  125. Free(kernel, static_cast<Derived*>(this));
  126. if (is_initialized) {
  127. Derived::PostDestroy(arg);
  128. }
  129. }
  130. virtual bool IsInitialized() const {
  131. return true;
  132. }
  133. virtual uintptr_t GetPostDestroyArgument() const {
  134. return 0;
  135. }
  136. size_t GetSlabIndex() const {
  137. return SlabHeap<Derived>(kernel).GetObjectIndex(static_cast<const Derived*>(this));
  138. }
  139. public:
  140. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  141. kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
  142. kernel.ObjectListContainer().Initialize();
  143. }
  144. static Derived* Create(KernelCore& kernel) {
  145. Derived* obj = Allocate(kernel);
  146. if (obj != nullptr) {
  147. KAutoObject::Create(obj);
  148. }
  149. return obj;
  150. }
  151. static void Register(KernelCore& kernel, Derived* obj) {
  152. return kernel.ObjectListContainer().Register(obj);
  153. }
  154. static size_t GetObjectSize(KernelCore& kernel) {
  155. return kernel.SlabHeap<Derived>().GetObjectSize();
  156. }
  157. static size_t GetSlabHeapSize(KernelCore& kernel) {
  158. return kernel.SlabHeap<Derived>().GetSlabHeapSize();
  159. }
  160. static size_t GetPeakIndex(KernelCore& kernel) {
  161. return kernel.SlabHeap<Derived>().GetPeakIndex();
  162. }
  163. static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
  164. return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
  165. }
  166. static size_t GetNumRemaining(KernelCore& kernel) {
  167. return kernel.SlabHeap<Derived>().GetNumRemaining();
  168. }
  169. protected:
  170. KernelCore& kernel;
  171. };
  172. } // namespace Kernel