[fixup] Replace boost::intrusive_ptr with std::shared_ptr

This commit is contained in:
Yuri Kunde Schlesner 2015-01-03 17:07:43 -02:00
parent 6480d24a8c
commit b0d9242bc7
14 changed files with 117 additions and 154 deletions

View File

@ -64,9 +64,9 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
} }
/// Create an address arbiter /// Create an address arbiter
AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) { static std::shared_ptr<AddressArbiter> CreateAddressArbiter(Handle& handle, const std::string& name) {
AddressArbiter* address_arbiter = new AddressArbiter; auto address_arbiter = std::make_shared<AddressArbiter>();
// TOOD(yuriks): Fix error reporting // TODO(yuriks): Don't auto-create handle
handle = Kernel::g_handle_table.Create(address_arbiter).ValueOr(INVALID_HANDLE); handle = Kernel::g_handle_table.Create(address_arbiter).ValueOr(INVALID_HANDLE);
address_arbiter->name = name; address_arbiter->name = name;
return address_arbiter; return address_arbiter;

View File

@ -128,10 +128,10 @@ ResultCode ClearEvent(Handle handle) {
* @param name Optional name of event * @param name Optional name of event
* @return Newly created Event object * @return Newly created Event object
*/ */
Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) { static std::shared_ptr<Event> CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) {
Event* evt = new Event; auto evt = std::make_shared<Event>();
// TOOD(yuriks): Fix error reporting // TODO(yuriks): Don't auto-create handle
handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE); handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE);
evt->locked = true; evt->locked = true;
@ -150,7 +150,7 @@ Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string
*/ */
Handle CreateEvent(const ResetType reset_type, const std::string& name) { Handle CreateEvent(const ResetType reset_type, const std::string& name) {
Handle handle; Handle handle;
Event* evt = CreateEvent(handle, reset_type, name); CreateEvent(handle, reset_type, name);
return handle; return handle;
} }

View File

@ -13,7 +13,7 @@
namespace Kernel { namespace Kernel {
smart_ptr<Thread> g_main_thread = nullptr; std::shared_ptr<Thread> g_main_thread = nullptr;
HandleTable g_handle_table; HandleTable g_handle_table;
u64 g_program_id = 0; u64 g_program_id = 0;
@ -22,7 +22,7 @@ HandleTable::HandleTable() {
Clear(); Clear();
} }
ResultVal<Handle> HandleTable::Create(smart_ptr<Object> obj) { ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) {
_dbg_assert_(Kernel, obj != nullptr); _dbg_assert_(Kernel, obj != nullptr);
u16 slot = next_free_slot; u16 slot = next_free_slot;
@ -48,7 +48,7 @@ ResultVal<Handle> HandleTable::Create(smart_ptr<Object> obj) {
} }
ResultVal<Handle> HandleTable::Duplicate(Handle handle) { ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
smart_ptr<Object> object = GetGeneric(handle); std::shared_ptr<Object> object = GetGeneric(handle);
if (object == nullptr) { if (object == nullptr) {
LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle);
return ERR_INVALID_HANDLE; return ERR_INVALID_HANDLE;
@ -77,9 +77,9 @@ bool HandleTable::IsValid(Handle handle) const {
return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
} }
smart_ptr<Object> HandleTable::GetGeneric(Handle handle) const { std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
if (handle == CurrentThread) { if (handle == CurrentThread) {
return GetCurrentThread(); return GetCurrentThread()->shared_from_this();
} else if (handle == CurrentProcess) { } else if (handle == CurrentProcess) {
LOG_ERROR(Kernel, "Current process (%08X) pseudo-handle not supported", CurrentProcess); LOG_ERROR(Kernel, "Current process (%08X) pseudo-handle not supported", CurrentProcess);
return nullptr; return nullptr;

View File

@ -4,10 +4,10 @@
#pragma once #pragma once
#include <boost/intrusive_ptr.hpp>
#include <array> #include <array>
#include <memory>
#include <string> #include <string>
#include "common/common.h" #include "common/common.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@ -51,7 +51,7 @@ enum {
class HandleTable; class HandleTable;
class Object : NonCopyable { class Object : NonCopyable, public std::enable_shared_from_this<Object> {
friend class HandleTable; friend class HandleTable;
u32 handle; u32 handle;
public: public:
@ -69,28 +69,8 @@ public:
LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
return UnimplementedFunction(ErrorModule::Kernel); return UnimplementedFunction(ErrorModule::Kernel);
} }
private:
friend void intrusive_ptr_add_ref(Object*);
friend void intrusive_ptr_release(Object*);
unsigned int ref_count = 0;
}; };
// Special functions used by boost::instrusive_ptr to do automatic ref-counting
inline void intrusive_ptr_add_ref(Object* object) {
++object->ref_count;
}
inline void intrusive_ptr_release(Object* object) {
if (--object->ref_count == 0) {
delete object;
}
}
template <typename T>
using smart_ptr = boost::intrusive_ptr<T>;
/** /**
* This class allows the creation of Handles, which are references to objects that can be tested * This class allows the creation of Handles, which are references to objects that can be tested
* for validity and looked up. Here they are used to pass references to kernel objects to/from the * for validity and looked up. Here they are used to pass references to kernel objects to/from the
@ -123,7 +103,7 @@ public:
* @return The created Handle or one of the following errors: * @return The created Handle or one of the following errors:
* - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded.
*/ */
ResultVal<Handle> Create(smart_ptr<Object> obj); ResultVal<Handle> Create(std::shared_ptr<Object> obj);
/** /**
* Returns a new handle that points to the same object as the passed in handle. * Returns a new handle that points to the same object as the passed in handle.
@ -147,7 +127,7 @@ public:
* Looks up a handle. * Looks up a handle.
* @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid.
*/ */
smart_ptr<Object> GetGeneric(Handle handle) const; std::shared_ptr<Object> GetGeneric(Handle handle) const;
/** /**
* Looks up a handle while verifying its type. * Looks up a handle while verifying its type.
@ -155,10 +135,10 @@ public:
* type differs from the handle type `T::HANDLE_TYPE`. * type differs from the handle type `T::HANDLE_TYPE`.
*/ */
template <class T> template <class T>
smart_ptr<T> Get(Handle handle) const { std::shared_ptr<T> Get(Handle handle) const {
smart_ptr<Object> object = GetGeneric(handle); std::shared_ptr<Object> object = GetGeneric(handle);
if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
return boost::static_pointer_cast<T>(object); return std::static_pointer_cast<T>(object);
} }
return nullptr; return nullptr;
} }
@ -177,7 +157,7 @@ private:
static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; }
/// Stores the Object referenced by the handle or null if the slot is empty. /// Stores the Object referenced by the handle or null if the slot is empty.
std::array<smart_ptr<Object>, MAX_COUNT> objects; std::array<std::shared_ptr<Object>, MAX_COUNT> objects;
/** /**
* The value of `next_generation` when the handle was created, used to check for validity. For * The value of `next_generation` when the handle was created, used to check for validity. For
@ -196,7 +176,7 @@ private:
}; };
extern HandleTable g_handle_table; extern HandleTable g_handle_table;
extern smart_ptr<Thread> g_main_thread; extern std::shared_ptr<Thread> g_main_thread;
/// The ID code of the currently running game /// The ID code of the currently running game
/// TODO(Subv): This variable should not be here, /// TODO(Subv): This variable should not be here,

View File

@ -137,9 +137,10 @@ ResultCode ReleaseMutex(Handle handle) {
* @param name Optional name of mutex * @param name Optional name of mutex
* @return Pointer to new Mutex object * @return Pointer to new Mutex object
*/ */
Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) { static std::shared_ptr<Mutex> CreateMutex(Handle& handle, bool initial_locked, const std::string& name) {
Mutex* mutex = new Mutex; auto mutex = std::make_shared<Mutex>();
// TODO(yuriks): Fix error reporting
// TODO(yuriks): Don't auto-create handle
handle = Kernel::g_handle_table.Create(mutex).ValueOr(INVALID_HANDLE); handle = Kernel::g_handle_table.Create(mutex).ValueOr(INVALID_HANDLE);
mutex->locked = mutex->initial_locked = initial_locked; mutex->locked = mutex->initial_locked = initial_locked;
@ -147,7 +148,7 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name)
// Acquire mutex with current thread if initialized as locked... // Acquire mutex with current thread if initialized as locked...
if (mutex->locked) { if (mutex->locked) {
MutexAcquireLock(mutex); MutexAcquireLock(mutex.get());
// Otherwise, reset lock thread handle // Otherwise, reset lock thread handle
} else { } else {
@ -164,7 +165,7 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name)
*/ */
Handle CreateMutex(bool initial_locked, const std::string& name) { Handle CreateMutex(bool initial_locked, const std::string& name) {
Handle handle; Handle handle;
Mutex* mutex = CreateMutex(handle, initial_locked, name); CreateMutex(handle, initial_locked, name);
return handle; return handle;
} }

View File

@ -56,8 +56,8 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel,
ErrorSummary::WrongArgument, ErrorLevel::Permanent); ErrorSummary::WrongArgument, ErrorLevel::Permanent);
Semaphore* semaphore = new Semaphore; auto semaphore = std::make_shared<Semaphore>();
// TOOD(yuriks): Fix error reporting // TODO(yuriks): Don't auto-create handle
*handle = g_handle_table.Create(semaphore).ValueOr(INVALID_HANDLE); *handle = g_handle_table.Create(semaphore).ValueOr(INVALID_HANDLE);
// When the semaphore is created, some slots are reserved for other threads, // When the semaphore is created, some slots are reserved for other threads,

