From 5e91fc0d1aa806a9635e06e047d5367988f21093 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 12:32:46 -0200 Subject: [PATCH 01/18] Filesys: Move creation of Handles for File/Directory to service handlers --- src/core/hle/service/fs/archive.cpp | 24 ++++++++---------------- src/core/hle/service/fs/archive.h | 14 ++++++++++---- src/core/hle/service/fs/fs_user.cpp | 27 +++++++++++++++------------ 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 43eef034e..0ce9ad4d6 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -303,7 +303,8 @@ ResultCode CreateArchive(std::unique_ptr&& backend, Arc return RESULT_SUCCESS; } -ResultVal OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { +ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, + const FileSys::Path& path, const FileSys::Mode mode) { Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; @@ -314,10 +315,8 @@ ResultVal OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::NotFound, ErrorLevel::Status); } - auto file = Common::make_unique(std::move(backend), path); - // TOOD(yuriks): Fix error reporting - Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE); - return MakeResult(handle); + auto file = Kernel::SharedPtr(new File(std::move(backend), path)); + return MakeResult>(std::move(file)); } ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { @@ -403,13 +402,8 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons ErrorSummary::NothingHappened, ErrorLevel::Status); } -/** - * Open a Directory from an Archive - * @param archive_handle Handle to an open Archive object - * @param path Path to the Directory inside of the Archive - * @return Opened Directory object - */ -ResultVal OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { +ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, + const FileSys::Path& path) { Archive* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_HANDLE; @@ -420,10 +414,8 @@ ResultVal OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F ErrorSummary::NotFound, ErrorLevel::Permanent); } - auto directory = Common::make_unique(std::move(backend), path); - // TOOD(yuriks): Fix error reporting - Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE); - return MakeResult(handle); + auto directory = Kernel::SharedPtr(new Directory(std::move(backend), path)); + return MakeResult>(std::move(directory)); } ResultCode FormatSaveData() { diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ba674d7f6..ab5ea4da8 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -15,6 +15,10 @@ extern const std::string SYSTEM_ID; /// The scrambled SD card CID, also known as ID1 extern const std::string SDCARD_ID; +namespace Kernel { + class Session; +} + namespace Service { namespace FS { @@ -58,9 +62,10 @@ ResultCode CreateArchive(std::unique_ptr&& backend, Arc * @param archive_handle Handle to an open Archive object * @param path Path to the File inside of the Archive * @param mode Mode under which to open the File - * @return Handle to the opened File object + * @return The opened File object as a Session */ -ResultVal OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); +ResultVal> OpenFileFromArchive(ArchiveHandle archive_handle, + const FileSys::Path& path, const FileSys::Mode mode); /** * Delete a File from an Archive @@ -121,9 +126,10 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons * Open a Directory from an Archive * @param archive_handle Handle to an open Archive object * @param path Path to the Directory inside of the Archive - * @return Handle to the opened File object + * @return The opened Directory object as a Session */ -ResultVal OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); +ResultVal> OpenDirectoryFromArchive(ArchiveHandle archive_handle, + const FileSys::Path& path); /** * Creates a blank SaveData archive. diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index c495b6f3c..9cb7d809a 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -14,6 +14,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User +using Kernel::SharedPtr; +using Kernel::Session; + namespace Service { namespace FS { @@ -58,10 +61,10 @@ static void OpenFile(Service::Interface* self) { LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); - ResultVal handle = OpenFileFromArchive(archive_handle, file_path, mode); - cmd_buff[1] = handle.Code().raw; - if (handle.Succeeded()) { - cmd_buff[3] = *handle; + ResultVal> file_res = OpenFileFromArchive(archive_handle, file_path, mode); + cmd_buff[1] = file_res.Code().raw; + if (file_res.Succeeded()) { + cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); } else { cmd_buff[3] = 0; LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); @@ -114,10 +117,10 @@ static void OpenFileDirectly(Service::Interface* self) { } SCOPE_EXIT({ CloseArchive(*archive_handle); }); - ResultVal handle = OpenFileFromArchive(*archive_handle, file_path, mode); - cmd_buff[1] = handle.Code().raw; - if (handle.Succeeded()) { - cmd_buff[3] = *handle; + ResultVal> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); + cmd_buff[1] = file_res.Code().raw; + if (file_res.Succeeded()) { + cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); } else { cmd_buff[3] = 0; LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); @@ -334,10 +337,10 @@ static void OpenDirectory(Service::Interface* self) { LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - ResultVal handle = OpenDirectoryFromArchive(archive_handle, dir_path); - cmd_buff[1] = handle.Code().raw; - if (handle.Succeeded()) { - cmd_buff[3] = *handle; + ResultVal> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); + cmd_buff[1] = dir_res.Code().raw; + if (dir_res.Succeeded()) { + cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom(); } else { LOG_ERROR(Service_FS, "failed to get a handle for directory"); } From 8779b31fe60c728ace89a9b5128b68feffa9c7d7 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 16:07:04 -0200 Subject: [PATCH 02/18] Make Port/Service registration and querying more HW-accurate --- src/core/hle/service/service.cpp | 134 +++++++++++++------------------ src/core/hle/service/service.h | 30 ++----- src/core/hle/service/srv.cpp | 6 +- src/core/hle/svc.cpp | 20 ++++- 4 files changed, 82 insertions(+), 108 deletions(-) diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 355196fd3..e0979ea5d 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -54,96 +54,76 @@ namespace Service { -Manager* g_manager = nullptr; ///< Service manager - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// Service Manager class - -void Manager::AddService(Interface* service) { - // TOOD(yuriks): Fix error reporting - m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); - m_services.push_back(service); -} - -void Manager::DeleteService(const std::string& port_name) { - Interface* service = FetchFromPortName(port_name); - m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); - m_port_map.erase(port_name); -} - -Interface* Manager::FetchFromHandle(Handle handle) { - // TODO(yuriks): This function is very suspicious and should probably be exterminated. - return Kernel::g_handle_table.Get(handle).get(); -} - -Interface* Manager::FetchFromPortName(const std::string& port_name) { - auto itr = m_port_map.find(port_name); - if (itr == m_port_map.end()) { - return nullptr; - } - return FetchFromHandle(itr->second); -} - +std::unordered_map> g_kernel_named_ports; +std::unordered_map> g_srv_services; //////////////////////////////////////////////////////////////////////////////////////////////////// // Module interface +static void AddNamedPort(Interface* interface) { + g_kernel_named_ports.emplace(interface->GetPortName(), interface); +} + +static void AddService(Interface* interface) { + g_srv_services.emplace(interface->GetPortName(), interface); +} + /// Initialize ServiceManager void Init() { - g_manager = new Manager; + AddNamedPort(new SRV::Interface); - g_manager->AddService(new SRV::Interface); - g_manager->AddService(new AC_U::Interface); - g_manager->AddService(new ACT_U::Interface); - g_manager->AddService(new AM_APP::Interface); - g_manager->AddService(new AM_NET::Interface); - g_manager->AddService(new AM_SYS::Interface); - g_manager->AddService(new APT_A::Interface); - g_manager->AddService(new APT_S::Interface); - g_manager->AddService(new APT_U::Interface); - g_manager->AddService(new BOSS_P::Interface); - g_manager->AddService(new BOSS_U::Interface); - g_manager->AddService(new CAM_U::Interface); - g_manager->AddService(new CECD_S::Interface); - g_manager->AddService(new CECD_U::Interface); - g_manager->AddService(new CFG_I::Interface); - g_manager->AddService(new CFG_S::Interface); - g_manager->AddService(new CFG_U::Interface); - g_manager->AddService(new CSND_SND::Interface); - g_manager->AddService(new DSP_DSP::Interface); - g_manager->AddService(new ERR_F::Interface); - g_manager->AddService(new FRD_A::Interface); - g_manager->AddService(new FRD_U::Interface); - g_manager->AddService(new FS::FSUserInterface); - g_manager->AddService(new GSP_GPU::Interface); - g_manager->AddService(new GSP_LCD::Interface); - g_manager->AddService(new HID_User::Interface); - g_manager->AddService(new HID_SPVR::Interface); - g_manager->AddService(new HTTP_C::Interface); - g_manager->AddService(new IR_RST::Interface); - g_manager->AddService(new IR_U::Interface); - g_manager->AddService(new LDR_RO::Interface); - g_manager->AddService(new MIC_U::Interface); - g_manager->AddService(new NDM_U::Interface); - g_manager->AddService(new NEWS_S::Interface); - g_manager->AddService(new NEWS_U::Interface); - g_manager->AddService(new NIM_AOC::Interface); - g_manager->AddService(new NS_S::Interface); - g_manager->AddService(new NWM_UDS::Interface); - g_manager->AddService(new PM_APP::Interface); - g_manager->AddService(new PTM_PLAY::Interface); - g_manager->AddService(new PTM_U::Interface); - g_manager->AddService(new PTM_SYSM::Interface); - g_manager->AddService(new SOC_U::Interface); - g_manager->AddService(new SSL_C::Interface); - g_manager->AddService(new Y2R_U::Interface); + AddService(new AC_U::Interface); + AddService(new ACT_U::Interface); + AddService(new AM_APP::Interface); + AddService(new AM_NET::Interface); + AddService(new AM_SYS::Interface); + AddService(new APT_A::Interface); + AddService(new APT_S::Interface); + AddService(new APT_U::Interface); + AddService(new BOSS_P::Interface); + AddService(new BOSS_U::Interface); + AddService(new CAM_U::Interface); + AddService(new CECD_S::Interface); + AddService(new CECD_U::Interface); + AddService(new CFG_I::Interface); + AddService(new CFG_S::Interface); + AddService(new CFG_U::Interface); + AddService(new CSND_SND::Interface); + AddService(new DSP_DSP::Interface); + AddService(new ERR_F::Interface); + AddService(new FRD_A::Interface); + AddService(new FRD_U::Interface); + AddService(new FS::FSUserInterface); + AddService(new GSP_GPU::Interface); + AddService(new GSP_LCD::Interface); + AddService(new HID_User::Interface); + AddService(new HID_SPVR::Interface); + AddService(new HTTP_C::Interface); + AddService(new IR_RST::Interface); + AddService(new IR_U::Interface); + AddService(new LDR_RO::Interface); + AddService(new MIC_U::Interface); + AddService(new NDM_U::Interface); + AddService(new NEWS_S::Interface); + AddService(new NEWS_U::Interface); + AddService(new NIM_AOC::Interface); + AddService(new NS_S::Interface); + AddService(new NWM_UDS::Interface); + AddService(new PM_APP::Interface); + AddService(new PTM_PLAY::Interface); + AddService(new PTM_U::Interface); + AddService(new PTM_SYSM::Interface); + AddService(new SOC_U::Interface); + AddService(new SSL_C::Interface); + AddService(new Y2R_U::Interface); LOG_DEBUG(Service, "initialized OK"); } /// Shutdown ServiceManager void Shutdown() { - delete g_manager; + g_srv_services.clear(); + g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index e75d5008b..533d3565b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -5,9 +5,10 @@ #pragma once #include -#include #include #include +#include +#include #include "common/common.h" #include "common/string_util.h" @@ -121,34 +122,15 @@ private: }; -/// Simple class to manage accessing services from ports and UID handles -class Manager { -public: - /// Add a service to the manager - void AddService(Interface* service); - - /// Removes a service from the manager - void DeleteService(const std::string& port_name); - - /// Get a Service Interface from its Handle - Interface* FetchFromHandle(Handle handle); - - /// Get a Service Interface from its port - Interface* FetchFromPortName(const std::string& port_name); - -private: - std::vector m_services; - std::map m_port_map; -}; - /// Initialize ServiceManager void Init(); /// Shutdown ServiceManager void Shutdown(); - -extern Manager* g_manager; ///< Service manager - +/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. +extern std::unordered_map> g_kernel_named_ports; +/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. +extern std::unordered_map> g_srv_services; } // namespace diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index aa0aac3bb..c50aebf15 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -35,10 +35,10 @@ static void GetServiceHandle(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); - Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); + auto it = Service::g_srv_services.find(port_name); - if (nullptr != service) { - cmd_buff[3] = service->GetHandle(); + if (it != Service::g_srv_services.end()) { + cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom(); LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); } else { LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 88813c2ce..d253f4fe5 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -30,6 +30,11 @@ using Kernel::ERR_INVALID_HANDLE; namespace SVC { +const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, + ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA +const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E + /// An invalid result code that is meant to be overwritten when a thread resumes from waiting const ResultCode RESULT_INVALID(0xDEADC0DE); @@ -94,14 +99,21 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o } /// Connect to an OS service given the port name, returns the handle to the port to out -static ResultCode ConnectToPort(Handle* out, const char* port_name) { - Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); +static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { + if (port_name == nullptr) + return ERR_NOT_FOUND; + if (std::strlen(port_name) > 11) + return ERR_PORT_NAME_TOO_LONG; LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); - _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); - *out = service->GetHandle(); + auto it = Service::g_kernel_named_ports.find(port_name); + if (it == Service::g_kernel_named_ports.end()) { + LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); + return ERR_NOT_FOUND; + } + CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second)); return RESULT_SUCCESS; } From a79d21c83e3fa433924999940c18e40fe980f50f Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 16:56:49 -0200 Subject: [PATCH 03/18] Service: Clean-up Interface --- src/core/hle/service/ac_u.cpp | 2 +- src/core/hle/service/act_u.cpp | 2 +- src/core/hle/service/am_app.cpp | 2 +- src/core/hle/service/am_net.cpp | 2 +- src/core/hle/service/am_sys.cpp | 2 +- src/core/hle/service/apt_a.cpp | 2 +- src/core/hle/service/apt_s.cpp | 2 +- src/core/hle/service/apt_u.cpp | 2 +- src/core/hle/service/boss_p.cpp | 2 +- src/core/hle/service/boss_u.cpp | 2 +- src/core/hle/service/cam_u.cpp | 2 +- src/core/hle/service/cecd_s.cpp | 2 +- src/core/hle/service/cecd_u.cpp | 2 +- src/core/hle/service/cfg/cfg_i.cpp | 2 +- src/core/hle/service/cfg/cfg_s.cpp | 2 +- src/core/hle/service/cfg/cfg_u.cpp | 2 +- src/core/hle/service/csnd_snd.cpp | 2 +- src/core/hle/service/dsp_dsp.cpp | 2 +- src/core/hle/service/err_f.cpp | 2 +- src/core/hle/service/frd_a.cpp | 2 +- src/core/hle/service/frd_u.cpp | 2 +- src/core/hle/service/fs/fs_user.cpp | 2 +- src/core/hle/service/gsp_gpu.cpp | 2 +- src/core/hle/service/gsp_lcd.cpp | 2 +- src/core/hle/service/hid/hid_spvr.cpp | 2 +- src/core/hle/service/hid/hid_user.cpp | 2 +- src/core/hle/service/http_c.cpp | 2 +- src/core/hle/service/ir_rst.cpp | 2 +- src/core/hle/service/ir_u.cpp | 2 +- src/core/hle/service/ldr_ro.cpp | 2 +- src/core/hle/service/mic_u.cpp | 2 +- src/core/hle/service/ndm_u.cpp | 2 +- src/core/hle/service/news_s.cpp | 2 +- src/core/hle/service/news_u.cpp | 2 +- src/core/hle/service/nim_aoc.cpp | 2 +- src/core/hle/service/ns_s.cpp | 2 +- src/core/hle/service/nwm_uds.cpp | 2 +- src/core/hle/service/pm_app.cpp | 2 +- src/core/hle/service/ptm_play.cpp | 2 +- src/core/hle/service/ptm_sysm.cpp | 2 +- src/core/hle/service/ptm_u.cpp | 2 +- src/core/hle/service/service.h | 31 ++++++++------------------- src/core/hle/service/soc_u.cpp | 2 +- src/core/hle/service/srv.cpp | 2 +- src/core/hle/service/ssl_c.cpp | 2 +- src/core/hle/service/y2r_u.cpp | 2 +- 46 files changed, 54 insertions(+), 67 deletions(-) diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 20a3fa2e5..53d920de1 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -53,7 +53,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp index 10870f14b..4ea7a9fb2 100644 --- a/src/core/hle/service/act_u.cpp +++ b/src/core/hle/service/act_u.cpp @@ -18,7 +18,7 @@ namespace ACT_U { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/am_app.cpp b/src/core/hle/service/am_app.cpp index 0b396b6d3..df10db87f 100644 --- a/src/core/hle/service/am_app.cpp +++ b/src/core/hle/service/am_app.cpp @@ -18,7 +18,7 @@ namespace AM_APP { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am_net.cpp index 112844e5b..c74012d9d 100644 --- a/src/core/hle/service/am_net.cpp +++ b/src/core/hle/service/am_net.cpp @@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp index b63c8c087..c5df8abda 100644 --- a/src/core/hle/service/am_sys.cpp +++ b/src/core/hle/service/am_sys.cpp @@ -18,7 +18,7 @@ namespace AM_SYS { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp index 42f2879c1..e1dd2a5fb 100644 --- a/src/core/hle/service/apt_a.cpp +++ b/src/core/hle/service/apt_a.cpp @@ -39,7 +39,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/apt_s.cpp b/src/core/hle/service/apt_s.cpp index 7ad428ee7..686335428 100644 --- a/src/core/hle/service/apt_s.cpp +++ b/src/core/hle/service/apt_s.cpp @@ -117,7 +117,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index 4c3f621d0..1e6f1f78c 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp @@ -520,7 +520,7 @@ Interface::Interface() { lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom(); - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/boss_p.cpp b/src/core/hle/service/boss_p.cpp index f245a38e9..b3aa6acee 100644 --- a/src/core/hle/service/boss_p.cpp +++ b/src/core/hle/service/boss_p.cpp @@ -18,7 +18,7 @@ namespace BOSS_P { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp index 1820ea7ad..50bb5d426 100644 --- a/src/core/hle/service/boss_u.cpp +++ b/src/core/hle/service/boss_u.cpp @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cam_u.cpp b/src/core/hle/service/cam_u.cpp index 549095339..cf3b27664 100644 --- a/src/core/hle/service/cam_u.cpp +++ b/src/core/hle/service/cam_u.cpp @@ -18,7 +18,7 @@ namespace CAM_U { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cecd_s.cpp b/src/core/hle/service/cecd_s.cpp index 9c4992f13..2c707baff 100644 --- a/src/core/hle/service/cecd_s.cpp +++ b/src/core/hle/service/cecd_s.cpp @@ -18,7 +18,7 @@ namespace CECD_S { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cecd_u.cpp b/src/core/hle/service/cecd_u.cpp index b7655ef0b..b7ea3a186 100644 --- a/src/core/hle/service/cecd_u.cpp +++ b/src/core/hle/service/cecd_u.cpp @@ -18,7 +18,7 @@ namespace CECD_U { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 7c1ee8ac3..555b7884a 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -104,7 +104,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index cf4e82152..2170894d6 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -92,7 +92,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 835620909..1da9f59f6 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -186,7 +186,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 3a557efe1..39b00982c 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -29,7 +29,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 9a38be393..7a18c1747 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -206,7 +206,7 @@ Interface::Interface() { interrupt_event = nullptr; read_pipe_count = 0; - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 8c900eabc..962de2170 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/frd_a.cpp b/src/core/hle/service/frd_a.cpp index 53edc2cd8..79140a756 100644 --- a/src/core/hle/service/frd_a.cpp +++ b/src/core/hle/service/frd_a.cpp @@ -18,7 +18,7 @@ namespace FRD_A { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/frd_u.cpp b/src/core/hle/service/frd_u.cpp index 021186e57..59faca77a 100644 --- a/src/core/hle/service/frd_u.cpp +++ b/src/core/hle/service/frd_u.cpp @@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 9cb7d809a..94a3a31c8 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -591,7 +591,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = { // Interface class FSUserInterface::FSUserInterface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace FS diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 5b91f17d2..936203318 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -389,7 +389,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); g_interrupt_event = 0; g_shared_memory = 0; diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index 6213472ff..d63fa1ee2 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp @@ -20,7 +20,7 @@ namespace GSP_LCD { // Interface class Interface::Interface() { - //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + //Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 76c40b659..054aa8b59 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -32,7 +32,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 5444aa5ee..68edafebb 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -72,7 +72,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index d0bff552f..6595ca572 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -58,7 +58,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp index d49bd5335..31da8e160 100644 --- a/src/core/hle/service/ir_rst.cpp +++ b/src/core/hle/service/ir_rst.cpp @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir_u.cpp index da6f38e41..7fa233048 100644 --- a/src/core/hle/service/ir_u.cpp +++ b/src/core/hle/service/ir_u.cpp @@ -36,7 +36,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 7d6e2e8e8..459717fff 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 82bce9180..af967b5b6 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -34,7 +34,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp index 0f03de6ae..df3c97193 100644 --- a/src/core/hle/service/ndm_u.cpp +++ b/src/core/hle/service/ndm_u.cpp @@ -24,7 +24,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/news_s.cpp b/src/core/hle/service/news_s.cpp index 1850f59bd..d7537875b 100644 --- a/src/core/hle/service/news_s.cpp +++ b/src/core/hle/service/news_s.cpp @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/news_u.cpp b/src/core/hle/service/news_u.cpp index b5adad4c6..a9e161c23 100644 --- a/src/core/hle/service/news_u.cpp +++ b/src/core/hle/service/news_u.cpp @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/nim_aoc.cpp b/src/core/hle/service/nim_aoc.cpp index 17d1c4ff5..ab2ef4429 100644 --- a/src/core/hle/service/nim_aoc.cpp +++ b/src/core/hle/service/nim_aoc.cpp @@ -25,7 +25,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index b9aca4257..5cf3e2039 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp @@ -21,7 +21,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index ce456a966..61fcb54ce 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -26,7 +26,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index 529dccafb..d61eaf80f 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp @@ -26,7 +26,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ptm_play.cpp b/src/core/hle/service/ptm_play.cpp index ae9e2925c..b357057fd 100644 --- a/src/core/hle/service/ptm_play.cpp +++ b/src/core/hle/service/ptm_play.cpp @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ptm_sysm.cpp b/src/core/hle/service/ptm_sysm.cpp index 4b5f86a47..b6f688de3 100644 --- a/src/core/hle/service/ptm_sysm.cpp +++ b/src/core/hle/service/ptm_sysm.cpp @@ -50,7 +50,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 753180add..7b465a348 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -137,7 +137,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file // TODO(Subv): In the future we should use the FS service to query this archive std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 533d3565b..121e69932 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -5,11 +5,12 @@ #pragma once #include -#include #include #include #include +#include + #include "common/common.h" #include "common/string_util.h" #include "core/mem_map.h" @@ -69,21 +70,6 @@ public: return "[UNKNOWN SERVICE PORT]"; } - /// Allocates a new handle for the service - Handle CreateHandle(Kernel::Object *obj) { - // TODO(yuriks): Fix error reporting - Handle handle = Kernel::g_handle_table.Create(obj).ValueOr(INVALID_HANDLE); - m_handles.push_back(handle); - return handle; - } - - /// Frees a handle from the service - template - void DeleteHandle(const Handle handle) { - Kernel::g_handle_table.Close(handle); - m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); - } - ResultVal SyncRequest() override { u32* cmd_buff = Kernel::GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); @@ -109,16 +95,17 @@ protected: /** * Registers the functions in the service */ - void Register(const FunctionInfo* functions, int len) { - for (int i = 0; i < len; i++) { - m_functions[functions[i].id] = functions[i]; + template + void Register(const FunctionInfo (&functions)[N]) { + m_functions.reserve(N); + for (auto& fn : functions) { + // Usually this array is sorted by id already, so hint to instead at the end + m_functions.emplace_hint(m_functions.cend(), fn.id, fn); } } private: - - std::vector m_handles; - std::map m_functions; + boost::container::flat_map m_functions; }; diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index bb8ee86be..414c53c54 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -734,7 +734,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } Interface::~Interface() { diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index c50aebf15..b140e9fe3 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -63,7 +63,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index 360516cdf..3f49c1c97 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index b3d873ef0..fc76d2721 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -54,7 +54,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + Register(FunctionTable); } } // namespace From 6e11570862e184a10b7954ec26e0d70b9e0c2def Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 17:15:02 -0200 Subject: [PATCH 04/18] Service: Store function names as const char* instead of std::string Uses less memory (strings and function table is stored in constant data) and speeds up start up (no need to allocate and copy strings). --- src/core/hle/service/service.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 121e69932..3370f9f9b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -29,7 +29,7 @@ static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 character class Manager; /// Interface to a CTROS service -class Interface : public Kernel::Session { +class Interface : public Kernel::Session { // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be // just something that encapsulates a session and acts as a helper to implement service // processes. @@ -40,11 +40,11 @@ class Interface : public Kernel::Session { * Creates a function string for logging, complete with the name (or header code, depending * on what's passed in) the port name, and all the cmd_buff arguments. */ - std::string MakeFunctionString(const std::string& name, const std::string& port_name, const u32* cmd_buff) { + std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { // Number of params == bits 0-5 + bits 6-11 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); - std::string function_string = Common::StringFromFormat("function '%s': port=%s", name.c_str(), port_name.c_str()); + std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); for (int i = 1; i <= num_params; ++i) { function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); } @@ -59,7 +59,7 @@ public: struct FunctionInfo { u32 id; Function func; - std::string name; + const char* name; }; /** @@ -76,13 +76,13 @@ public: if (itr == m_functions.end() || itr->second.func == nullptr) { std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; - LOG_ERROR(Service, "%s %s", "unknown/unimplemented", MakeFunctionString(function_name, GetPortName(), cmd_buff).c_str()); + LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); // TODO(bunnei): Hack - ignore error cmd_buff[1] = 0; return MakeResult(false); } else { - LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName(), cmd_buff).c_str()); + LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); } itr->second.func(this); From 664c79ff47054df845096e7e29d5cc437dfec2a2 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Fri, 30 Jan 2015 23:07:54 -0200 Subject: [PATCH 05/18] Thread: Modernize two functions that slipped through previous rebases --- src/core/hle/kernel/address_arbiter.cpp | 4 ++-- src/core/hle/kernel/thread.cpp | 9 ++++----- src/core/hle/kernel/thread.h | 15 +++++++-------- src/core/hle/svc.cpp | 6 +++--- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 2d01e2ef5..6e8f959f3 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -51,7 +51,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, case ArbitrationType::WaitIfLessThanWithTimeout: if ((s32)Memory::Read32(address) <= value) { Kernel::WaitCurrentThread_ArbitrateAddress(address); - Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); + GetCurrentThread()->WakeAfterDelay(nanoseconds); HLE::Reschedule(__func__); } break; @@ -71,7 +71,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, Memory::Write32(address, memory_value); if (memory_value <= value) { Kernel::WaitCurrentThread_ArbitrateAddress(address); - Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); + GetCurrentThread()->WakeAfterDelay(nanoseconds); HLE::Reschedule(__func__); } break; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 56950ebd4..1ea5589cb 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -248,14 +248,13 @@ static void ThreadWakeupCallback(u64 parameter, int cycles_late) { } -void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds) { +void Thread::WakeAfterDelay(s64 nanoseconds) { // Don't schedule a wakeup if the thread wants to wait forever if (nanoseconds == -1) return; - _dbg_assert_(Kernel, thread != nullptr); u64 microseconds = nanoseconds / 1000; - CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, thread->GetHandle()); + CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, GetHandle()); } void Thread::ReleaseWaitObject(WaitObject* wait_object) { @@ -418,7 +417,7 @@ void Thread::SetPriority(s32 priority) { } } -Handle SetupIdleThread() { +SharedPtr SetupIdleThread() { // We need to pass a few valid values to get around parameter checking in Thread::Create. auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); @@ -427,7 +426,7 @@ Handle SetupIdleThread() { thread->idle = true; CallThread(thread.get()); - return thread->GetHandle(); + return thread; } SharedPtr SetupMainThread(s32 priority, u32 stack_size) { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index d6299364a..cba074e07 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -77,6 +77,12 @@ public: /// Resumes a thread from waiting by marking it as "ready" void ResumeFromWait(); + /** + * Schedules an event to wake up the specified thread after the specified delay. + * @param nanoseconds The time this thread will be allowed to sleep for. + */ + void WakeAfterDelay(s64 nanoseconds); + /** * Sets the result after the thread awakens (from either WaitSynchronization SVC) * @param result Value to set to the returned result @@ -150,20 +156,13 @@ void WaitCurrentThread_WaitSynchronization(SharedPtr wait_object, bo */ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); -/** - * Schedules an event to wake up the specified thread after the specified delay. - * @param handle The thread handle. - * @param nanoseconds The time this thread will be allowed to sleep for. - */ -void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds); - /** * Sets up the idle thread, this is a thread that is intended to never execute instructions, * only to advance the timing. It is scheduled when there are no other ready threads in the thread queue * and will try to yield on every call. * @returns The handle of the idle thread */ -Handle SetupIdleThread(); +SharedPtr SetupIdleThread(); /// Initialize threading void ThreadingInit(); diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index d253f4fe5..1a0c07cb9 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -152,7 +152,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { Kernel::WaitCurrentThread_WaitSynchronization(object, false, false); // Create an event to wake the thread up after the specified nanosecond delay has passed - Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); + Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); HLE::Reschedule(__func__); @@ -228,7 +228,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou } // Create an event to wake the thread up after the specified nanosecond delay has passed - Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); + Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); HLE::Reschedule(__func__); @@ -540,7 +540,7 @@ static void SleepThread(s64 nanoseconds) { Kernel::WaitCurrentThread_Sleep(); // Create an event to wake the thread up after the specified nanosecond delay has passed - Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nanoseconds); + Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds); HLE::Reschedule(__func__); } From 8441591659a5176ab9d75309d4ecc9c2d6716e91 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 10:37:32 -0200 Subject: [PATCH 06/18] FS: Remove use of GetHandle --- src/core/hle/service/fs/archive.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 0ce9ad4d6..ccf132f31 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -163,7 +163,7 @@ public: case FileCommand::OpenLinkFile: { LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); - cmd_buff[3] = GetHandle(); + cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE); break; } From ec9c7732518a441ce740ef9e813fd85cc1d7410c Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 10:40:16 -0200 Subject: [PATCH 07/18] Kernel: Remove previous scheduled event when a Timer is re-Set --- src/core/hle/kernel/timer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 503a5d2ce..794be060c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -38,6 +38,9 @@ void Timer::Acquire() { } void Timer::Set(s64 initial, s64 interval) { + // Ensure we get rid of any previous scheduled event + Cancel(); + initial_delay = initial; interval_delay = interval; From a9b86db3cfec5ce907051d6730ffd98c0fd03876 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 14:23:09 -0200 Subject: [PATCH 08/18] Kernel: Use separate Handle tables for CoreTiming userdata This is to support the removal of GetHandle soon --- src/core/hle/kernel/thread.cpp | 22 +++++++++++----------- src/core/hle/kernel/thread.h | 3 +++ src/core/hle/kernel/timer.cpp | 15 ++++++++------- src/core/hle/kernel/timer.h | 3 +++ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 1ea5589cb..72a14bfac 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include "common/common.h" @@ -228,13 +227,15 @@ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { /// Event type for the thread wake up event static int ThreadWakeupEventType = -1; +// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing +// us to simply use a pool index or similar. +static Kernel::HandleTable wakeup_callback_handle_table; /// Callback that will wake up the thread it was scheduled for -static void ThreadWakeupCallback(u64 parameter, int cycles_late) { - Handle handle = static_cast(parameter); - SharedPtr thread = Kernel::g_handle_table.Get(handle); +static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { + SharedPtr thread = wakeup_callback_handle_table.Get((Handle)thread_handle); if (thread == nullptr) { - LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); + LOG_CRITICAL(Kernel, "Callback fired for invalid thread %08X", thread_handle); return; } @@ -254,7 +255,7 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { return; u64 microseconds = nanoseconds / 1000; - CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, GetHandle()); + CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, callback_handle); } void Thread::ReleaseWaitObject(WaitObject* wait_object) { @@ -301,7 +302,7 @@ void Thread::ReleaseWaitObject(WaitObject* wait_object) { void Thread::ResumeFromWait() { // Cancel any outstanding wakeup events - CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); + CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); status &= ~THREADSTATUS_WAIT; @@ -384,6 +385,7 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, thread->wait_objects.clear(); thread->wait_address = 0; thread->name = std::move(name); + thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); ResetThread(thread.get(), arg, 0); CallThread(thread.get()); @@ -419,10 +421,8 @@ void Thread::SetPriority(s32 priority) { SharedPtr SetupIdleThread() { // We need to pass a few valid values to get around parameter checking in Thread::Create. - auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, - THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); - _dbg_assert_(Kernel, thread_res.Succeeded()); - SharedPtr thread = std::move(*thread_res); + auto thread = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, + THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE).MoveFrom(); thread->idle = true; CallThread(thread.get()); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index cba074e07..9a4a00fe8 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -122,6 +122,9 @@ public: private: Thread() = default; + + /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. + Handle callback_handle; }; /// Sets up the primary application thread diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 794be060c..90e5e64b3 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -2,8 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include - #include "common/common.h" #include "core/core_timing.h" @@ -15,6 +13,9 @@ namespace Kernel { /// The event type of the generic timer callback event static int timer_callback_event_type = -1; +// TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing +// us to simply use a pool index or similar. +static Kernel::HandleTable timer_callback_handle_table; ResultVal> Timer::Create(ResetType reset_type, std::string name) { SharedPtr timer(new Timer); @@ -26,6 +27,7 @@ ResultVal> Timer::Create(ResetType reset_type, std::string name timer->name = std::move(name); timer->initial_delay = 0; timer->interval_delay = 0; + timer->callback_handle = timer_callback_handle_table.Create(timer).MoveFrom(); return MakeResult>(timer); } @@ -45,13 +47,12 @@ void Timer::Set(s64 initial, s64 interval) { interval_delay = interval; u64 initial_microseconds = initial / 1000; - // TODO(yuriks): Figure out a replacement for GetHandle here - CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, - GetHandle()); + CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), + timer_callback_event_type, callback_handle); } void Timer::Cancel() { - CoreTiming::UnscheduleEvent(timer_callback_event_type, GetHandle()); + CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_handle); } void Timer::Clear() { @@ -60,7 +61,7 @@ void Timer::Clear() { /// The timer callback event, called when a timer is fired static void TimerCallback(u64 timer_handle, int cycles_late) { - SharedPtr timer = Kernel::g_handle_table.Get(timer_handle); + SharedPtr timer = timer_callback_handle_table.Get(timer_handle); if (timer == nullptr) { LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08X", timer_handle); diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index c45e79954..f72b8b31b 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -50,6 +50,9 @@ public: private: Timer() = default; + + /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. + Handle callback_handle; }; /// Initializes the required variables for timers From 869ec46683c508de5692eaace1a66e682f90b4de Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 14:55:40 -0200 Subject: [PATCH 09/18] Kernel: Introduce unique Object ids for debugging --- src/core/hle/kernel/kernel.cpp | 2 ++ src/core/hle/kernel/kernel.h | 6 ++++++ src/core/hle/kernel/shared_memory.cpp | 6 +++--- src/core/hle/kernel/thread.cpp | 10 +++++----- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d7fa4dcea..a2459e7b1 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -14,6 +14,8 @@ namespace Kernel { +unsigned int Object::next_object_id = 0; + SharedPtr g_main_thread = nullptr; HandleTable g_handle_table; u64 g_program_id = 0; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 9860479ac..5567780fe 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -67,6 +67,9 @@ public: virtual ~Object() {} Handle GetHandle() const { return handle; } + /// Returns a unique identifier for the object. For debugging purposes only. + unsigned int GetObjectId() const { return object_id; } + virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } virtual Kernel::HandleType GetHandleType() const = 0; @@ -101,7 +104,10 @@ private: friend void intrusive_ptr_add_ref(Object*); friend void intrusive_ptr_release(Object*); + static unsigned int next_object_id; + unsigned int ref_count = 0; + unsigned int object_id = next_object_id++; }; // Special functions used by boost::instrusive_ptr to do automatic ref-counting diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index eff68d481..b586c9903 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -23,8 +23,8 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, MemoryPermission other_permissions) { if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { - LOG_ERROR(Kernel, "cannot map handle=0x%08X, address=0x%08X outside of shared mem bounds!", - GetHandle(), address); + LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!", + GetObjectId(), address); // TODO: Verify error code with hardware return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); @@ -41,7 +41,7 @@ ResultVal SharedMemory::GetPointer(u32 offset) { if (base_address != 0) return MakeResult(Memory::GetPointer(base_address + offset)); - LOG_ERROR(Kernel_SVC, "memory block handle=0x%08X not mapped!", GetHandle()); + LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId()); // TODO(yuriks): Verify error code. return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, ErrorSummary::InvalidState, ErrorLevel::Permanent); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 72a14bfac..2fae1b3bc 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -326,11 +326,11 @@ static void DebugThreadQueue() { if (!thread) { return; } - LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); + LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority, GetCurrentThread()->GetObjectId()); for (auto& t : thread_list) { s32 priority = thread_ready_queue.contains(t.get()); if (priority != -1) { - LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); + LOG_DEBUG(Kernel, "0x%02X %u", priority, t->GetObjectId()); } } } @@ -459,13 +459,13 @@ void Reschedule() { HLE::g_reschedule = false; if (next != nullptr) { - LOG_TRACE(Kernel, "context switch 0x%08X -> 0x%08X", prev->GetHandle(), next->GetHandle()); + LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId()); SwitchContext(next); } else { - LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); + LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId()); for (auto& thread : thread_list) { - LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X", thread->GetHandle(), + LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(), thread->current_priority, thread->status); } } From 5354a479bccc2ab47692e6cb237ec66ee8251207 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 14:57:32 -0200 Subject: [PATCH 10/18] Kernel: Remove Object::GetHandle (it's not used anymore :D) --- src/core/hle/kernel/kernel.cpp | 5 +---- src/core/hle/kernel/kernel.h | 5 ----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a2459e7b1..645c3bafc 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -76,13 +76,10 @@ ResultVal HandleTable::Create(SharedPtr obj) { // CTR-OS doesn't use generation 0, so skip straight to 1. if (next_generation >= (1 << 15)) next_generation = 1; - Handle handle = generation | (slot << 15); - if (obj->handle == INVALID_HANDLE) - obj->handle = handle; - generations[slot] = generation; objects[slot] = std::move(obj); + Handle handle = generation | (slot << 15); return MakeResult(handle); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5567780fe..bf5b47a61 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -58,14 +58,9 @@ enum { DEFAULT_STACK_SIZE = 0x4000, }; -class HandleTable; - class Object : NonCopyable { - friend class HandleTable; - u32 handle = INVALID_HANDLE; public: virtual ~Object() {} - Handle GetHandle() const { return handle; } /// Returns a unique identifier for the object. For debugging purposes only. unsigned int GetObjectId() const { return object_id; } From e8330dd162ac9669befc68c64772543d7884ac7f Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 16:12:20 -0200 Subject: [PATCH 11/18] Kernel: Fix bug in HandleTable::Close --- src/core/hle/kernel/kernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 645c3bafc..a24c2f69f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -101,7 +101,7 @@ ResultCode HandleTable::Close(Handle handle) { objects[slot] = nullptr; - generations[generation] = next_free_slot; + generations[slot] = next_free_slot; next_free_slot = slot; return RESULT_SUCCESS; } From c4208c1171afe5522f1237480a49aac855313ff8 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 16:12:54 -0200 Subject: [PATCH 12/18] SVC: Enable CloseHandle, clean up DuplicateHandle --- src/core/hle/svc.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 1a0c07cb9..8bfa1428e 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -131,9 +131,8 @@ static ResultCode SendSyncRequest(Handle handle) { /// Close a handle static ResultCode CloseHandle(Handle handle) { - // ImplementMe - LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle); - return RESULT_SUCCESS; + LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle); + return Kernel::g_handle_table.Close(handle); } /// Wait for a handle to synchronize, timeout after the specified nanoseconds @@ -445,12 +444,9 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { /// Duplicates a kernel handle static ResultCode DuplicateHandle(Handle* out, Handle handle) { - ResultVal out_h = Kernel::g_handle_table.Duplicate(handle); - if (out_h.Succeeded()) { - *out = *out_h; - LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); - } - return out_h.Code(); + CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle)); + LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); + return RESULT_SUCCESS; } /// Signals an event From 0f69668fc61f7453b4c6451186b515762532c35a Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 16:13:23 -0200 Subject: [PATCH 13/18] HID: Fix crash when pressing a key when the emulator is stopped --- src/core/hle/service/hid/hid.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 835055af4..b6e4861d2 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -30,6 +30,8 @@ static s16 next_circle_y = 0; * Gets a pointer to the PadData structure inside HID shared memory */ static inline PadData* GetPadData() { + if (g_shared_mem == nullptr) + return nullptr; return reinterpret_cast(g_shared_mem->GetPointer().ValueOr(nullptr)); } From 4e84df8be30c5bac65e4c4e9faf07bf0fc3fb33a Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 19:22:40 -0200 Subject: [PATCH 14/18] Mutex: Replace g_mutex_held_locks with a set inside Thread --- src/core/hle/kernel/mutex.cpp | 28 +++++++--------------------- src/core/hle/kernel/thread.cpp | 3 +++ src/core/hle/kernel/thread.h | 10 ++++++++-- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index acf484659..6fdcc97ee 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include "common/common.h" #include "core/hle/kernel/kernel.h" @@ -13,9 +15,6 @@ namespace Kernel { -typedef std::multimap, SharedPtr> MutexMap; -static MutexMap g_mutex_held_locks; - /** * Resumes a thread waiting for the specified mutex * @param mutex The mutex that some thread is waiting on @@ -33,15 +32,10 @@ static void ResumeWaitingThread(Mutex* mutex) { } void ReleaseThreadMutexes(Thread* thread) { - auto locked_range = g_mutex_held_locks.equal_range(thread); - - // Release every mutex that the thread holds, and resume execution on the waiting threads - for (auto iter = locked_range.first; iter != locked_range.second; ++iter) { - ResumeWaitingThread(iter->second.get()); + for (auto& mtx : thread->held_mutexes) { + ResumeWaitingThread(mtx.get()); } - - // Erase all the locks that this thread holds - g_mutex_held_locks.erase(thread); + thread->held_mutexes.clear(); } ResultVal> Mutex::Create(bool initial_locked, std::string name) { @@ -76,7 +70,7 @@ void Mutex::Acquire(Thread* thread) { locked = true; - g_mutex_held_locks.insert(std::make_pair(thread, this)); + thread->held_mutexes.insert(this); holding_thread = thread; } @@ -84,15 +78,7 @@ void Mutex::Release() { if (!locked) return; - auto locked_range = g_mutex_held_locks.equal_range(holding_thread); - - for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) { - if (iter->second == this) { - g_mutex_held_locks.erase(iter); - break; - } - } - + holding_thread->held_mutexes.erase(this); ResumeWaitingThread(this); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 2fae1b3bc..3c6669ca2 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -40,6 +40,9 @@ static Thread* current_thread; static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup static u32 next_thread_id; ///< The next available thread id +Thread::Thread() { +} + Thread* GetCurrentThread() { return current_thread; } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9a4a00fe8..f29897ae8 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -7,6 +7,8 @@ #include #include +#include + #include "common/common_types.h" #include "core/core.h" @@ -40,6 +42,8 @@ enum ThreadStatus { namespace Kernel { +class Mutex; + class Thread final : public WaitObject { public: static ResultVal> Create(std::string name, VAddr entry_point, s32 priority, @@ -109,8 +113,10 @@ public: s32 processor_id; - std::vector> wait_objects; ///< Objects that the thread is waiting on + /// Mutexes currently held by this thread, which will be released when it exits. + boost::container::flat_set> held_mutexes; + std::vector> wait_objects; ///< Objects that the thread is waiting on VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address bool wait_all; ///< True if the thread is waiting on all objects before resuming bool wait_set_output; ///< True if the output parameter should be set on thread wakeup @@ -121,7 +127,7 @@ public: bool idle = false; private: - Thread() = default; + Thread(); /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. Handle callback_handle; From 12232e0b08152a9cc39bf83c7214673257d7466f Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 20:27:35 -0200 Subject: [PATCH 15/18] Update boost external --- externals/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/boost b/externals/boost index a1afc91d3..728a4d7d1 160000 --- a/externals/boost +++ b/externals/boost @@ -1 +1 @@ -Subproject commit a1afc91d3aaa3da06bdbc13c78613e1466653405 +Subproject commit 728a4d7d1c8b28355544ae829df9c4b5f28373c5 From 7725256f649719dcce2c50ea84e79d6199dd9a50 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 22:56:59 -0200 Subject: [PATCH 16/18] Explicitly instantiate constructors/destructors for Kernel objects This should speed up compile times a bit, as well as enable more liberal use of forward declarations. (Due to SharedPtr not trying to emit the destructor anymore.) --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/address_arbiter.cpp | 3 +++ src/core/hle/kernel/address_arbiter.h | 3 ++- src/core/hle/kernel/event.cpp | 3 +++ src/core/hle/kernel/event.h | 3 ++- src/core/hle/kernel/mutex.cpp | 3 +++ src/core/hle/kernel/mutex.h | 3 ++- src/core/hle/kernel/semaphore.cpp | 3 +++ src/core/hle/kernel/semaphore.h | 3 ++- src/core/hle/kernel/session.cpp | 13 +++++++++++++ src/core/hle/kernel/session.h | 4 ++++ src/core/hle/kernel/shared_memory.cpp | 3 +++ src/core/hle/kernel/shared_memory.h | 3 ++- src/core/hle/kernel/thread.cpp | 4 ++-- src/core/hle/kernel/thread.h | 1 + src/core/hle/kernel/timer.cpp | 3 +++ src/core/hle/kernel/timer.h | 3 ++- 17 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 src/core/hle/kernel/session.cpp diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ac173c486..0ab0e440c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -26,6 +26,7 @@ set(SRCS hle/kernel/kernel.cpp hle/kernel/mutex.cpp hle/kernel/semaphore.cpp + hle/kernel/session.cpp hle/kernel/shared_memory.cpp hle/kernel/timer.cpp hle/kernel/thread.cpp diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 6e8f959f3..2084f24cc 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -15,6 +15,9 @@ namespace Kernel { +AddressArbiter::AddressArbiter() {} +AddressArbiter::~AddressArbiter() {} + ResultVal> AddressArbiter::Create(std::string name) { SharedPtr address_arbiter(new AddressArbiter); // TOOD(yuriks): Don't create Handle (see Thread::Create()) diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 638afff9e..a616d840f 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -47,7 +47,8 @@ public: ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); private: - AddressArbiter() = default; + AddressArbiter(); + ~AddressArbiter() override; }; } // namespace FileSys diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index d9ad40c6a..3796fbb74 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -14,6 +14,9 @@ namespace Kernel { +Event::Event() {} +Event::~Event() {} + ResultVal> Event::Create(ResetType reset_type, std::string name) { SharedPtr evt(new Event); // TOOD(yuriks): Don't create Handle (see Thread::Create()) diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 2c3e6b14e..6f88afb3e 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -39,7 +39,8 @@ public: void Clear(); private: - Event() = default; + Event(); + ~Event() override; }; } // namespace diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 6fdcc97ee..c6ad5ca91 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -38,6 +38,9 @@ void ReleaseThreadMutexes(Thread* thread) { thread->held_mutexes.clear(); } +Mutex::Mutex() {} +Mutex::~Mutex() {} + ResultVal> Mutex::Create(bool initial_locked, std::string name) { SharedPtr mutex(new Mutex); // TOOD(yuriks): Don't create Handle (see Thread::Create()) diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1e69528f1..21fd26e56 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -47,7 +47,8 @@ public: void Release(); private: - Mutex() = default; + Mutex(); + ~Mutex() override; }; /** diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index a9e406ef4..234d60d85 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -10,6 +10,9 @@ namespace Kernel { +Semaphore::Semaphore() {} +Semaphore::~Semaphore() {} + ResultVal> Semaphore::Create(s32 initial_count, s32 max_count, std::string name) { diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 9bb404ab6..d8dc1fd78 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -47,7 +47,8 @@ public: ResultVal Release(s32 release_count); private: - Semaphore() = default; + Semaphore(); + ~Semaphore() override; }; } // namespace diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp new file mode 100644 index 000000000..0594967f8 --- /dev/null +++ b/src/core/hle/kernel/session.cpp @@ -0,0 +1,13 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/kernel/session.h" +#include "core/hle/kernel/thread.h" + +namespace Kernel { + +Session::Session() {} +Session::~Session() {} + +} diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 1788e4375..7cc9332c9 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -5,6 +5,7 @@ #pragma once #include "core/hle/kernel/kernel.h" +#include "core/mem_map.h" namespace Kernel { @@ -43,6 +44,9 @@ inline static u32* GetCommandBuffer(const int offset=0) { */ class Session : public WaitObject { public: + Session(); + ~Session() override; + std::string GetTypeName() const override { return "Session"; } static const HandleType HANDLE_TYPE = HandleType::Session; diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index b586c9903..c429bb9b4 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -9,6 +9,9 @@ namespace Kernel { +SharedMemory::SharedMemory() {} +SharedMemory::~SharedMemory() {} + ResultVal> SharedMemory::Create(std::string name) { SharedPtr shared_memory(new SharedMemory); diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index d393e8175..d9e741d20 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -57,7 +57,8 @@ public: std::string name; ///< Name of shared memory object (optional) private: - SharedMemory() = default; + SharedMemory(); + ~SharedMemory() override; }; } // namespace diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 3c6669ca2..9ad53b8cf 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -40,8 +40,8 @@ static Thread* current_thread; static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup static u32 next_thread_id; ///< The next available thread id -Thread::Thread() { -} +Thread::Thread() {} +Thread::~Thread() {} Thread* GetCurrentThread() { return current_thread; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f29897ae8..980c2613a 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -128,6 +128,7 @@ public: private: Thread(); + ~Thread() override; /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. Handle callback_handle; diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 90e5e64b3..7c3cdc0d0 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -17,6 +17,9 @@ static int timer_callback_event_type = -1; // us to simply use a pool index or similar. static Kernel::HandleTable timer_callback_handle_table; +Timer::Timer() {} +Timer::~Timer() {} + ResultVal> Timer::Create(ResetType reset_type, std::string name) { SharedPtr timer(new Timer); // TOOD(yuriks): Don't create Handle (see Thread::Create()) diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index f72b8b31b..e217d6dae 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -49,7 +49,8 @@ public: void Clear(); private: - Timer() = default; + Timer(); + ~Timer() override; /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. Handle callback_handle; From 52f58e64efbf43c114f701eb8f39fb463138ffb8 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sat, 31 Jan 2015 23:26:16 -0200 Subject: [PATCH 17/18] Kernel: Make WaitObjects share ownership of Threads waiting on them During normal operation, a thread waiting on an WaitObject and the object hold mutual references to each other for the duration of the wait. If a process is forcefully terminated (The CTR kernel has a SVC to do this, TerminateProcess, though no equivalent exists for threads.) its threads would also be stopped and destroyed, leaving dangling pointers in the WaitObjects. The solution is to simply have the Thread remove itself from WaitObjects when it is stopped. The vector of Threads in WaitObject has also been changed to hold SharedPtrs, just in case. (Better to have a reference cycle than a crash.) --- src/core/hle/kernel/kernel.cpp | 8 ++++---- src/core/hle/kernel/kernel.h | 10 +++++----- src/core/hle/kernel/mutex.cpp | 4 ++-- src/core/hle/kernel/mutex.h | 2 +- src/core/hle/kernel/thread.cpp | 3 +++ src/core/hle/kernel/thread.h | 2 ++ 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index a24c2f69f..7e0b9542e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -20,10 +20,10 @@ SharedPtr g_main_thread = nullptr; HandleTable g_handle_table; u64 g_program_id = 0; -void WaitObject::AddWaitingThread(Thread* thread) { +void WaitObject::AddWaitingThread(SharedPtr thread) { auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); if (itr == waiting_threads.end()) - waiting_threads.push_back(thread); + waiting_threads.push_back(std::move(thread)); } void WaitObject::RemoveWaitingThread(Thread* thread) { @@ -32,11 +32,11 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { waiting_threads.erase(itr); } -Thread* WaitObject::WakeupNextThread() { +SharedPtr WaitObject::WakeupNextThread() { if (waiting_threads.empty()) return nullptr; - auto next_thread = waiting_threads.front(); + auto next_thread = std::move(waiting_threads.front()); waiting_threads.erase(waiting_threads.begin()); next_thread->ReleaseWaitObject(this); diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index bf5b47a61..4d8e388b6 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -136,25 +136,26 @@ public: * Add a thread to wait on this object * @param thread Pointer to thread to add */ - void AddWaitingThread(Thread* thread); + void AddWaitingThread(SharedPtr thread); /** * Removes a thread from waiting on this object (e.g. if it was resumed already) * @param thread Pointer to thread to remove */ - void RemoveWaitingThread(Thread* thead); + void RemoveWaitingThread(Thread* thread); /** * Wake up the next thread waiting on this object * @return Pointer to the thread that was resumed, nullptr if no threads are waiting */ - Thread* WakeupNextThread(); + SharedPtr WakeupNextThread(); /// Wake up all threads waiting on this object void WakeupAllWaitingThreads(); private: - std::vector waiting_threads; ///< Threads waiting for this object to become available + /// Threads waiting for this object to become available + std::vector> waiting_threads; }; /** @@ -275,7 +276,6 @@ private: }; extern HandleTable g_handle_table; -extern SharedPtr g_main_thread; /// The ID code of the currently running game /// 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 c6ad5ca91..7c634f9bd 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -66,7 +66,7 @@ void Mutex::Acquire() { Acquire(GetCurrentThread()); } -void Mutex::Acquire(Thread* thread) { +void Mutex::Acquire(SharedPtr thread) { _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); if (locked) return; @@ -74,7 +74,7 @@ void Mutex::Acquire(Thread* thread) { locked = true; thread->held_mutexes.insert(this); - holding_thread = thread; + holding_thread = std::move(thread); } void Mutex::Release() { diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 21fd26e56..cdd79e265 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -43,7 +43,7 @@ public: * @param mutex Mutex that is to be acquired * @param thread Thread that will acquire the mutex */ - void Acquire(Thread* thread); + void Acquire(SharedPtr thread); void Release(); private: diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 9ad53b8cf..f092916dd 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -110,6 +110,9 @@ void Thread::Stop(const char* reason) { WakeupAllWaitingThreads(); // Stopped threads are never waiting. + for (auto& wait_object : wait_objects) { + wait_object->RemoveWaitingThread(this); + } wait_objects.clear(); wait_address = 0; } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 980c2613a..633bb7c98 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -134,6 +134,8 @@ private: Handle callback_handle; }; +extern SharedPtr g_main_thread; + /// Sets up the primary application thread SharedPtr SetupMainThread(s32 priority, u32 stack_size); From 88a4a808c688eeabb136e9b45223a0e9c95896bc Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 1 Feb 2015 00:14:40 -0200 Subject: [PATCH 18/18] Kernel: Stop creating useless Handles during object creation They're finally unnecessary, and will stop cluttering the application's handle table. --- src/core/hle/kernel/address_arbiter.cpp | 6 ++---- src/core/hle/kernel/address_arbiter.h | 2 +- src/core/hle/kernel/event.cpp | 6 ++---- src/core/hle/kernel/event.h | 2 +- src/core/hle/kernel/mutex.cpp | 6 ++---- src/core/hle/kernel/mutex.h | 2 +- src/core/hle/kernel/semaphore.cpp | 2 -- src/core/hle/kernel/shared_memory.cpp | 8 +++----- src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/kernel/thread.cpp | 8 -------- src/core/hle/kernel/timer.cpp | 7 +++---- src/core/hle/kernel/timer.h | 2 +- src/core/hle/service/apt_u.cpp | 8 ++++---- src/core/hle/service/dsp_dsp.cpp | 3 +-- src/core/hle/service/gsp_gpu.cpp | 2 +- src/core/hle/service/hid/hid.cpp | 12 ++++++------ src/core/hle/service/srv.cpp | 2 +- src/core/hle/svc.cpp | 18 +++++++++++------- 18 files changed, 41 insertions(+), 57 deletions(-) diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 2084f24cc..42f8ce2d9 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -18,14 +18,12 @@ namespace Kernel { AddressArbiter::AddressArbiter() {} AddressArbiter::~AddressArbiter() {} -ResultVal> AddressArbiter::Create(std::string name) { +SharedPtr AddressArbiter::Create(std::string name) { SharedPtr address_arbiter(new AddressArbiter); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(address_arbiter)); address_arbiter->name = std::move(name); - return MakeResult>(std::move(address_arbiter)); + return address_arbiter; } ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index a616d840f..8f6a1a8df 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -34,7 +34,7 @@ public: * @param name Optional name used for debugging. * @returns The created AddressArbiter. */ - static ResultVal> Create(std::string name = "Unknown"); + static SharedPtr Create(std::string name = "Unknown"); std::string GetTypeName() const override { return "Arbiter"; } std::string GetName() const override { return name; } diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 3796fbb74..898e1c98f 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -17,16 +17,14 @@ namespace Kernel { Event::Event() {} Event::~Event() {} -ResultVal> Event::Create(ResetType reset_type, std::string name) { +SharedPtr Event::Create(ResetType reset_type, std::string name) { SharedPtr evt(new Event); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(evt)); evt->signaled = false; evt->reset_type = evt->intitial_reset_type = reset_type; evt->name = std::move(name); - return MakeResult>(evt); + return evt; } bool Event::ShouldWait() { diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 6f88afb3e..fba960d2a 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -18,7 +18,7 @@ public: * @param reset_type ResetType describing how to create event * @param name Optional name of event */ - static ResultVal> Create(ResetType reset_type, std::string name = "Unknown"); + static SharedPtr Create(ResetType reset_type, std::string name = "Unknown"); std::string GetTypeName() const override { return "Event"; } std::string GetName() const override { return name; } diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 7c634f9bd..9f7166ca4 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -41,10 +41,8 @@ void ReleaseThreadMutexes(Thread* thread) { Mutex::Mutex() {} Mutex::~Mutex() {} -ResultVal> Mutex::Create(bool initial_locked, std::string name) { +SharedPtr Mutex::Create(bool initial_locked, std::string name) { SharedPtr mutex(new Mutex); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(mutex)); mutex->initial_locked = initial_locked; mutex->locked = false; @@ -55,7 +53,7 @@ ResultVal> Mutex::Create(bool initial_locked, std::string name) if (initial_locked) mutex->Acquire(); - return MakeResult>(mutex); + return mutex; } bool Mutex::ShouldWait() { diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index cdd79e265..548403614 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -22,7 +22,7 @@ public: * @param name Optional name of mutex * @return Pointer to new Mutex object */ - static ResultVal> Create(bool initial_locked, std::string name = "Unknown"); + static SharedPtr Create(bool initial_locked, std::string name = "Unknown"); std::string GetTypeName() const override { return "Mutex"; } std::string GetName() const override { return name; } diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 234d60d85..c8cf8b9a2 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -21,8 +21,6 @@ ResultVal> Semaphore::Create(s32 initial_count, s32 max_cou ErrorSummary::WrongArgument, ErrorLevel::Permanent); SharedPtr semaphore(new Semaphore); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(semaphore)); // When the semaphore is created, some slots are reserved for other threads, // and the rest is reserved for the caller thread diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index c429bb9b4..4211fcf04 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -12,14 +12,12 @@ namespace Kernel { SharedMemory::SharedMemory() {} SharedMemory::~SharedMemory() {} -ResultVal> SharedMemory::Create(std::string name) { +SharedPtr SharedMemory::Create(std::string name) { SharedPtr shared_memory(new SharedMemory); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(shared_memory)); - shared_memory->name = std::move(name); - return MakeResult>(std::move(shared_memory)); + + return shared_memory; } ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index d9e741d20..5833b411c 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -29,7 +29,7 @@ public: * Creates a shared memory object * @param name Optional object name, used only for debugging purposes. */ - static ResultVal> Create(std::string name = "Unknown"); + static SharedPtr Create(std::string name = "Unknown"); std::string GetTypeName() const override { return "SharedMemory"; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f092916dd..3987f9608 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -368,14 +368,6 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, SharedPtr thread(new Thread); - // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for - // the time being. Create a handle here, it will be copied to the handle field in - // the object and use by the rest of the code. This should be removed when other - // code doesn't rely on the handle anymore. - ResultVal handle = Kernel::g_handle_table.Create(thread); - if (handle.Failed()) - return handle.Code(); - thread_list.push_back(thread); thread_ready_queue.prepare(priority); diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 7c3cdc0d0..4352fc99c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -20,10 +20,8 @@ static Kernel::HandleTable timer_callback_handle_table; Timer::Timer() {} Timer::~Timer() {} -ResultVal> Timer::Create(ResetType reset_type, std::string name) { +SharedPtr Timer::Create(ResetType reset_type, std::string name) { SharedPtr timer(new Timer); - // TOOD(yuriks): Don't create Handle (see Thread::Create()) - CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(timer)); timer->reset_type = reset_type; timer->signaled = false; @@ -31,7 +29,8 @@ ResultVal> Timer::Create(ResetType reset_type, std::string name timer->initial_delay = 0; timer->interval_delay = 0; timer->callback_handle = timer_callback_handle_table.Create(timer).MoveFrom(); - return MakeResult>(timer); + + return timer; } bool Timer::ShouldWait() { diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index e217d6dae..540e4e187 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -19,7 +19,7 @@ public: * @param name Optional name of timer * @return The created Timer */ - static ResultVal> Create(ResetType reset_type, std::string name = "Unknown"); + static SharedPtr Create(ResetType reset_type, std::string name = "Unknown"); std::string GetTypeName() const override { return "Timer"; } std::string GetName() const override { return name; } diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index 1e6f1f78c..ccfd04591 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp @@ -69,8 +69,8 @@ void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(bunnei): Check if these are created in Initialize or on APT process startup. - notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification").MoveFrom(); - pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause").MoveFrom(); + notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification"); + pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause"); cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom(); cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom(); @@ -512,13 +512,13 @@ Interface::Interface() { file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); // Create shared font memory object - shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem").MoveFrom(); + shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem"); } else { LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); shared_font_mem = nullptr; } - lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom(); + lock = Kernel::Mutex::Create(false, "APT_U:Lock"); Register(FunctionTable); } diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 7a18c1747..0f86894a6 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -201,8 +201,7 @@ const Interface::FunctionInfo FunctionTable[] = { // Interface class Interface::Interface() { - semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, - "DSP_DSP::semaphore_event").MoveFrom(); + semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); interrupt_event = nullptr; read_pipe_count = 0; diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 936203318..495c117ee 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -187,7 +187,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { g_interrupt_event = Kernel::g_handle_table.Get(cmd_buff[3]); _assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!"); - g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom(); + g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem"); Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index b6e4861d2..7cb01729e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -124,14 +124,14 @@ void PadUpdateComplete() { void HIDInit() { using namespace Kernel; - g_shared_mem = SharedMemory::Create("HID:SharedMem").MoveFrom(); + g_shared_mem = SharedMemory::Create("HID:SharedMem"); // Create event handles - g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1").MoveFrom(); - g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2").MoveFrom(); - g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer").MoveFrom(); - g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope").MoveFrom(); - g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad").MoveFrom(); + g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1"); + g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2"); + g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer"); + g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope"); + g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad"); } void HIDShutdown() { diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index b140e9fe3..cc59a03ce 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -23,7 +23,7 @@ static void GetProcSemaphore(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // TODO(bunnei): Change to a semaphore once these have been implemented - event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event").MoveFrom(); + event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event"); event_handle->Clear(); cmd_buff[1] = 0; // No error diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 8bfa1428e..34a27917f 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -261,7 +261,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou static ResultCode CreateAddressArbiter(Handle* out_handle) { using Kernel::AddressArbiter; - CASCADE_RESULT(SharedPtr arbiter, AddressArbiter::Create()); + SharedPtr arbiter = AddressArbiter::Create(); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(arbiter))); LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *out_handle); return RESULT_SUCCESS; @@ -366,7 +366,7 @@ static ResultCode SetThreadPriority(Handle handle, s32 priority) { static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { using Kernel::Mutex; - CASCADE_RESULT(SharedPtr mutex, Mutex::Create(initial_locked != 0)); + SharedPtr mutex = Mutex::Create(initial_locked != 0); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", @@ -434,7 +434,9 @@ static ResultCode QueryMemory(void* info, void* out, u32 addr) { /// Create an event static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { - CASCADE_RESULT(auto evt, Kernel::Event::Create(static_cast(reset_type))); + using Kernel::Event; + + SharedPtr evt = Kernel::Event::Create(static_cast(reset_type)); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", @@ -451,9 +453,10 @@ static ResultCode DuplicateHandle(Handle* out, Handle handle) { /// Signals an event static ResultCode SignalEvent(Handle handle) { + using Kernel::Event; LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); - auto evt = Kernel::g_handle_table.Get(handle); + SharedPtr evt = Kernel::g_handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -464,9 +467,10 @@ static ResultCode SignalEvent(Handle handle) { /// Clears an event static ResultCode ClearEvent(Handle handle) { + using Kernel::Event; LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); - auto evt = Kernel::g_handle_table.Get(handle); + SharedPtr evt = Kernel::g_handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -478,7 +482,7 @@ static ResultCode ClearEvent(Handle handle) { static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { using Kernel::Timer; - CASCADE_RESULT(auto timer, Timer::Create(static_cast(reset_type))); + SharedPtr timer = Timer::Create(static_cast(reset_type)); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", @@ -552,7 +556,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 using Kernel::SharedMemory; // TODO(Subv): Implement this function - CASCADE_RESULT(auto shared_memory, SharedMemory::Create()); + SharedPtr shared_memory = SharedMemory::Create(); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr);