slab_helpers.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. public:
  19. constexpr KSlabAllocated() = default;
  20. size_t GetSlabIndex(KernelCore& kernel) const {
  21. return kernel.SlabHeap<Derived>().GetIndex(static_cast<const Derived*>(this));
  22. }
  23. public:
  24. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  25. kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
  26. }
  27. static Derived* Allocate(KernelCore& kernel) {
  28. return kernel.SlabHeap<Derived>().Allocate();
  29. }
  30. static void Free(KernelCore& kernel, Derived* obj) {
  31. kernel.SlabHeap<Derived>().Free(obj);
  32. }
  33. static size_t GetObjectSize(KernelCore& kernel) {
  34. return kernel.SlabHeap<Derived>().GetObjectSize();
  35. }
  36. static size_t GetSlabHeapSize(KernelCore& kernel) {
  37. return kernel.SlabHeap<Derived>().GetSlabHeapSize();
  38. }
  39. static size_t GetPeakIndex(KernelCore& kernel) {
  40. return kernel.SlabHeap<Derived>().GetPeakIndex();
  41. }
  42. static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
  43. return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
  44. }
  45. static size_t GetNumRemaining(KernelCore& kernel) {
  46. return kernel.SlabHeap<Derived>().GetNumRemaining();
  47. }
  48. };
  49. template <typename Derived, typename Base>
  50. class KAutoObjectWithSlabHeapAndContainer : public Base {
  51. static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
  52. private:
  53. static Derived* Allocate(KernelCore& kernel) {
  54. return kernel.SlabHeap<Derived>().AllocateWithKernel(kernel);
  55. }
  56. static void Free(KernelCore& kernel, Derived* obj) {
  57. kernel.SlabHeap<Derived>().Free(obj);
  58. }
  59. public:
  60. KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {}
  61. virtual ~KAutoObjectWithSlabHeapAndContainer() {}
  62. virtual void Destroy() override {
  63. const bool is_initialized = this->IsInitialized();
  64. uintptr_t arg = 0;
  65. if (is_initialized) {
  66. kernel.ObjectListContainer().Unregister(this);
  67. arg = this->GetPostDestroyArgument();
  68. this->Finalize();
  69. }
  70. Free(kernel, static_cast<Derived*>(this));
  71. if (is_initialized) {
  72. Derived::PostDestroy(arg);
  73. }
  74. }
  75. virtual bool IsInitialized() const {
  76. return true;
  77. }
  78. virtual uintptr_t GetPostDestroyArgument() const {
  79. return 0;
  80. }
  81. size_t GetSlabIndex() const {
  82. return SlabHeap<Derived>(kernel).GetObjectIndex(static_cast<const Derived*>(this));
  83. }
  84. public:
  85. static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
  86. kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
  87. kernel.ObjectListContainer().Initialize();
  88. }
  89. static Derived* Create(KernelCore& kernel) {
  90. Derived* obj = Allocate(kernel);
  91. if (obj != nullptr) {
  92. KAutoObject::Create(obj);
  93. }
  94. return obj;
  95. }
  96. static void Register(KernelCore& kernel, Derived* obj) {
  97. return kernel.ObjectListContainer().Register(obj);
  98. }
  99. static size_t GetObjectSize(KernelCore& kernel) {
  100. return kernel.SlabHeap<Derived>().GetObjectSize();
  101. }
  102. static size_t GetSlabHeapSize(KernelCore& kernel) {
  103. return kernel.SlabHeap<Derived>().GetSlabHeapSize();
  104. }
  105. static size_t GetPeakIndex(KernelCore& kernel) {
  106. return kernel.SlabHeap<Derived>().GetPeakIndex();
  107. }
  108. static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
  109. return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
  110. }
  111. static size_t GetNumRemaining(KernelCore& kernel) {
  112. return kernel.SlabHeap<Derived>().GetNumRemaining();
  113. }
  114. protected:
  115. KernelCore& kernel;
  116. };
  117. } // namespace Kernel