diff options
| author | 2014-12-29 19:47:41 -0800 | |
|---|---|---|
| committer | 2014-12-29 19:47:41 -0800 | |
| commit | 8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch) | |
| tree | f1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/hle/kernel/kernel.cpp | |
| parent | Add comment regarding __WIN32__ in SkyEye code (diff) | |
| parent | Merge pull request #367 from bunnei/usat_ssat (diff) | |
| download | yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip | |
Fix merge conflicts
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 139 |
1 files changed, 74 insertions, 65 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 018000abd..e59ed1b57 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -1,106 +1,117 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project / PPSSPP Project | 1 | // Copyright 2014 Citra Emulator Project |
| 2 | // Licensed under GPLv2 | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | |||
| 5 | #include "common/common.h" | 7 | #include "common/common.h" |
| 6 | 8 | ||
| 7 | #include "core/core.h" | 9 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/kernel.h" |
| 9 | #include "core/hle/kernel/thread.h" | 11 | #include "core/hle/kernel/thread.h" |
| 10 | #include "core/hle/kernel/archive.h" | ||
| 11 | 12 | ||
| 12 | namespace Kernel { | 13 | namespace Kernel { |
| 13 | 14 | ||
| 14 | Handle g_main_thread = 0; | 15 | Handle g_main_thread = 0; |
| 15 | ObjectPool g_object_pool; | 16 | HandleTable g_handle_table; |
| 17 | u64 g_program_id = 0; | ||
| 16 | 18 | ||
| 17 | ObjectPool::ObjectPool() { | 19 | HandleTable::HandleTable() { |
| 18 | next_id = INITIAL_NEXT_ID; | 20 | next_generation = 1; |
| 21 | Clear(); | ||
| 19 | } | 22 | } |
| 20 | 23 | ||
| 21 | Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) { | 24 | ResultVal<Handle> HandleTable::Create(Object* obj) { |
| 22 | if (range_top > MAX_COUNT) { | 25 | _dbg_assert_(Kernel, obj != nullptr); |
| 23 | range_top = MAX_COUNT; | 26 | |
| 24 | } | 27 | u16 slot = next_free_slot; |
| 25 | if (next_id >= range_bottom && next_id < range_top) { | 28 | if (slot >= generations.size()) { |
| 26 | range_bottom = next_id++; | 29 | LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); |
| 27 | } | 30 | return ERR_OUT_OF_HANDLES; |
| 28 | for (int i = range_bottom; i < range_top; i++) { | ||
| 29 | if (!occupied[i]) { | ||
| 30 | occupied[i] = true; | ||
| 31 | pool[i] = obj; | ||
| 32 | pool[i]->handle = i + HANDLE_OFFSET; | ||
| 33 | return i + HANDLE_OFFSET; | ||
| 34 | } | ||
| 35 | } | 31 | } |
| 36 | ERROR_LOG(HLE, "Unable to allocate kernel object, too many objects slots in use."); | 32 | next_free_slot = generations[slot]; |
| 37 | return 0; | 33 | |
| 38 | } | 34 | u16 generation = next_generation++; |
| 39 | 35 | ||
| 40 | bool ObjectPool::IsValid(Handle handle) { | 36 | // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. |
| 41 | int index = handle - HANDLE_OFFSET; | 37 | // CTR-OS doesn't use generation 0, so skip straight to 1. |
| 42 | if (index < 0) | 38 | if (next_generation >= (1 << 15)) next_generation = 1; |
| 43 | return false; | ||
| 44 | if (index >= MAX_COUNT) | ||
| 45 | return false; | ||
| 46 | 39 | ||
| 47 | return occupied[index]; | 40 | generations[slot] = generation; |
| 41 | intrusive_ptr_add_ref(obj); | ||
| 42 | objects[slot] = obj; | ||
| 43 | |||
| 44 | Handle handle = generation | (slot << 15); | ||
| 45 | obj->handle = handle; | ||
| 46 | return MakeResult<Handle>(handle); | ||
| 48 | } | 47 | } |
| 49 | 48 | ||
| 50 | void ObjectPool::Clear() { | 49 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { |
| 51 | for (int i = 0; i < MAX_COUNT; i++) { | 50 | Object* object = GetGeneric(handle); |
| 52 | //brutally clear everything, no validation | 51 | if (object == nullptr) { |
| 53 | if (occupied[i]) | 52 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); |
| 54 | delete pool[i]; | 53 | return ERR_INVALID_HANDLE; |
| 55 | occupied[i] = false; | ||
| 56 | } | 54 | } |
| 57 | pool.fill(nullptr); | 55 | return Create(object); |
| 58 | next_id = INITIAL_NEXT_ID; | 56 | } |
| 57 | |||
| 58 | ResultCode HandleTable::Close(Handle handle) { | ||
| 59 | if (!IsValid(handle)) | ||
| 60 | return ERR_INVALID_HANDLE; | ||
| 61 | |||
| 62 | size_t slot = GetSlot(handle); | ||
| 63 | u16 generation = GetGeneration(handle); | ||
| 64 | |||
| 65 | intrusive_ptr_release(objects[slot]); | ||
| 66 | objects[slot] = nullptr; | ||
| 67 | |||
| 68 | generations[generation] = next_free_slot; | ||
| 69 | next_free_slot = slot; | ||
| 70 | return RESULT_SUCCESS; | ||
| 59 | } | 71 | } |
| 60 | 72 | ||
| 61 | Object* &ObjectPool::operator [](Handle handle) | 73 | bool HandleTable::IsValid(Handle handle) const { |
| 62 | { | 74 | size_t slot = GetSlot(handle); |
| 63 | _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ"); | 75 | u16 generation = GetGeneration(handle); |
| 64 | return pool[handle - HANDLE_OFFSET]; | 76 | |
| 77 | return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; | ||
| 65 | } | 78 | } |
| 66 | 79 | ||
| 67 | void ObjectPool::List() { | 80 | Object* HandleTable::GetGeneric(Handle handle) const { |
| 68 | for (int i = 0; i < MAX_COUNT; i++) { | 81 | if (handle == CurrentThread) { |
| 69 | if (occupied[i]) { | 82 | // TODO(yuriks) Directly return the pointer once this is possible. |
| 70 | if (pool[i]) { | 83 | handle = GetCurrentThreadHandle(); |
| 71 | INFO_LOG(KERNEL, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(), | 84 | } else if (handle == CurrentProcess) { |
| 72 | pool[i]->GetName().c_str()); | 85 | LOG_ERROR(Kernel, "Current process (%08X) pseudo-handle not supported", CurrentProcess); |
| 73 | } | 86 | return nullptr; |
| 74 | } | ||
| 75 | } | 87 | } |
| 76 | } | ||
| 77 | 88 | ||
| 78 | int ObjectPool::GetCount() { | 89 | if (!IsValid(handle)) { |
| 79 | int count = 0; | 90 | return nullptr; |
| 80 | for (int i = 0; i < MAX_COUNT; i++) { | ||
| 81 | if (occupied[i]) | ||
| 82 | count++; | ||
| 83 | } | 91 | } |
| 84 | return count; | 92 | return objects[GetSlot(handle)]; |
| 85 | } | 93 | } |
| 86 | 94 | ||
| 87 | Object* ObjectPool::CreateByIDType(int type) { | 95 | void HandleTable::Clear() { |
| 88 | ERROR_LOG(COMMON, "Unimplemented: %d.", type); | 96 | for (size_t i = 0; i < MAX_COUNT; ++i) { |
| 89 | return nullptr; | 97 | generations[i] = i + 1; |
| 98 | if (objects[i] != nullptr) | ||
| 99 | intrusive_ptr_release(objects[i]); | ||
| 100 | objects[i] = nullptr; | ||
| 101 | } | ||
| 102 | next_free_slot = 0; | ||
| 90 | } | 103 | } |
| 91 | 104 | ||
| 92 | /// Initialize the kernel | 105 | /// Initialize the kernel |
| 93 | void Init() { | 106 | void Init() { |
| 94 | Kernel::ThreadingInit(); | 107 | Kernel::ThreadingInit(); |
| 95 | Kernel::ArchiveInit(); | ||
| 96 | } | 108 | } |
| 97 | 109 | ||
| 98 | /// Shutdown the kernel | 110 | /// Shutdown the kernel |
| 99 | void Shutdown() { | 111 | void Shutdown() { |
| 100 | Kernel::ThreadingShutdown(); | 112 | Kernel::ThreadingShutdown(); |
| 101 | Kernel::ArchiveShutdown(); | ||
| 102 | 113 | ||
| 103 | g_object_pool.Clear(); // Free all kernel objects | 114 | g_handle_table.Clear(); // Free all kernel objects |
| 104 | } | 115 | } |
| 105 | 116 | ||
| 106 | /** | 117 | /** |
| @@ -109,8 +120,6 @@ void Shutdown() { | |||
| 109 | * @return True on success, otherwise false | 120 | * @return True on success, otherwise false |
| 110 | */ | 121 | */ |
| 111 | bool LoadExec(u32 entry_point) { | 122 | bool LoadExec(u32 entry_point) { |
| 112 | Init(); | ||
| 113 | |||
| 114 | Core::g_app_core->SetPC(entry_point); | 123 | Core::g_app_core->SetPC(entry_point); |
| 115 | 124 | ||
| 116 | // 0x30 is the typical main thread priority I've seen used so far | 125 | // 0x30 is the typical main thread priority I've seen used so far |