k_class_token.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/bit_util.h"
  7. #include "common/common_types.h"
  8. namespace Kernel {
  9. class KAutoObject;
  10. class KClassTokenGenerator {
  11. public:
  12. using TokenBaseType = u16;
  13. public:
  14. static constexpr size_t BaseClassBits = 8;
  15. static constexpr size_t FinalClassBits = (sizeof(TokenBaseType) * CHAR_BIT) - BaseClassBits;
  16. // One bit per base class.
  17. static constexpr size_t NumBaseClasses = BaseClassBits;
  18. // Final classes are permutations of three bits.
  19. static constexpr size_t NumFinalClasses = [] {
  20. TokenBaseType index = 0;
  21. for (size_t i = 0; i < FinalClassBits; i++) {
  22. for (size_t j = i + 1; j < FinalClassBits; j++) {
  23. for (size_t k = j + 1; k < FinalClassBits; k++) {
  24. index++;
  25. }
  26. }
  27. }
  28. return index;
  29. }();
  30. private:
  31. template <TokenBaseType Index>
  32. static constexpr inline TokenBaseType BaseClassToken = 1U << Index;
  33. template <TokenBaseType Index>
  34. static constexpr inline TokenBaseType FinalClassToken = [] {
  35. TokenBaseType index = 0;
  36. for (size_t i = 0; i < FinalClassBits; i++) {
  37. for (size_t j = i + 1; j < FinalClassBits; j++) {
  38. for (size_t k = j + 1; k < FinalClassBits; k++) {
  39. if ((index++) == Index) {
  40. return static_cast<TokenBaseType>(((1ULL << i) | (1ULL << j) | (1ULL << k))
  41. << BaseClassBits);
  42. }
  43. }
  44. }
  45. }
  46. }();
  47. template <typename T>
  48. static constexpr inline TokenBaseType GetClassToken() {
  49. static_assert(std::is_base_of<KAutoObject, T>::value);
  50. if constexpr (std::is_same<T, KAutoObject>::value) {
  51. static_assert(T::ObjectType == ObjectType::KAutoObject);
  52. return 0;
  53. } else if constexpr (!std::is_final<T>::value) {
  54. static_assert(ObjectType::BaseClassesStart <= T::ObjectType &&
  55. T::ObjectType < ObjectType::BaseClassesEnd);
  56. constexpr auto ClassIndex = static_cast<TokenBaseType>(T::ObjectType) -
  57. static_cast<TokenBaseType>(ObjectType::BaseClassesStart);
  58. return BaseClassToken<ClassIndex> | GetClassToken<typename T::BaseClass>();
  59. } else if constexpr (ObjectType::FinalClassesStart <= T::ObjectType &&
  60. T::ObjectType < ObjectType::FinalClassesEnd) {
  61. constexpr auto ClassIndex = static_cast<TokenBaseType>(T::ObjectType) -
  62. static_cast<TokenBaseType>(ObjectType::FinalClassesStart);
  63. return FinalClassToken<ClassIndex> | GetClassToken<typename T::BaseClass>();
  64. } else {
  65. static_assert(!std::is_same<T, T>::value, "GetClassToken: Invalid Type");
  66. }
  67. };
  68. public:
  69. enum class ObjectType {
  70. KAutoObject,
  71. BaseClassesStart,
  72. KSynchronizationObject = BaseClassesStart,
  73. KReadableEvent,
  74. BaseClassesEnd,
  75. FinalClassesStart = BaseClassesEnd,
  76. KInterruptEvent = FinalClassesStart,
  77. KDebug,
  78. KThread,
  79. KServerPort,
  80. KServerSession,
  81. KClientPort,
  82. KClientSession,
  83. KProcess,
  84. KResourceLimit,
  85. KLightSession,
  86. KPort,
  87. KSession,
  88. KSharedMemory,
  89. KEvent,
  90. KWritableEvent,
  91. KLightClientSession,
  92. KLightServerSession,
  93. KTransferMemory,
  94. KDeviceAddressSpace,
  95. KSessionRequest,
  96. KCodeMemory,
  97. // NOTE: True order for these has not been determined yet.
  98. KAlpha,
  99. KBeta,
  100. FinalClassesEnd = FinalClassesStart + NumFinalClasses,
  101. };
  102. template <typename T>
  103. static constexpr inline TokenBaseType ClassToken = GetClassToken<T>();
  104. };
  105. using ClassTokenType = KClassTokenGenerator::TokenBaseType;
  106. template <typename T>
  107. static constexpr inline ClassTokenType ClassToken = KClassTokenGenerator::ClassToken<T>;
  108. } // namespace Kernel