kernel.cpp 2.8 KB

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