mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 03:21:04 +00:00
[fixup] Replace boost::intrusive_ptr with std::shared_ptr
This commit is contained in:
parent
6480d24a8c
commit
b0d9242bc7
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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() {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user