diff options
Diffstat (limited to 'src')
26 files changed, 152 insertions, 158 deletions
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp index caa6896f9..a9423d6c7 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.cpp +++ b/src/citra_qt/debugger/graphics_framebuffer.cpp | |||
| @@ -158,17 +158,17 @@ void GraphicsFramebufferWidget::OnFramebufferAddressChanged(qint64 new_value) | |||
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | void GraphicsFramebufferWidget::OnFramebufferWidthChanged(unsigned int new_value) | 161 | void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value) |
| 162 | { | 162 | { |
| 163 | if (framebuffer_width != new_value) { | 163 | if (framebuffer_width != static_cast<unsigned>(new_value)) { |
| 164 | framebuffer_width = new_value; | 164 | framebuffer_width = static_cast<unsigned>(new_value); |
| 165 | 165 | ||
| 166 | framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); | 166 | framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); |
| 167 | emit Update(); | 167 | emit Update(); |
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | void GraphicsFramebufferWidget::OnFramebufferHeightChanged(unsigned int new_value) | 171 | void GraphicsFramebufferWidget::OnFramebufferHeightChanged(int new_value) |
| 172 | { | 172 | { |
| 173 | if (framebuffer_height != new_value) { | 173 | if (framebuffer_height != new_value) { |
| 174 | framebuffer_height = new_value; | 174 | framebuffer_height = new_value; |
diff --git a/src/citra_qt/debugger/graphics_framebuffer.h b/src/citra_qt/debugger/graphics_framebuffer.h index 02813525c..56215761e 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.h +++ b/src/citra_qt/debugger/graphics_framebuffer.h | |||
| @@ -62,8 +62,8 @@ public: | |||
| 62 | public slots: | 62 | public slots: |
| 63 | void OnFramebufferSourceChanged(int new_value); | 63 | void OnFramebufferSourceChanged(int new_value); |
| 64 | void OnFramebufferAddressChanged(qint64 new_value); | 64 | void OnFramebufferAddressChanged(qint64 new_value); |
| 65 | void OnFramebufferWidthChanged(unsigned int new_value); | 65 | void OnFramebufferWidthChanged(int new_value); |
| 66 | void OnFramebufferHeightChanged(unsigned int new_value); | 66 | void OnFramebufferHeightChanged(int new_value); |
| 67 | void OnFramebufferFormatChanged(int new_value); | 67 | void OnFramebufferFormatChanged(int new_value); |
| 68 | void OnUpdate(); | 68 | void OnUpdate(); |
| 69 | 69 | ||
diff --git a/src/common/common.h b/src/common/common.h index bf48ae667..3246c7797 100644 --- a/src/common/common.h +++ b/src/common/common.h | |||
| @@ -11,13 +11,6 @@ | |||
| 11 | #include <cstdio> | 11 | #include <cstdio> |
| 12 | #include <cstring> | 12 | #include <cstring> |
| 13 | 13 | ||
| 14 | // Force enable logging in the right modes. For some reason, something had changed | ||
| 15 | // so that debugfast no longer logged. | ||
| 16 | #if defined(_DEBUG) || defined(DEBUGFAST) | ||
| 17 | #undef LOGGING | ||
| 18 | #define LOGGING 1 | ||
| 19 | #endif | ||
| 20 | |||
| 21 | #define STACKALIGN | 14 | #define STACKALIGN |
| 22 | 15 | ||
| 23 | // An inheritable class to disallow the copy constructor and operator= functions | 16 | // An inheritable class to disallow the copy constructor and operator= functions |
diff --git a/src/common/log.h b/src/common/log.h index 667f2fbb9..b397cf14d 100644 --- a/src/common/log.h +++ b/src/common/log.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #endif | 14 | #endif |
| 15 | #endif | 15 | #endif |
| 16 | 16 | ||
| 17 | #if _DEBUG | 17 | #ifdef _DEBUG |
| 18 | #define _dbg_assert_(_t_, _a_) \ | 18 | #define _dbg_assert_(_t_, _a_) \ |
| 19 | if (!(_a_)) {\ | 19 | if (!(_a_)) {\ |
| 20 | LOG_CRITICAL(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ | 20 | LOG_CRITICAL(_t_, "Error...\n\n Line: %d\n File: %s\n Time: %s\n\nIgnore and continue?", \ |
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index bda3d633a..3d94bf0d9 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -74,17 +74,6 @@ enum class Class : ClassType { | |||
| 74 | }; | 74 | }; |
| 75 | 75 | ||
| 76 | /** | 76 | /** |
| 77 | * Level below which messages are simply discarded without buffering regardless of the display | ||
| 78 | * settings. | ||
| 79 | */ | ||
| 80 | const Level MINIMUM_LEVEL = | ||
| 81 | #ifdef _DEBUG | ||
| 82 | Level::Trace; | ||
| 83 | #else | ||
| 84 | Level::Debug; | ||
| 85 | #endif | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Logs a message to the global logger. This proxy exists to avoid exposing the details of the | 77 | * Logs a message to the global logger. This proxy exists to avoid exposing the details of the |
| 89 | * Logger class, including the ConcurrentRingBuffer template, to all files that desire to log | 78 | * Logger class, including the ConcurrentRingBuffer template, to all files that desire to log |
| 90 | * messages, reducing unecessary recompilations. | 79 | * messages, reducing unecessary recompilations. |
| @@ -103,13 +92,15 @@ void LogMessage(Class log_class, Level log_level, | |||
| 103 | } // namespace Log | 92 | } // namespace Log |
| 104 | 93 | ||
| 105 | #define LOG_GENERIC(log_class, log_level, ...) \ | 94 | #define LOG_GENERIC(log_class, log_level, ...) \ |
| 106 | do { \ | 95 | ::Log::LogMessage(::Log::Class::log_class, ::Log::Level::log_level, \ |
| 107 | if (::Log::Level::log_level >= ::Log::MINIMUM_LEVEL) \ | 96 | __FILE__, __LINE__, __func__, __VA_ARGS__) |
| 108 | ::Log::LogMessage(::Log::Class::log_class, ::Log::Level::log_level, \ | ||
| 109 | __FILE__, __LINE__, __func__, __VA_ARGS__); \ | ||
| 110 | } while (0) | ||
| 111 | 97 | ||
| 98 | #ifdef _DEBUG | ||
| 112 | #define LOG_TRACE( log_class, ...) LOG_GENERIC(log_class, Trace, __VA_ARGS__) | 99 | #define LOG_TRACE( log_class, ...) LOG_GENERIC(log_class, Trace, __VA_ARGS__) |
| 100 | #else | ||
| 101 | #define LOG_TRACE( log_class, ...) (void(0)) | ||
| 102 | #endif | ||
| 103 | |||
| 113 | #define LOG_DEBUG( log_class, ...) LOG_GENERIC(log_class, Debug, __VA_ARGS__) | 104 | #define LOG_DEBUG( log_class, ...) LOG_GENERIC(log_class, Debug, __VA_ARGS__) |
| 114 | #define LOG_INFO( log_class, ...) LOG_GENERIC(log_class, Info, __VA_ARGS__) | 105 | #define LOG_INFO( log_class, ...) LOG_GENERIC(log_class, Info, __VA_ARGS__) |
| 115 | #define LOG_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __VA_ARGS__) | 106 | #define LOG_WARNING( log_class, ...) LOG_GENERIC(log_class, Warning, __VA_ARGS__) |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 28adc5500..62e3460e1 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -30,7 +30,7 @@ public: | |||
| 30 | 30 | ||
| 31 | /// Arbitrate an address | 31 | /// Arbitrate an address |
| 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { | 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { |
| 33 | Object* object = Kernel::g_handle_table.GetGeneric(handle); | 33 | Object* object = Kernel::g_handle_table.GetGeneric(handle).get(); |
| 34 | if (object == nullptr) | 34 | if (object == nullptr) |
| 35 | return InvalidHandle(ErrorModule::Kernel); | 35 | return InvalidHandle(ErrorModule::Kernel); |
| 36 | 36 | ||
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 697e08681..271190dbe 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp | |||
| @@ -53,7 +53,7 @@ public: | |||
| 53 | * @return Result of operation, 0 on success, otherwise error code | 53 | * @return Result of operation, 0 on success, otherwise error code |
| 54 | */ | 54 | */ |
| 55 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { | 55 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { |
| 56 | Event* evt = g_handle_table.Get<Event>(handle); | 56 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 57 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 57 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 58 | 58 | ||
| 59 | evt->permanent_locked = permanent_locked; | 59 | evt->permanent_locked = permanent_locked; |
| @@ -67,7 +67,7 @@ ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { | |||
| 67 | * @return Result of operation, 0 on success, otherwise error code | 67 | * @return Result of operation, 0 on success, otherwise error code |
| 68 | */ | 68 | */ |
| 69 | ResultCode SetEventLocked(const Handle handle, const bool locked) { | 69 | ResultCode SetEventLocked(const Handle handle, const bool locked) { |
| 70 | Event* evt = g_handle_table.Get<Event>(handle); | 70 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 71 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 71 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 72 | 72 | ||
| 73 | if (!evt->permanent_locked) { | 73 | if (!evt->permanent_locked) { |
| @@ -82,13 +82,13 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) { | |||
| 82 | * @return Result of operation, 0 on success, otherwise error code | 82 | * @return Result of operation, 0 on success, otherwise error code |
| 83 | */ | 83 | */ |
| 84 | ResultCode SignalEvent(const Handle handle) { | 84 | ResultCode SignalEvent(const Handle handle) { |
| 85 | Event* evt = g_handle_table.Get<Event>(handle); | 85 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 86 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 86 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 87 | 87 | ||
| 88 | // Resume threads waiting for event to signal | 88 | // Resume threads waiting for event to signal |
| 89 | bool event_caught = false; | 89 | bool event_caught = false; |
| 90 | for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { | 90 | for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { |
| 91 | Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]); | 91 | Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]).get(); |
| 92 | if (thread != nullptr) | 92 | if (thread != nullptr) |
| 93 | thread->ResumeFromWait(); | 93 | thread->ResumeFromWait(); |
| 94 | 94 | ||
| @@ -112,7 +112,7 @@ ResultCode SignalEvent(const Handle handle) { | |||
| 112 | * @return Result of operation, 0 on success, otherwise error code | 112 | * @return Result of operation, 0 on success, otherwise error code |
| 113 | */ | 113 | */ |
| 114 | ResultCode ClearEvent(Handle handle) { | 114 | ResultCode ClearEvent(Handle handle) { |
| 115 | Event* evt = g_handle_table.Get<Event>(handle); | 115 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 116 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 116 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 117 | 117 | ||
| 118 | if (!evt->permanent_locked) { | 118 | if (!evt->permanent_locked) { |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a1bc6c5d8..d3684896f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | Thread* g_main_thread = nullptr; | 17 | SharedPtr<Thread> g_main_thread = nullptr; |
| 18 | HandleTable g_handle_table; | 18 | HandleTable g_handle_table; |
| 19 | u64 g_program_id = 0; | 19 | u64 g_program_id = 0; |
| 20 | 20 | ||
| @@ -23,7 +23,7 @@ HandleTable::HandleTable() { | |||
| 23 | Clear(); | 23 | Clear(); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | ResultVal<Handle> HandleTable::Create(Object* obj) { | 26 | ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { |
| 27 | _dbg_assert_(Kernel, obj != nullptr); | 27 | _dbg_assert_(Kernel, obj != nullptr); |
| 28 | 28 | ||
| 29 | u16 slot = next_free_slot; | 29 | u16 slot = next_free_slot; |
| @@ -39,22 +39,23 @@ ResultVal<Handle> HandleTable::Create(Object* obj) { | |||
| 39 | // CTR-OS doesn't use generation 0, so skip straight to 1. | 39 | // CTR-OS doesn't use generation 0, so skip straight to 1. |
| 40 | if (next_generation >= (1 << 15)) next_generation = 1; | 40 | if (next_generation >= (1 << 15)) next_generation = 1; |
| 41 | 41 | ||
| 42 | Handle handle = generation | (slot << 15); | ||
| 43 | if (obj->handle == INVALID_HANDLE) | ||
| 44 | obj->handle = handle; | ||
| 45 | |||
| 42 | generations[slot] = generation; | 46 | generations[slot] = generation; |
| 43 | intrusive_ptr_add_ref(obj); | 47 | objects[slot] = std::move(obj); |
| 44 | objects[slot] = obj; | ||
| 45 | 48 | ||
| 46 | Handle handle = generation | (slot << 15); | ||
| 47 | obj->handle = handle; | ||
| 48 | return MakeResult<Handle>(handle); | 49 | return MakeResult<Handle>(handle); |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { | 52 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { |
| 52 | Object* object = GetGeneric(handle); | 53 | SharedPtr<Object> object = GetGeneric(handle); |
| 53 | if (object == nullptr) { | 54 | if (object == nullptr) { |
| 54 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); | 55 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); |
| 55 | return ERR_INVALID_HANDLE; | 56 | return ERR_INVALID_HANDLE; |
| 56 | } | 57 | } |
| 57 | return Create(object); | 58 | return Create(std::move(object)); |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | ResultCode HandleTable::Close(Handle handle) { | 61 | ResultCode HandleTable::Close(Handle handle) { |
| @@ -64,7 +65,6 @@ ResultCode HandleTable::Close(Handle handle) { | |||
| 64 | size_t slot = GetSlot(handle); | 65 | size_t slot = GetSlot(handle); |
| 65 | u16 generation = GetGeneration(handle); | 66 | u16 generation = GetGeneration(handle); |
| 66 | 67 | ||
| 67 | intrusive_ptr_release(objects[slot]); | ||
| 68 | objects[slot] = nullptr; | 68 | objects[slot] = nullptr; |
| 69 | 69 | ||
| 70 | generations[generation] = next_free_slot; | 70 | generations[generation] = next_free_slot; |
| @@ -79,7 +79,7 @@ bool HandleTable::IsValid(Handle handle) const { | |||
| 79 | return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; | 79 | return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | Object* HandleTable::GetGeneric(Handle handle) const { | 82 | SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const { |
| 83 | if (handle == CurrentThread) { | 83 | if (handle == CurrentThread) { |
| 84 | return GetCurrentThread(); | 84 | return GetCurrentThread(); |
| 85 | } else if (handle == CurrentProcess) { | 85 | } else if (handle == CurrentProcess) { |
| @@ -96,8 +96,6 @@ Object* HandleTable::GetGeneric(Handle handle) const { | |||
| 96 | void HandleTable::Clear() { | 96 | void HandleTable::Clear() { |
| 97 | for (size_t i = 0; i < MAX_COUNT; ++i) { | 97 | for (size_t i = 0; i < MAX_COUNT; ++i) { |
| 98 | generations[i] = i + 1; | 98 | generations[i] = i + 1; |
| 99 | if (objects[i] != nullptr) | ||
| 100 | intrusive_ptr_release(objects[i]); | ||
| 101 | objects[i] = nullptr; | 99 | objects[i] = nullptr; |
| 102 | } | 100 | } |
| 103 | next_free_slot = 0; | 101 | next_free_slot = 0; |
| @@ -125,7 +123,7 @@ bool LoadExec(u32 entry_point) { | |||
| 125 | Core::g_app_core->SetPC(entry_point); | 123 | Core::g_app_core->SetPC(entry_point); |
| 126 | 124 | ||
| 127 | // 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 |
| 128 | g_main_thread = Kernel::SetupMainThread(0x30); | 126 | g_main_thread = Kernel::SetupMainThread(0x30, Kernel::DEFAULT_STACK_SIZE); |
| 129 | // Setup the idle thread | 127 | // Setup the idle thread |
| 130 | Kernel::SetupIdleThread(); | 128 | Kernel::SetupIdleThread(); |
| 131 | 129 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 31d80c7ac..5e5217b78 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <boost/intrusive_ptr.hpp> | ||
| 8 | |||
| 7 | #include <array> | 9 | #include <array> |
| 8 | #include <string> | 10 | #include <string> |
| 9 | #include "common/common.h" | 11 | #include "common/common.h" |
| @@ -52,7 +54,7 @@ class HandleTable; | |||
| 52 | 54 | ||
| 53 | class Object : NonCopyable { | 55 | class Object : NonCopyable { |
| 54 | friend class HandleTable; | 56 | friend class HandleTable; |
| 55 | u32 handle; | 57 | u32 handle = INVALID_HANDLE; |
| 56 | public: | 58 | public: |
| 57 | virtual ~Object() {} | 59 | virtual ~Object() {} |
| 58 | Handle GetHandle() const { return handle; } | 60 | Handle GetHandle() const { return handle; } |
| @@ -76,7 +78,7 @@ private: | |||
| 76 | unsigned int ref_count = 0; | 78 | unsigned int ref_count = 0; |
| 77 | }; | 79 | }; |
| 78 | 80 | ||
| 79 | // Special functions that will later be used by boost::instrusive_ptr to do automatic ref-counting | 81 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting |
| 80 | inline void intrusive_ptr_add_ref(Object* object) { | 82 | inline void intrusive_ptr_add_ref(Object* object) { |
| 81 | ++object->ref_count; | 83 | ++object->ref_count; |
| 82 | } | 84 | } |
| @@ -87,6 +89,9 @@ inline void intrusive_ptr_release(Object* object) { | |||
| 87 | } | 89 | } |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 92 | template <typename T> | ||
| 93 | using SharedPtr = boost::intrusive_ptr<T>; | ||
| 94 | |||
| 90 | /** | 95 | /** |
| 91 | * This class allows the creation of Handles, which are references to objects that can be tested | 96 | * This class allows the creation of Handles, which are references to objects that can be tested |
| 92 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the | 97 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the |
| @@ -119,7 +124,7 @@ public: | |||
| 119 | * @return The created Handle or one of the following errors: | 124 | * @return The created Handle or one of the following errors: |
| 120 | * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. | 125 | * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. |
| 121 | */ | 126 | */ |
| 122 | ResultVal<Handle> Create(Object* obj); | 127 | ResultVal<Handle> Create(SharedPtr<Object> obj); |
| 123 | 128 | ||
| 124 | /** | 129 | /** |
| 125 | * Returns a new handle that points to the same object as the passed in handle. | 130 | * Returns a new handle that points to the same object as the passed in handle. |
| @@ -143,7 +148,7 @@ public: | |||
| 143 | * Looks up a handle. | 148 | * Looks up a handle. |
| 144 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. | 149 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. |
| 145 | */ | 150 | */ |
| 146 | Object* GetGeneric(Handle handle) const; | 151 | SharedPtr<Object> GetGeneric(Handle handle) const; |
| 147 | 152 | ||
| 148 | /** | 153 | /** |
| 149 | * Looks up a handle while verifying its type. | 154 | * Looks up a handle while verifying its type. |
| @@ -151,10 +156,10 @@ public: | |||
| 151 | * type differs from the handle type `T::HANDLE_TYPE`. | 156 | * type differs from the handle type `T::HANDLE_TYPE`. |
| 152 | */ | 157 | */ |
| 153 | template <class T> | 158 | template <class T> |
| 154 | T* Get(Handle handle) const { | 159 | SharedPtr<T> Get(Handle handle) const { |
| 155 | Object* object = GetGeneric(handle); | 160 | SharedPtr<Object> object = GetGeneric(handle); |
| 156 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { | 161 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { |
| 157 | return static_cast<T*>(object); | 162 | return boost::static_pointer_cast<T>(std::move(object)); |
| 158 | } | 163 | } |
| 159 | return nullptr; | 164 | return nullptr; |
| 160 | } | 165 | } |
| @@ -173,7 +178,7 @@ private: | |||
| 173 | static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } | 178 | static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } |
| 174 | 179 | ||
| 175 | /// Stores the Object referenced by the handle or null if the slot is empty. | 180 | /// Stores the Object referenced by the handle or null if the slot is empty. |
| 176 | std::array<Object*, MAX_COUNT> objects; | 181 | std::array<SharedPtr<Object>, MAX_COUNT> objects; |
| 177 | 182 | ||
| 178 | /** | 183 | /** |
| 179 | * The value of `next_generation` when the handle was created, used to check for validity. For | 184 | * The value of `next_generation` when the handle was created, used to check for validity. For |
| @@ -192,7 +197,7 @@ private: | |||
| 192 | }; | 197 | }; |
| 193 | 198 | ||
| 194 | extern HandleTable g_handle_table; | 199 | extern HandleTable g_handle_table; |
| 195 | extern Thread* g_main_thread; | 200 | extern SharedPtr<Thread> g_main_thread; |
| 196 | 201 | ||
| 197 | /// The ID code of the currently running game | 202 | /// The ID code of the currently running game |
| 198 | /// TODO(Subv): This variable should not be here, | 203 | /// TODO(Subv): This variable should not be here, |
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 7d008f6cc..853a5dd74 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -48,7 +48,7 @@ void MutexAcquireLock(Mutex* mutex, Handle thread = GetCurrentThread()->GetHandl | |||
| 48 | bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) { | 48 | bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) { |
| 49 | MutexAcquireLock(mutex, thread_handle); | 49 | MutexAcquireLock(mutex, thread_handle); |
| 50 | 50 | ||
| 51 | Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle); | 51 | Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle).get(); |
| 52 | if (thread == nullptr) { | 52 | if (thread == nullptr) { |
| 53 | LOG_ERROR(Kernel, "Called with invalid handle: %08X", thread_handle); | 53 | LOG_ERROR(Kernel, "Called with invalid handle: %08X", thread_handle); |
| 54 | return false; | 54 | return false; |
| @@ -94,7 +94,7 @@ void ReleaseThreadMutexes(Handle thread) { | |||
| 94 | 94 | ||
| 95 | // Release every mutex that the thread holds, and resume execution on the waiting threads | 95 | // Release every mutex that the thread holds, and resume execution on the waiting threads |
| 96 | for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { | 96 | for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { |
| 97 | Mutex* mutex = g_handle_table.Get<Mutex>(iter->second); | 97 | Mutex* mutex = g_handle_table.Get<Mutex>(iter->second).get(); |
| 98 | ResumeWaitingThread(mutex); | 98 | ResumeWaitingThread(mutex); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| @@ -122,7 +122,7 @@ bool ReleaseMutex(Mutex* mutex) { | |||
| 122 | * @param handle Handle to mutex to release | 122 | * @param handle Handle to mutex to release |
| 123 | */ | 123 | */ |
| 124 | ResultCode ReleaseMutex(Handle handle) { | 124 | ResultCode ReleaseMutex(Handle handle) { |
| 125 | Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle); | 125 | Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle).get(); |
| 126 | if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); | 126 | if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 127 | 127 | ||
| 128 | if (!ReleaseMutex(mutex)) { | 128 | if (!ReleaseMutex(mutex)) { |
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index d7eeaa3da..88ec9a104 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp | |||
| @@ -70,7 +70,7 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count, | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | 72 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { |
| 73 | Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle); | 73 | Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle).get(); |
| 74 | if (semaphore == nullptr) | 74 | if (semaphore == nullptr) |
| 75 | return InvalidHandle(ErrorModule::Kernel); | 75 | return InvalidHandle(ErrorModule::Kernel); |
| 76 | 76 | ||
| @@ -84,7 +84,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | |||
| 84 | // Notify some of the threads that the semaphore has been released | 84 | // Notify some of the threads that the semaphore has been released |
| 85 | // stop once the semaphore is full again or there are no more waiting threads | 85 | // stop once the semaphore is full again or there are no more waiting threads |
| 86 | while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { | 86 | while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { |
| 87 | Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()); | 87 | Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()).get(); |
| 88 | if (thread != nullptr) | 88 | if (thread != nullptr) |
| 89 | thread->ResumeFromWait(); | 89 | thread->ResumeFromWait(); |
| 90 | semaphore->waiting_threads.pop(); | 90 | semaphore->waiting_threads.pop(); |
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index cea1f6fa1..5368e4728 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -61,7 +61,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions | |||
| 61 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 61 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 62 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 62 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 63 | } | 63 | } |
| 64 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | 64 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get(); |
| 65 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); | 65 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 66 | 66 | ||
| 67 | shared_memory->base_address = address; | 67 | shared_memory->base_address = address; |
| @@ -72,7 +72,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions | |||
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { | 74 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { |
| 75 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | 75 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get(); |
| 76 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); | 76 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 77 | 77 | ||
| 78 | if (0 != shared_memory->base_address) | 78 | if (0 != shared_memory->base_address) |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 6d126099b..bc86a7c59 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -36,7 +36,7 @@ ResultVal<bool> Thread::WaitSynchronization() { | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | // Lists all thread ids that aren't deleted/etc. | 38 | // Lists all thread ids that aren't deleted/etc. |
| 39 | static std::vector<Thread*> thread_list; // TODO(yuriks): Owned | 39 | static std::vector<SharedPtr<Thread>> thread_list; |
| 40 | 40 | ||
| 41 | // Lists only ready thread ids. | 41 | // Lists only ready thread ids. |
| 42 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> thread_ready_queue; | 42 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> thread_ready_queue; |
| @@ -110,8 +110,8 @@ void Thread::Stop(const char* reason) { | |||
| 110 | 110 | ||
| 111 | ChangeReadyState(this, false); | 111 | ChangeReadyState(this, false); |
| 112 | status = THREADSTATUS_DORMANT; | 112 | status = THREADSTATUS_DORMANT; |
| 113 | for (Thread* waiting_thread : waiting_threads) { | 113 | for (auto& waiting_thread : waiting_threads) { |
| 114 | if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, this)) | 114 | if (CheckWaitType(waiting_thread.get(), WAITTYPE_THREADEND, this)) |
| 115 | waiting_thread->ResumeFromWait(); | 115 | waiting_thread->ResumeFromWait(); |
| 116 | } | 116 | } |
| 117 | waiting_threads.clear(); | 117 | waiting_threads.clear(); |
| @@ -143,15 +143,15 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) { | |||
| 143 | s32 priority = THREADPRIO_LOWEST; | 143 | s32 priority = THREADPRIO_LOWEST; |
| 144 | 144 | ||
| 145 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 145 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 146 | for (Thread* thread : thread_list) { | 146 | for (auto& thread : thread_list) { |
| 147 | if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) | 147 | if (!CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address)) |
| 148 | continue; | 148 | continue; |
| 149 | 149 | ||
| 150 | if (thread == nullptr) | 150 | if (thread == nullptr) |
| 151 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. | 151 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. |
| 152 | 152 | ||
| 153 | if(thread->current_priority <= priority) { | 153 | if(thread->current_priority <= priority) { |
| 154 | highest_priority_thread = thread; | 154 | highest_priority_thread = thread.get(); |
| 155 | priority = thread->current_priority; | 155 | priority = thread->current_priority; |
| 156 | } | 156 | } |
| 157 | } | 157 | } |
| @@ -168,8 +168,8 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) { | |||
| 168 | void ArbitrateAllThreads(Object* arbiter, u32 address) { | 168 | void ArbitrateAllThreads(Object* arbiter, u32 address) { |
| 169 | 169 | ||
| 170 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 170 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 171 | for (Thread* thread : thread_list) { | 171 | for (auto& thread : thread_list) { |
| 172 | if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) | 172 | if (CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address)) |
| 173 | thread->ResumeFromWait(); | 173 | thread->ResumeFromWait(); |
| 174 | } | 174 | } |
| 175 | } | 175 | } |
| @@ -241,7 +241,7 @@ static int ThreadWakeupEventType = -1; | |||
| 241 | /// Callback that will wake up the thread it was scheduled for | 241 | /// Callback that will wake up the thread it was scheduled for |
| 242 | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | 242 | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { |
| 243 | Handle handle = static_cast<Handle>(parameter); | 243 | Handle handle = static_cast<Handle>(parameter); |
| 244 | Thread* thread = Kernel::g_handle_table.Get<Thread>(handle); | 244 | SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(handle); |
| 245 | if (thread == nullptr) { | 245 | if (thread == nullptr) { |
| 246 | LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); | 246 | LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); |
| 247 | return; | 247 | return; |
| @@ -281,20 +281,18 @@ static void DebugThreadQueue() { | |||
| 281 | return; | 281 | return; |
| 282 | } | 282 | } |
| 283 | LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); | 283 | LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); |
| 284 | for (Thread* t : thread_list) { | 284 | for (auto& t : thread_list) { |
| 285 | s32 priority = thread_ready_queue.contains(t); | 285 | s32 priority = thread_ready_queue.contains(t.get()); |
| 286 | if (priority != -1) { | 286 | if (priority != -1) { |
| 287 | LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); | 287 | LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); |
| 288 | } | 288 | } |
| 289 | } | 289 | } |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priority, u32 arg, | 292 | ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, |
| 293 | s32 processor_id, u32 stack_top, int stack_size) { | 293 | u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size) { |
| 294 | _dbg_assert_(Kernel, name != nullptr); | 294 | if (stack_size < 0x200) { |
| 295 | 295 | LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name.c_str(), stack_size); | |
| 296 | if ((u32)stack_size < 0x200) { | ||
| 297 | LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name, stack_size); | ||
| 298 | // TODO: Verify error | 296 | // TODO: Verify error |
| 299 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Kernel, | 297 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Kernel, |
| 300 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 298 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| @@ -303,27 +301,26 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit | |||
| 303 | if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { | 301 | if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { |
| 304 | s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); | 302 | s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); |
| 305 | LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", | 303 | LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", |
| 306 | name, priority, new_priority); | 304 | name.c_str(), priority, new_priority); |
| 307 | // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm | 305 | // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm |
| 308 | // validity of this | 306 | // validity of this |
| 309 | priority = new_priority; | 307 | priority = new_priority; |
| 310 | } | 308 | } |
| 311 | 309 | ||
| 312 | if (!Memory::GetPointer(entry_point)) { | 310 | if (!Memory::GetPointer(entry_point)) { |
| 313 | LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name, entry_point); | 311 | LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); |
| 314 | // TODO: Verify error | 312 | // TODO: Verify error |
| 315 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 313 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 316 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 314 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 317 | } | 315 | } |
| 318 | 316 | ||
| 319 | Thread* thread = new Thread; | 317 | SharedPtr<Thread> thread(new Thread); |
| 320 | 318 | ||
| 321 | // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for | 319 | // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for |
| 322 | // the time being. Create a handle here, it will be copied to the handle field in | 320 | // the time being. Create a handle here, it will be copied to the handle field in |
| 323 | // the object and use by the rest of the code. This should be removed when other | 321 | // the object and use by the rest of the code. This should be removed when other |
| 324 | // code doesn't rely on the handle anymore. | 322 | // code doesn't rely on the handle anymore. |
| 325 | ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread); | 323 | ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread); |
| 326 | // TODO(yuriks): Plug memory leak | ||
| 327 | if (handle.Failed()) | 324 | if (handle.Failed()) |
| 328 | return handle.Code(); | 325 | return handle.Code(); |
| 329 | 326 | ||
| @@ -340,12 +337,12 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit | |||
| 340 | thread->wait_type = WAITTYPE_NONE; | 337 | thread->wait_type = WAITTYPE_NONE; |
| 341 | thread->wait_object = nullptr; | 338 | thread->wait_object = nullptr; |
| 342 | thread->wait_address = 0; | 339 | thread->wait_address = 0; |
| 343 | thread->name = name; | 340 | thread->name = std::move(name); |
| 344 | 341 | ||
| 345 | ResetThread(thread, arg, 0); | 342 | ResetThread(thread.get(), arg, 0); |
| 346 | CallThread(thread); | 343 | CallThread(thread.get()); |
| 347 | 344 | ||
| 348 | return MakeResult<Thread*>(thread); | 345 | return MakeResult<SharedPtr<Thread>>(std::move(thread)); |
| 349 | } | 346 | } |
| 350 | 347 | ||
| 351 | /// Set the priority of the thread specified by handle | 348 | /// Set the priority of the thread specified by handle |
| @@ -379,20 +376,20 @@ Handle SetupIdleThread() { | |||
| 379 | auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, | 376 | auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, |
| 380 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); | 377 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); |
| 381 | _dbg_assert_(Kernel, thread_res.Succeeded()); | 378 | _dbg_assert_(Kernel, thread_res.Succeeded()); |
| 382 | Thread* thread = *thread_res; | 379 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 383 | 380 | ||
| 384 | thread->idle = true; | 381 | thread->idle = true; |
| 385 | CallThread(thread); | 382 | CallThread(thread.get()); |
| 386 | return thread->GetHandle(); | 383 | return thread->GetHandle(); |
| 387 | } | 384 | } |
| 388 | 385 | ||
| 389 | Thread* SetupMainThread(s32 priority, int stack_size) { | 386 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size) { |
| 390 | // Initialize new "main" thread | 387 | // Initialize new "main" thread |
| 391 | ResultVal<Thread*> thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0, | 388 | auto thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0, |
| 392 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); | 389 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); |
| 393 | // TODO(yuriks): Propagate error | 390 | // TODO(yuriks): Propagate error |
| 394 | _dbg_assert_(Kernel, thread_res.Succeeded()); | 391 | _dbg_assert_(Kernel, thread_res.Succeeded()); |
| 395 | Thread* thread = *thread_res; | 392 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 396 | 393 | ||
| 397 | // If running another thread already, set it to "ready" state | 394 | // If running another thread already, set it to "ready" state |
| 398 | Thread* cur = GetCurrentThread(); | 395 | Thread* cur = GetCurrentThread(); |
| @@ -401,7 +398,7 @@ Thread* SetupMainThread(s32 priority, int stack_size) { | |||
| 401 | } | 398 | } |
| 402 | 399 | ||
| 403 | // Run new "main" thread | 400 | // Run new "main" thread |
| 404 | current_thread = thread; | 401 | current_thread = thread.get(); |
| 405 | thread->status = THREADSTATUS_RUNNING; | 402 | thread->status = THREADSTATUS_RUNNING; |
| 406 | Core::g_app_core->LoadContext(thread->context); | 403 | Core::g_app_core->LoadContext(thread->context); |
| 407 | 404 | ||
| @@ -421,7 +418,7 @@ void Reschedule() { | |||
| 421 | } else { | 418 | } else { |
| 422 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); | 419 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); |
| 423 | 420 | ||
| 424 | for (Thread* thread : thread_list) { | 421 | for (auto& thread : thread_list) { |
| 425 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", | 422 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", |
| 426 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, | 423 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, |
| 427 | (thread->wait_object ? thread->wait_object->GetHandle() : INVALID_HANDLE)); | 424 | (thread->wait_object ? thread->wait_object->GetHandle() : INVALID_HANDLE)); |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 24450379c..284dec400 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -54,8 +54,8 @@ namespace Kernel { | |||
| 54 | 54 | ||
| 55 | class Thread : public Kernel::Object { | 55 | class Thread : public Kernel::Object { |
| 56 | public: | 56 | public: |
| 57 | static ResultVal<Thread*> Create(const char* name, u32 entry_point, s32 priority, u32 arg, | 57 | static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, |
| 58 | s32 processor_id, u32 stack_top, int stack_size = Kernel::DEFAULT_STACK_SIZE); | 58 | u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size); |
| 59 | 59 | ||
| 60 | std::string GetName() const override { return name; } | 60 | std::string GetName() const override { return name; } |
| 61 | std::string GetTypeName() const override { return "Thread"; } | 61 | std::string GetTypeName() const override { return "Thread"; } |
| @@ -99,7 +99,7 @@ public: | |||
| 99 | Object* wait_object; | 99 | Object* wait_object; |
| 100 | VAddr wait_address; | 100 | VAddr wait_address; |
| 101 | 101 | ||
| 102 | std::vector<Thread*> waiting_threads; // TODO(yuriks): Owned | 102 | std::vector<SharedPtr<Thread>> waiting_threads; |
| 103 | 103 | ||
| 104 | std::string name; | 104 | std::string name; |
| 105 | 105 | ||
| @@ -111,7 +111,7 @@ private: | |||
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | /// Sets up the primary application thread | 113 | /// Sets up the primary application thread |
| 114 | Thread* SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZE); | 114 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size); |
| 115 | 115 | ||
| 116 | /// Reschedules to the next available thread (call after current thread is suspended) | 116 | /// Reschedules to the next available thread (call after current thread is suspended) |
| 117 | void Reschedule(); | 117 | void Reschedule(); |
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 685a202c0..3b0452d4d 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -66,7 +66,7 @@ ResultCode CreateTimer(Handle* handle, const ResetType reset_type, const std::st | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | ResultCode ClearTimer(Handle handle) { | 68 | ResultCode ClearTimer(Handle handle) { |
| 69 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 69 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 70 | 70 | ||
| 71 | if (timer == nullptr) | 71 | if (timer == nullptr) |
| 72 | return InvalidHandle(ErrorModule::Kernel); | 72 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -80,7 +80,7 @@ static int TimerCallbackEventType = -1; | |||
| 80 | 80 | ||
| 81 | /// The timer callback event, called when a timer is fired | 81 | /// The timer callback event, called when a timer is fired |
| 82 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 82 | static void TimerCallback(u64 timer_handle, int cycles_late) { |
| 83 | Timer* timer = Kernel::g_handle_table.Get<Timer>(timer_handle); | 83 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle); |
| 84 | 84 | ||
| 85 | if (timer == nullptr) { | 85 | if (timer == nullptr) { |
| 86 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle); | 86 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle); |
| @@ -93,7 +93,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 93 | 93 | ||
| 94 | // Resume all waiting threads | 94 | // Resume all waiting threads |
| 95 | for (Handle thread_handle : timer->waiting_threads) { | 95 | for (Handle thread_handle : timer->waiting_threads) { |
| 96 | if (Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle)) | 96 | if (SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(thread_handle)) |
| 97 | thread->ResumeFromWait(); | 97 | thread->ResumeFromWait(); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -111,7 +111,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { | 113 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { |
| 114 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 114 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 115 | 115 | ||
| 116 | if (timer == nullptr) | 116 | if (timer == nullptr) |
| 117 | return InvalidHandle(ErrorModule::Kernel); | 117 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -125,7 +125,7 @@ ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | ResultCode CancelTimer(Handle handle) { | 127 | ResultCode CancelTimer(Handle handle) { |
| 128 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 128 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 129 | 129 | ||
| 130 | if (timer == nullptr) | 130 | if (timer == nullptr) |
| 131 | return InvalidHandle(ErrorModule::Kernel); | 131 | return InvalidHandle(ErrorModule::Kernel); |
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 0e9c213e0..82dcf5bba 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -369,14 +369,14 @@ private: | |||
| 369 | 369 | ||
| 370 | StorageType storage; | 370 | StorageType storage; |
| 371 | ResultCode result_code; | 371 | ResultCode result_code; |
| 372 | #if _DEBUG | 372 | #ifdef _DEBUG |
| 373 | // The purpose of this pointer is to aid inspecting the type with a debugger, eliminating the | 373 | // The purpose of this pointer is to aid inspecting the type with a debugger, eliminating the |
| 374 | // need to cast `storage` to a pointer or pay attention to `result_code`. | 374 | // need to cast `storage` to a pointer or pay attention to `result_code`. |
| 375 | const T* debug_ptr; | 375 | const T* debug_ptr; |
| 376 | #endif | 376 | #endif |
| 377 | 377 | ||
| 378 | void UpdateDebugPtr() { | 378 | void UpdateDebugPtr() { |
| 379 | #if _DEBUG | 379 | #ifdef _DEBUG |
| 380 | debug_ptr = empty() ? nullptr : static_cast<const T*>(static_cast<const void*>(&storage)); | 380 | debug_ptr = empty() ? nullptr : static_cast<const T*>(static_cast<const void*>(&storage)); |
| 381 | #endif | 381 | #endif |
| 382 | } | 382 | } |
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index d8b261ba7..d0ff4e585 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp | |||
| @@ -52,8 +52,6 @@ void Initialize(Service::Interface* self) { | |||
| 52 | Kernel::ReleaseMutex(lock_handle); | 52 | Kernel::ReleaseMutex(lock_handle); |
| 53 | 53 | ||
| 54 | cmd_buff[1] = 0; // No error | 54 | cmd_buff[1] = 0; // No error |
| 55 | |||
| 56 | LOG_DEBUG(Service_APT, "called"); | ||
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | void GetLockHandle(Service::Interface* self) { | 57 | void GetLockHandle(Service::Interface* self) { |
| @@ -194,8 +192,6 @@ void AppletUtility(Service::Interface* self) { | |||
| 194 | * 4 : Handle to shared font memory | 192 | * 4 : Handle to shared font memory |
| 195 | */ | 193 | */ |
| 196 | void GetSharedFont(Service::Interface* self) { | 194 | void GetSharedFont(Service::Interface* self) { |
| 197 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 198 | |||
| 199 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 195 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 200 | 196 | ||
| 201 | if (!shared_font.empty()) { | 197 | if (!shared_font.empty()) { |
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 7eb32146d..56f3117f4 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -27,8 +27,6 @@ static void Initialize(Service::Interface* self) { | |||
| 27 | // TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per | 27 | // TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per |
| 28 | // http://3dbrew.org/wiki/FS:Initialize#Request | 28 | // http://3dbrew.org/wiki/FS:Initialize#Request |
| 29 | cmd_buff[1] = RESULT_SUCCESS.raw; | 29 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 30 | |||
| 31 | LOG_DEBUG(Service_FS, "called"); | ||
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | /** | 32 | /** |
| @@ -104,8 +102,8 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 104 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); | 102 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); |
| 105 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); | 103 | FileSys::Path file_path(filename_type, filename_size, filename_ptr); |
| 106 | 104 | ||
| 107 | LOG_DEBUG(Service_FS, "archive_path=%s file_path=%s, mode=%u attributes=%d", | 105 | LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s file_path=%s, mode=%u attributes=%d", |
| 108 | archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); | 106 | archive_id, archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); |
| 109 | 107 | ||
| 110 | ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); | 108 | ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); |
| 111 | if (archive_handle.Failed()) { | 109 | if (archive_handle.Failed()) { |
| @@ -367,7 +365,7 @@ static void OpenArchive(Service::Interface* self) { | |||
| 367 | u32 archivename_ptr = cmd_buff[5]; | 365 | u32 archivename_ptr = cmd_buff[5]; |
| 368 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); | 366 | FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); |
| 369 | 367 | ||
| 370 | LOG_DEBUG(Service_FS, "archive_path=%s", archive_path.DebugStr().c_str()); | 368 | LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s", archive_id, archive_path.DebugStr().c_str()); |
| 371 | 369 | ||
| 372 | ResultVal<ArchiveHandle> handle = OpenArchive(archive_id, archive_path); | 370 | ResultVal<ArchiveHandle> handle = OpenArchive(archive_id, archive_path); |
| 373 | cmd_buff[1] = handle.Code().raw; | 371 | cmd_buff[1] = handle.Code().raw; |
| @@ -408,8 +406,6 @@ static void IsSdmcDetected(Service::Interface* self) { | |||
| 408 | 406 | ||
| 409 | cmd_buff[1] = 0; | 407 | cmd_buff[1] = 0; |
| 410 | cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0; | 408 | cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0; |
| 411 | |||
| 412 | LOG_DEBUG(Service_FS, "called"); | ||
| 413 | } | 409 | } |
| 414 | 410 | ||
| 415 | /** | 411 | /** |
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 26a43217e..2b115240f 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -331,9 +331,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 331 | 331 | ||
| 332 | /// This triggers handling of the GX command written to the command buffer in shared memory. | 332 | /// This triggers handling of the GX command written to the command buffer in shared memory. |
| 333 | static void TriggerCmdReqQueue(Service::Interface* self) { | 333 | static void TriggerCmdReqQueue(Service::Interface* self) { |
| 334 | |||
| 335 | LOG_TRACE(Service_GSP, "called"); | ||
| 336 | |||
| 337 | // Iterate through each thread's command queue... | 334 | // Iterate through each thread's command queue... |
| 338 | for (unsigned thread_id = 0; thread_id < 0x4; ++thread_id) { | 335 | for (unsigned thread_id = 0; thread_id < 0x4; ++thread_id) { |
| 339 | CommandBuffer* command_buffer = (CommandBuffer*)GetCommandBuffer(thread_id); | 336 | CommandBuffer* command_buffer = (CommandBuffer*)GetCommandBuffer(thread_id); |
diff --git a/src/core/hle/service/hid_user.cpp b/src/core/hle/service/hid_user.cpp index 8ef9af9d2..1403b1de9 100644 --- a/src/core/hle/service/hid_user.cpp +++ b/src/core/hle/service/hid_user.cpp | |||
| @@ -163,8 +163,6 @@ static void GetIPCHandles(Service::Interface* self) { | |||
| 163 | cmd_buff[6] = event_accelerometer; | 163 | cmd_buff[6] = event_accelerometer; |
| 164 | cmd_buff[7] = event_gyroscope; | 164 | cmd_buff[7] = event_gyroscope; |
| 165 | cmd_buff[8] = event_debug_pad; | 165 | cmd_buff[8] = event_debug_pad; |
| 166 | |||
| 167 | LOG_TRACE(Service_HID, "called"); | ||
| 168 | } | 166 | } |
| 169 | 167 | ||
| 170 | const Interface::FunctionInfo FunctionTable[] = { | 168 | const Interface::FunctionInfo FunctionTable[] = { |
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index fd79cd8ab..753180add 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp | |||
| @@ -76,8 +76,6 @@ static void GetShellState(Service::Interface* self) { | |||
| 76 | 76 | ||
| 77 | cmd_buff[1] = 0; | 77 | cmd_buff[1] = 0; |
| 78 | cmd_buff[2] = shell_open ? 1 : 0; | 78 | cmd_buff[2] = shell_open ? 1 : 0; |
| 79 | |||
| 80 | LOG_TRACE(Service_PTM, "PTM_U::GetShellState called"); | ||
| 81 | } | 79 | } |
| 82 | 80 | ||
| 83 | /** | 81 | /** |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 0c5597283..33c29a4a0 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -59,7 +59,8 @@ void Manager::DeleteService(const std::string& port_name) { | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | Interface* Manager::FetchFromHandle(Handle handle) { | 61 | Interface* Manager::FetchFromHandle(Handle handle) { |
| 62 | return Kernel::g_handle_table.Get<Interface>(handle); | 62 | // TODO(yuriks): This function is very suspicious and should probably be exterminated. |
| 63 | return Kernel::g_handle_table.Get<Interface>(handle).get(); | ||
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | Interface* Manager::FetchFromPortName(const std::string& port_name) { | 66 | Interface* Manager::FetchFromPortName(const std::string& port_name) { |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 41ba1e554..e75d5008b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -33,6 +33,22 @@ class Interface : public Kernel::Session { | |||
| 33 | // processes. | 33 | // processes. |
| 34 | 34 | ||
| 35 | friend class Manager; | 35 | friend class Manager; |
| 36 | |||
| 37 | /** | ||
| 38 | * Creates a function string for logging, complete with the name (or header code, depending | ||
| 39 | * on what's passed in) the port name, and all the cmd_buff arguments. | ||
| 40 | */ | ||
| 41 | std::string MakeFunctionString(const std::string& name, const std::string& port_name, const u32* cmd_buff) { | ||
| 42 | // Number of params == bits 0-5 + bits 6-11 | ||
| 43 | int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); | ||
| 44 | |||
| 45 | std::string function_string = Common::StringFromFormat("function '%s': port=%s", name.c_str(), port_name.c_str()); | ||
| 46 | for (int i = 1; i <= num_params; ++i) { | ||
| 47 | function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); | ||
| 48 | } | ||
| 49 | return function_string; | ||
| 50 | } | ||
| 51 | |||
| 36 | public: | 52 | public: |
| 37 | std::string GetName() const override { return GetPortName(); } | 53 | std::string GetName() const override { return GetPortName(); } |
| 38 | 54 | ||
| @@ -72,21 +88,14 @@ public: | |||
| 72 | auto itr = m_functions.find(cmd_buff[0]); | 88 | auto itr = m_functions.find(cmd_buff[0]); |
| 73 | 89 | ||
| 74 | if (itr == m_functions.end() || itr->second.func == nullptr) { | 90 | if (itr == m_functions.end() || itr->second.func == nullptr) { |
| 75 | // Number of params == bits 0-5 + bits 6-11 | 91 | std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; |
| 76 | int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); | 92 | LOG_ERROR(Service, "%s %s", "unknown/unimplemented", MakeFunctionString(function_name, GetPortName(), cmd_buff).c_str()); |
| 77 | |||
| 78 | std::string error = "unknown/unimplemented function '%s': port=%s"; | ||
| 79 | for (int i = 1; i <= num_params; ++i) { | ||
| 80 | error += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); | ||
| 81 | } | ||
| 82 | |||
| 83 | std::string name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; | ||
| 84 | |||
| 85 | LOG_ERROR(Service, error.c_str(), name.c_str(), GetPortName().c_str()); | ||
| 86 | 93 | ||
| 87 | // TODO(bunnei): Hack - ignore error | 94 | // TODO(bunnei): Hack - ignore error |
| 88 | cmd_buff[1] = 0; | 95 | cmd_buff[1] = 0; |
| 89 | return MakeResult<bool>(false); | 96 | return MakeResult<bool>(false); |
| 97 | } else { | ||
| 98 | LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName(), cmd_buff).c_str()); | ||
| 90 | } | 99 | } |
| 91 | 100 | ||
| 92 | itr->second.func(this); | 101 | itr->second.func(this); |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 912b52adf..ac5f30a28 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -14,16 +14,12 @@ namespace SRV { | |||
| 14 | static Handle g_event_handle = 0; | 14 | static Handle g_event_handle = 0; |
| 15 | 15 | ||
| 16 | static void Initialize(Service::Interface* self) { | 16 | static void Initialize(Service::Interface* self) { |
| 17 | LOG_DEBUG(Service_SRV, "called"); | ||
| 18 | |||
| 19 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 17 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 20 | 18 | ||
| 21 | cmd_buff[1] = 0; // No error | 19 | cmd_buff[1] = 0; // No error |
| 22 | } | 20 | } |
| 23 | 21 | ||
| 24 | static void GetProcSemaphore(Service::Interface* self) { | 22 | static void GetProcSemaphore(Service::Interface* self) { |
| 25 | LOG_TRACE(Service_SRV, "called"); | ||
| 26 | |||
| 27 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 23 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 28 | 24 | ||
| 29 | // TODO(bunnei): Change to a semaphore once these have been implemented | 25 | // TODO(bunnei): Change to a semaphore once these have been implemented |
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index f9e3619dd..b3d873ef0 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp | |||
| @@ -12,6 +12,21 @@ | |||
| 12 | 12 | ||
| 13 | namespace Y2R_U { | 13 | namespace Y2R_U { |
| 14 | 14 | ||
| 15 | /** | ||
| 16 | * Y2R_U::IsBusyConversion service function | ||
| 17 | * Outputs: | ||
| 18 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 19 | * 2 : Whether the current conversion is of type busy conversion (?) | ||
| 20 | */ | ||
| 21 | static void IsBusyConversion(Service::Interface* self) { | ||
| 22 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 23 | |||
| 24 | cmd_buff[1] = RESULT_SUCCESS.raw;; | ||
| 25 | cmd_buff[2] = 0; | ||
| 26 | |||
| 27 | LOG_WARNING(Service, "(STUBBED) called"); | ||
| 28 | } | ||
| 29 | |||
| 15 | const Interface::FunctionInfo FunctionTable[] = { | 30 | const Interface::FunctionInfo FunctionTable[] = { |
| 16 | {0x00010040, nullptr, "SetInputFormat"}, | 31 | {0x00010040, nullptr, "SetInputFormat"}, |
| 17 | {0x00030040, nullptr, "SetOutputFormat"}, | 32 | {0x00030040, nullptr, "SetOutputFormat"}, |
| @@ -29,7 +44,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 29 | {0x00220040, nullptr, "SetAlpha"}, | 44 | {0x00220040, nullptr, "SetAlpha"}, |
| 30 | {0x00260000, nullptr, "StartConversion"}, | 45 | {0x00260000, nullptr, "StartConversion"}, |
| 31 | {0x00270000, nullptr, "StopConversion"}, | 46 | {0x00270000, nullptr, "StopConversion"}, |
| 32 | {0x00280000, nullptr, "IsBusyConversion"}, | 47 | {0x00280000, IsBusyConversion, "IsBusyConversion"}, |
| 33 | {0x002A0000, nullptr, "PingProcess"}, | 48 | {0x002A0000, nullptr, "PingProcess"}, |
| 34 | {0x002B0000, nullptr, "DriverInitialize"}, | 49 | {0x002B0000, nullptr, "DriverInitialize"}, |
| 35 | {0x002C0000, nullptr, "DriverFinalize"} | 50 | {0x002C0000, nullptr, "DriverFinalize"} |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 8ac1c7350..d3b4483ca 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 25 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 26 | // Namespace SVC | 26 | // Namespace SVC |
| 27 | 27 | ||
| 28 | using Kernel::SharedPtr; | ||
| 29 | |||
| 28 | namespace SVC { | 30 | namespace SVC { |
| 29 | 31 | ||
| 30 | enum ControlMemoryOperation { | 32 | enum ControlMemoryOperation { |
| @@ -94,7 +96,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) { | |||
| 94 | 96 | ||
| 95 | /// Synchronize to an OS service | 97 | /// Synchronize to an OS service |
| 96 | static Result SendSyncRequest(Handle handle) { | 98 | static Result SendSyncRequest(Handle handle) { |
| 97 | Kernel::Session* session = Kernel::g_handle_table.Get<Kernel::Session>(handle); | 99 | SharedPtr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle); |
| 98 | if (session == nullptr) { | 100 | if (session == nullptr) { |
| 99 | return InvalidHandle(ErrorModule::Kernel).raw; | 101 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 100 | } | 102 | } |
| @@ -121,12 +123,12 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | |||
| 121 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this | 123 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this |
| 122 | bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated | 124 | bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated |
| 123 | 125 | ||
| 124 | Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handle); | 126 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle); |
| 125 | if (object == nullptr) | 127 | if (object == nullptr) |
| 126 | return InvalidHandle(ErrorModule::Kernel).raw; | 128 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 127 | 129 | ||
| 128 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(), | 130 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, |
| 129 | object->GetName().c_str(), nano_seconds); | 131 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); |
| 130 | 132 | ||
| 131 | ResultVal<bool> wait = object->WaitSynchronization(); | 133 | ResultVal<bool> wait = object->WaitSynchronization(); |
| 132 | 134 | ||
| @@ -151,12 +153,12 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 151 | 153 | ||
| 152 | // Iterate through each handle, synchronize kernel object | 154 | // Iterate through each handle, synchronize kernel object |
| 153 | for (s32 i = 0; i < handle_count; i++) { | 155 | for (s32 i = 0; i < handle_count; i++) { |
| 154 | Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handles[i]); | 156 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]); |
| 155 | if (object == nullptr) | 157 | if (object == nullptr) |
| 156 | return InvalidHandle(ErrorModule::Kernel).raw; | 158 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 157 | 159 | ||
| 158 | LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(), | 160 | LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], |
| 159 | object->GetName().c_str()); | 161 | object->GetTypeName().c_str(), object->GetName().c_str()); |
| 160 | 162 | ||
| 161 | // TODO(yuriks): Verify how the real function behaves when an error happens here | 163 | // TODO(yuriks): Verify how the real function behaves when an error happens here |
| 162 | ResultVal<bool> wait_result = object->WaitSynchronization(); | 164 | ResultVal<bool> wait_result = object->WaitSynchronization(); |
| @@ -183,7 +185,6 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 183 | 185 | ||
| 184 | /// Create an address arbiter (to allocate access to shared resources) | 186 | /// Create an address arbiter (to allocate access to shared resources) |
| 185 | static Result CreateAddressArbiter(u32* arbiter) { | 187 | static Result CreateAddressArbiter(u32* arbiter) { |
| 186 | LOG_TRACE(Kernel_SVC, "called"); | ||
| 187 | Handle handle = Kernel::CreateAddressArbiter(); | 188 | Handle handle = Kernel::CreateAddressArbiter(); |
| 188 | *arbiter = handle; | 189 | *arbiter = handle; |
| 189 | return 0; | 190 | return 0; |
| @@ -223,6 +224,8 @@ static Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit, | |||
| 223 | 224 | ||
| 224 | /// Creates a new thread | 225 | /// Creates a new thread |
| 225 | static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) { | 226 | static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) { |
| 227 | using Kernel::Thread; | ||
| 228 | |||
| 226 | std::string name; | 229 | std::string name; |
| 227 | if (Symbols::HasSymbol(entry_point)) { | 230 | if (Symbols::HasSymbol(entry_point)) { |
| 228 | TSymbol symbol = Symbols::GetSymbol(entry_point); | 231 | TSymbol symbol = Symbols::GetSymbol(entry_point); |
| @@ -231,12 +234,13 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top | |||
| 231 | name = Common::StringFromFormat("unknown-%08x", entry_point); | 234 | name = Common::StringFromFormat("unknown-%08x", entry_point); |
| 232 | } | 235 | } |
| 233 | 236 | ||
| 234 | ResultVal<Kernel::Thread*> thread_res = Kernel::Thread::Create(name.c_str(), entry_point, priority, arg, | 237 | ResultVal<SharedPtr<Thread>> thread_res = Kernel::Thread::Create( |
| 235 | processor_id, stack_top); | 238 | name, entry_point, priority, arg, processor_id, stack_top, Kernel::DEFAULT_STACK_SIZE); |
| 236 | if (thread_res.Failed()) | 239 | if (thread_res.Failed()) |
| 237 | return thread_res.Code().raw; | 240 | return thread_res.Code().raw; |
| 238 | Kernel::Thread* thread = *thread_res; | 241 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 239 | 242 | ||
| 243 | // TODO(yuriks): Create new handle instead of using built-in | ||
| 240 | Core::g_app_core->SetReg(1, thread->GetHandle()); | 244 | Core::g_app_core->SetReg(1, thread->GetHandle()); |
| 241 | 245 | ||
| 242 | LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " | 246 | LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " |
| @@ -261,7 +265,7 @@ static void ExitThread() { | |||
| 261 | 265 | ||
| 262 | /// Gets the priority for the specified thread | 266 | /// Gets the priority for the specified thread |
| 263 | static Result GetThreadPriority(s32* priority, Handle handle) { | 267 | static Result GetThreadPriority(s32* priority, Handle handle) { |
| 264 | const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 268 | const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 265 | if (thread == nullptr) | 269 | if (thread == nullptr) |
| 266 | return InvalidHandle(ErrorModule::Kernel).raw; | 270 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 267 | 271 | ||
| @@ -271,7 +275,7 @@ static Result GetThreadPriority(s32* priority, Handle handle) { | |||
| 271 | 275 | ||
| 272 | /// Sets the priority for the specified thread | 276 | /// Sets the priority for the specified thread |
| 273 | static Result SetThreadPriority(Handle handle, s32 priority) { | 277 | static Result SetThreadPriority(Handle handle, s32 priority) { |
| 274 | Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 278 | SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 275 | if (thread == nullptr) | 279 | if (thread == nullptr) |
| 276 | return InvalidHandle(ErrorModule::Kernel).raw; | 280 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 277 | 281 | ||
| @@ -298,7 +302,7 @@ static Result ReleaseMutex(Handle handle) { | |||
| 298 | static Result GetThreadId(u32* thread_id, Handle handle) { | 302 | static Result GetThreadId(u32* thread_id, Handle handle) { |
| 299 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle); | 303 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle); |
| 300 | 304 | ||
| 301 | const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 305 | const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 302 | if (thread == nullptr) | 306 | if (thread == nullptr) |
| 303 | return InvalidHandle(ErrorModule::Kernel).raw; | 307 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 304 | 308 | ||