kernel.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2014 Citra Emulator Project / PPSSPP Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include "common/common.h"
  5. #include "core/core.h"
  6. #include "core/hle/kernel/kernel.h"
  7. #include "core/hle/kernel/thread.h"
  8. #include "core/hle/kernel/archive.h"
  9. namespace Kernel {
  10. Handle g_main_thread = 0;
  11. ObjectPool g_object_pool;
  12. ObjectPool::ObjectPool() {
  13. next_id = INITIAL_NEXT_ID;
  14. }
  15. Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) {
  16. if (range_top > MAX_COUNT) {
  17. range_top = MAX_COUNT;
  18. }
  19. if (next_id >= range_bottom && next_id < range_top) {
  20. range_bottom = next_id++;
  21. }
  22. for (int i = range_bottom; i < range_top; i++) {
  23. if (!occupied[i]) {
  24. occupied[i] = true;
  25. pool[i] = obj;
  26. pool[i]->handle = i + HANDLE_OFFSET;
  27. return i + HANDLE_OFFSET;
  28. }
  29. }
  30. ERROR_LOG(HLE, "Unable to allocate kernel object, too many objects slots in use.");
  31. return 0;
  32. }
  33. bool ObjectPool::IsValid(Handle handle) const {
  34. int index = handle - HANDLE_OFFSET;
  35. if (index < 0)
  36. return false;
  37. if (index >= MAX_COUNT)
  38. return false;
  39. return occupied[index];
  40. }
  41. void ObjectPool::Clear() {
  42. for (int i = 0; i < MAX_COUNT; i++) {
  43. //brutally clear everything, no validation
  44. if (occupied[i])
  45. delete pool[i];
  46. occupied[i] = false;
  47. }
  48. pool.fill(nullptr);
  49. next_id = INITIAL_NEXT_ID;
  50. }
  51. Object* &ObjectPool::operator [](Handle handle)
  52. {
  53. _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
  54. return pool[handle - HANDLE_OFFSET];
  55. }
  56. void ObjectPool::List() {
  57. for (int i = 0; i < MAX_COUNT; i++) {
  58. if (occupied[i]) {
  59. if (pool[i]) {
  60. INFO_LOG(KERNEL, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(),
  61. pool[i]->GetName().c_str());
  62. }
  63. }
  64. }
  65. }
  66. int ObjectPool::GetCount() const {
  67. int count = 0;
  68. for (int i = 0; i < MAX_COUNT; i++) {
  69. if (occupied[i])
  70. count++;
  71. }
  72. return count;
  73. }
  74. Object* ObjectPool::CreateByIDType(int type) {
  75. ERROR_LOG(COMMON, "Unimplemented: %d.", type);
  76. return nullptr;
  77. }
  78. /// Initialize the kernel
  79. void Init() {
  80. Kernel::ThreadingInit();
  81. Kernel::ArchiveInit();
  82. }
  83. /// Shutdown the kernel
  84. void Shutdown() {
  85. Kernel::ThreadingShutdown();
  86. Kernel::ArchiveShutdown();
  87. g_object_pool.Clear(); // Free all kernel objects
  88. }
  89. /**
  90. * Loads executable stored at specified address
  91. * @entry_point Entry point in memory of loaded executable
  92. * @return True on success, otherwise false
  93. */
  94. bool LoadExec(u32 entry_point) {
  95. Init();
  96. Core::g_app_core->SetPC(entry_point);
  97. // 0x30 is the typical main thread priority I've seen used so far
  98. g_main_thread = Kernel::SetupMainThread(0x30);
  99. return true;
  100. }
  101. } // namespace