View File

@ -30,9 +30,9 @@ public:
* @param name Name of shared memory object * @param name Name of shared memory object
* @return Pointer to newly created shared memory object * @return Pointer to newly created shared memory object
*/ */
SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) { static std::shared_ptr<SharedMemory> CreateSharedMemory(Handle& handle, const std::string& name) {
SharedMemory* shared_memory = new SharedMemory; auto shared_memory = std::make_shared<SharedMemory>();
// TOOD(yuriks): Fix error reporting // TODO(yuriks): Don't auto-create handle
handle = Kernel::g_handle_table.Create(shared_memory).ValueOr(INVALID_HANDLE); handle = Kernel::g_handle_table.Create(shared_memory).ValueOr(INVALID_HANDLE);
shared_memory->name = name; shared_memory->name = name;
return shared_memory; return shared_memory;

View File

@ -25,8 +25,10 @@ ResultVal<bool> Thread::WaitSynchronization() {
const bool wait = status != THREADSTATUS_DORMANT; const bool wait = status != THREADSTATUS_DORMANT;
if (wait) { if (wait) {
Thread* thread = GetCurrentThread(); Thread* thread = GetCurrentThread();
if (std::find(waiting_threads.begin(), waiting_threads.end(), thread) == waiting_threads.end()) { auto iter = std::find_if(waiting_threads.begin(), waiting_threads.end(),
waiting_threads.push_back(thread); [&](std::shared_ptr<Thread>& ptr) { return ptr.get() == thread; });
if (iter == waiting_threads.end()) {
waiting_threads.push_back(std::static_pointer_cast<Thread>(thread->shared_from_this()));
} }
WaitCurrentThread(WAITTYPE_THREADEND, this); WaitCurrentThread(WAITTYPE_THREADEND, this);
} }
@ -35,7 +37,7 @@ ResultVal<bool> Thread::WaitSynchronization() {
} }
// Lists all thread ids that aren't deleted/etc. // Lists all thread ids that aren't deleted/etc.
static std::vector<smart_ptr<Thread>> thread_queue; static std::vector<std::shared_ptr<Thread>> thread_queue;
// Lists only ready thread ids. // Lists only ready thread ids.
static Common::ThreadQueueList<Thread*> thread_ready_queue; static Common::ThreadQueueList<Thread*> thread_ready_queue;
@ -259,7 +261,7 @@ static void DebugThreadQueue() {
} }
} }
ResultVal<smart_ptr<Thread>> Thread::Create(const char* name, u32 entry_point, s32 priority, u32 arg, ResultVal<std::shared_ptr<Thread>> Thread::Create(const char* name, u32 entry_point, s32 priority, u32 arg,
s32 processor_id, u32 stack_top, int stack_size) { s32 processor_id, u32 stack_top, int stack_size) {
_dbg_assert_(Kernel, name != nullptr); _dbg_assert_(Kernel, name != nullptr);
@ -286,7 +288,7 @@ ResultVal<smart_ptr<Thread>> Thread::Create(const char* name, u32 entry_point, s
ErrorSummary::InvalidArgument, ErrorLevel::Permanent); ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
} }
Thread* thread = new Thread; std::shared_ptr<Thread> thread = std::make_shared<Thread>(ConstructionToken());
// TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for now. // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for now.
// TODO(yuriks): Don't create handle // TODO(yuriks): Don't create handle
@ -310,10 +312,10 @@ ResultVal<smart_ptr<Thread>> Thread::Create(const char* name, u32 entry_point, s
thread->wait_address = 0; thread->wait_address = 0;
thread->name = name; thread->name = name;
ResetThread(thread, arg, 0); ResetThread(thread.get(), arg, 0);
CallThread(thread); CallThread(thread.get());
return MakeResult<smart_ptr<Thread>>(thread); return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
} }
/// Set the priority of the thread specified by handle /// Set the priority of the thread specified by handle
@ -343,13 +345,13 @@ void Thread::SetPriority(s32 priority) {
} }
/// Sets up the primary application thread /// Sets up the primary application thread
smart_ptr<Thread> SetupMainThread(s32 priority, int stack_size) { std::shared_ptr<Thread> SetupMainThread(s32 priority, int stack_size) {
// Initialize new "main" thread // Initialize new "main" thread
ResultVal<smart_ptr<Thread>> thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0, ResultVal<std::shared_ptr<Thread>> thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0,
THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
// TODO(yuriks): Propagate error // TODO(yuriks): Propagate error
_dbg_assert_(Kernel, thread_res.Succeeded()); _dbg_assert_(Kernel, thread_res.Succeeded());
smart_ptr<Thread> thread = std::move(*thread_res); std::shared_ptr<Thread> thread = std::move(*thread_res);
// If running another thread already, set it to "ready" state // If running another thread already, set it to "ready" state
Thread* cur = GetCurrentThread(); Thread* cur = GetCurrentThread();

View File

@ -53,7 +53,7 @@ namespace Kernel {
class Thread : public Kernel::Object { class Thread : public Kernel::Object {
public: public:
static ResultVal<smart_ptr<Thread>> Create(const char* name, u32 entry_point, s32 priority, u32 arg, static ResultVal<std::shared_ptr<Thread>> Create(const char* name, u32 entry_point, s32 priority, u32 arg,
s32 processor_id, u32 stack_top, int stack_size = Kernel::DEFAULT_STACK_SIZE); s32 processor_id, u32 stack_top, int stack_size = Kernel::DEFAULT_STACK_SIZE);
std::string GetName() const override { return name; } std::string GetName() const override { return name; }
@ -97,16 +97,22 @@ public:
Object* wait_object; Object* wait_object;
VAddr wait_address; VAddr wait_address;
std::vector<smart_ptr<Thread>> waiting_threads; std::vector<std::shared_ptr<Thread>> waiting_threads;
std::string name; std::string name;
private: private:
Thread() = default; /**
* Private type used to prevent the constructor from being called for other classes, while
* still enabling the use of std::make_shared.
*/
struct ConstructionToken {};
public:
Thread(ConstructionToken) {};
}; };
/// Sets up the primary application thread /// Sets up the primary application thread
smart_ptr<Thread> SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZE); std::shared_ptr<Thread> SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZE);
/// Reschedules to the next available thread (call after current thread is suspended) /// Reschedules to the next available thread (call after current thread is suspended)
void Reschedule(); void Reschedule();

View File

@ -305,10 +305,8 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy
ErrorSummary::NotFound, ErrorLevel::Status); ErrorSummary::NotFound, ErrorLevel::Status);
} }
auto file = Common::make_unique<File>(std::move(backend), path); auto file = std::make_shared<File>(std::move(backend), path);
// TOOD(yuriks): Fix error reporting return Kernel::g_handle_table.Create(std::move(file));
Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE);
return MakeResult<Handle>(handle);
} }
ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) {
@ -411,10 +409,8 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F
ErrorSummary::NotFound, ErrorLevel::Permanent); ErrorSummary::NotFound, ErrorLevel::Permanent);
} }
auto directory = Common::make_unique<Directory>(std::move(backend), path); auto directory = std::make_shared<Directory>(std::move(backend), path);
// TOOD(yuriks): Fix error reporting return Kernel::g_handle_table.Create(std::move(directory));
Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE);
return MakeResult<Handle>(handle);
} }
ResultCode FormatSaveData() { ResultCode FormatSaveData() {

View File

@ -45,38 +45,24 @@ Manager* g_manager = nullptr; ///< Service manager
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Service Manager class // Service Manager class
Manager::Manager() { void Manager::AddService(std::shared_ptr<Interface> service) {
}
Manager::~Manager() {
for(Interface* service : m_services) {
DeleteService(service->GetPortName());
}
}
/// Add a service to the manager (does not create it though)
void Manager::AddService(Interface* service) {
// TOOD(yuriks): Fix error reporting // TOOD(yuriks): Fix error reporting
m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service->shared_from_this()).ValueOr(INVALID_HANDLE);
m_services.push_back(service); m_services.push_back(service);
} }
/// Removes a service from the manager, also frees memory
void Manager::DeleteService(const std::string& port_name) { void Manager::DeleteService(const std::string& port_name) {
Interface* service = FetchFromPortName(port_name); std::shared_ptr<Interface> service = FetchFromPortName(port_name);
m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end());
m_port_map.erase(port_name); m_port_map.erase(port_name);
delete service;
} }
/// Get a Service Interface from its Handle std::shared_ptr<Interface> Manager::FetchFromHandle(Handle handle) {
Interface* Manager::FetchFromHandle(Handle handle) {
// TODO(yuriks): This function is very suspicious and should probably be exterminated. // TODO(yuriks): This function is very suspicious and should probably be exterminated.
return Kernel::g_handle_table.Get<Interface>(handle).get(); return Kernel::g_handle_table.Get<Interface>(handle);
} }
/// Get a Service Interface from its port std::shared_ptr<Interface> Manager::FetchFromPortName(const std::string& port_name) {
Interface* Manager::FetchFromPortName(const std::string& port_name) {
auto itr = m_port_map.find(port_name); auto itr = m_port_map.find(port_name);
if (itr == m_port_map.end()) { if (itr == m_port_map.end()) {
return nullptr; return nullptr;
@ -92,37 +78,37 @@ Interface* Manager::FetchFromPortName(const std::string& port_name) {
void Init() { void Init() {
g_manager = new Manager; g_manager = new Manager;
g_manager->AddService(new SRV::Interface); g_manager->AddService(std::make_shared<SRV::Interface>());
g_manager->AddService(new AC_U::Interface); g_manager->AddService(std::make_shared<AC_U::Interface>());
g_manager->AddService(new ACT_U::Interface); g_manager->AddService(std::make_shared<ACT_U::Interface>());
g_manager->AddService(new AM_APP::Interface); g_manager->AddService(std::make_shared<AM_APP::Interface>());
g_manager->AddService(new AM_NET::Interface); g_manager->AddService(std::make_shared<AM_NET::Interface>());
g_manager->AddService(new APT_A::Interface); g_manager->AddService(std::make_shared<APT_A::Interface>());
g_manager->AddService(new APT_U::Interface); g_manager->AddService(std::make_shared<APT_U::Interface>());
g_manager->AddService(new BOSS_U::Interface); g_manager->AddService(std::make_shared<BOSS_U::Interface>());
g_manager->AddService(new CECD_U::Interface); g_manager->AddService(std::make_shared<CECD_U::Interface>());
g_manager->AddService(new CFG_I::Interface); g_manager->AddService(std::make_shared<CFG_I::Interface>());
g_manager->AddService(new CFG_U::Interface); g_manager->AddService(std::make_shared<CFG_U::Interface>());
g_manager->AddService(new CSND_SND::Interface); g_manager->AddService(std::make_shared<CSND_SND::Interface>());
g_manager->AddService(new DSP_DSP::Interface); g_manager->AddService(std::make_shared<DSP_DSP::Interface>());
g_manager->AddService(new ERR_F::Interface); g_manager->AddService(std::make_shared<ERR_F::Interface>());
g_manager->AddService(new FRD_U::Interface); g_manager->AddService(std::make_shared<FRD_U::Interface>());
g_manager->AddService(new FS::FSUserInterface); g_manager->AddService(std::make_shared<FS::FSUserInterface>());
g_manager->AddService(new GSP_GPU::Interface); g_manager->AddService(std::make_shared<GSP_GPU::Interface>());
g_manager->AddService(new HID_User::Interface); g_manager->AddService(std::make_shared<HID_User::Interface>());
g_manager->AddService(new HTTP_C::Interface); g_manager->AddService(std::make_shared<HTTP_C::Interface>());
g_manager->AddService(new IR_RST::Interface); g_manager->AddService(std::make_shared<IR_RST::Interface>());
g_manager->AddService(new IR_U::Interface); g_manager->AddService(std::make_shared<IR_U::Interface>());
g_manager->AddService(new LDR_RO::Interface); g_manager->AddService(std::make_shared<LDR_RO::Interface>());
g_manager->AddService(new MIC_U::Interface); g_manager->AddService(std::make_shared<MIC_U::Interface>());
g_manager->AddService(new NDM_U::Interface); g_manager->AddService(std::make_shared<NDM_U::Interface>());
g_manager->AddService(new NEWS_U::Interface); g_manager->AddService(std::make_shared<NEWS_U::Interface>());
g_manager->AddService(new NIM_AOC::Interface); g_manager->AddService(std::make_shared<NIM_AOC::Interface>());
g_manager->AddService(new NWM_UDS::Interface); g_manager->AddService(std::make_shared<NWM_UDS::Interface>());
g_manager->AddService(new PM_APP::Interface); g_manager->AddService(std::make_shared<PM_APP::Interface>());
g_manager->AddService(new PTM_U::Interface); g_manager->AddService(std::make_shared<PTM_U::Interface>());
g_manager->AddService(new SOC_U::Interface); g_manager->AddService(std::make_shared<SOC_U::Interface>());
g_manager->AddService(new SSL_C::Interface); g_manager->AddService(std::make_shared<SSL_C::Interface>());
LOG_DEBUG(Service, "initialized OK"); LOG_DEBUG(Service, "initialized OK");
} }

View File

@ -55,7 +55,7 @@ public:
/// Allocates a new handle for the service /// Allocates a new handle for the service
Handle CreateHandle(Kernel::Object *obj) { Handle CreateHandle(Kernel::Object *obj) {
// TODO(yuriks): Fix error reporting // TODO(yuriks): Fix error reporting
Handle handle = Kernel::g_handle_table.Create(obj).ValueOr(INVALID_HANDLE); Handle handle = Kernel::g_handle_table.Create(obj->shared_from_this()).ValueOr(INVALID_HANDLE);
m_handles.push_back(handle); m_handles.push_back(handle);
return handle; return handle;
} }
@ -114,29 +114,22 @@ private:
/// Simple class to manage accessing services from ports and UID handles /// Simple class to manage accessing services from ports and UID handles
class Manager { class Manager {
public: public:
Manager(); /// Add a service to the manager
void AddService(std::shared_ptr<Interface> service);
~Manager(); /// Removes a service from the manager
/// Add a service to the manager (does not create it though)
void AddService(Interface* service);
/// Removes a service from the manager (does not delete it though)
void DeleteService(const std::string& port_name); void DeleteService(const std::string& port_name);
/// Get a Service Interface from its UID /// Get a Service Interface from its Handle
Interface* FetchFromHandle(u32 uid); std::shared_ptr<Interface> FetchFromHandle(Handle handle);
/// Get a Service Interface from its port /// Get a Service Interface from its port
Interface* FetchFromPortName(const std::string& port_name); std::shared_ptr<Interface> FetchFromPortName(const std::string& port_name);
private: private:
std::vector<std::shared_ptr<Interface>> m_services;
std::vector<Interface*> m_services;
std::map<std::string, u32> m_port_map; std::map<std::string, u32> m_port_map;
}; };
/// Initialize ServiceManager /// Initialize ServiceManager

View File

@ -39,7 +39,7 @@ static void GetServiceHandle(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); std::shared_ptr<Service::Interface> service = Service::g_manager->FetchFromPortName(port_name);
if (nullptr != service) { if (nullptr != service) {
cmd_buff[3] = service->GetHandle(); cmd_buff[3] = service->GetHandle();

View File

@ -26,8 +26,6 @@
namespace SVC { namespace SVC {
using Kernel::smart_ptr;
enum ControlMemoryOperation { enum ControlMemoryOperation {
MEMORY_OPERATION_HEAP = 0x00000003, MEMORY_OPERATION_HEAP = 0x00000003,
MEMORY_OPERATION_GSP_HEAP = 0x00010003, MEMORY_OPERATION_GSP_HEAP = 0x00010003,
@ -83,7 +81,7 @@ static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other
/// Connect to an OS service given the port name, returns the handle to the port to out /// Connect to an OS service given the port name, returns the handle to the port to out
static Result ConnectToPort(Handle* out, const char* port_name) { static Result ConnectToPort(Handle* out, const char* port_name) {
Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); std::shared_ptr<Service::Interface> service = Service::g_manager->FetchFromPortName(port_name);
LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name);
_assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!");
@ -95,7 +93,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
/// Synchronize to an OS service /// Synchronize to an OS service
static Result SendSyncRequest(Handle handle) { static Result SendSyncRequest(Handle handle) {
smart_ptr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle); std::shared_ptr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
if (session == nullptr) { if (session == nullptr) {
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;
} }
@ -122,7 +120,7 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
// TODO(bunnei): Do something with nano_seconds, currently ignoring this // TODO(bunnei): Do something with nano_seconds, currently ignoring this
bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
smart_ptr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle); std::shared_ptr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle);
if (object == nullptr) if (object == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;
@ -151,7 +149,7 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
// Iterate through each handle, synchronize kernel object // Iterate through each handle, synchronize kernel object
for (s32 i = 0; i < handle_count; i++) { for (s32 i = 0; i < handle_count; i++) {
smart_ptr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]); std::shared_ptr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]);
if (object == nullptr) if (object == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;
@ -233,12 +231,13 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top
name = Common::StringFromFormat("unknown-%08x", entry_point); name = Common::StringFromFormat("unknown-%08x", entry_point);
} }
ResultVal<smart_ptr<Thread>> thread_res = Kernel::Thread::Create(name.c_str(), entry_point, priority, arg, ResultVal<std::shared_ptr<Thread>> thread_res = Kernel::Thread::Create(name.c_str(),
processor_id, stack_top); entry_point, priority, arg, processor_id, stack_top);
if (thread_res.Failed()) if (thread_res.Failed())
return thread_res.Code().raw; return thread_res.Code().raw;
smart_ptr<Thread> thread = std::move(*thread_res); std::shared_ptr<Thread> thread = std::move(*thread_res);
// TODO(yuriks): This handle is being implicitly created in CreateThread, and this will go away
Core::g_app_core->SetReg(1, thread->GetHandle()); Core::g_app_core->SetReg(1, thread->GetHandle());
LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
@ -258,7 +257,7 @@ static void ExitThread() {
/// Gets the priority for the specified thread /// Gets the priority for the specified thread
static Result GetThreadPriority(s32* priority, Handle handle) { static Result GetThreadPriority(s32* priority, Handle handle) {
const smart_ptr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); std::shared_ptr<const Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
if (thread == nullptr) if (thread == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;
@ -268,7 +267,7 @@ static Result GetThreadPriority(s32* priority, Handle handle) {
/// Sets the priority for the specified thread /// Sets the priority for the specified thread
static Result SetThreadPriority(Handle handle, s32 priority) { static Result SetThreadPriority(Handle handle, s32 priority) {
smart_ptr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); std::shared_ptr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
if (thread == nullptr) if (thread == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;
@ -295,7 +294,7 @@ static Result ReleaseMutex(Handle handle) {
static Result GetThreadId(u32* thread_id, Handle handle) { static Result GetThreadId(u32* thread_id, Handle handle) {
LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle); LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle);
const smart_ptr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); std::shared_ptr<const Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
if (thread == nullptr) if (thread == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw; return InvalidHandle(ErrorModule::Kernel).raw;