mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects. (#3154)
* kernel: Replace usage of boost::intrusive_ptr with std::shared_ptr for kernel objects. - See https://github.com/citra-emu/citra/pull/4710 for details.
This commit is contained in:
parent
b03242067d
commit
9046d4a548
74 changed files with 377 additions and 378 deletions
|
@ -73,7 +73,7 @@ private:
|
||||||
EffectInStatus info{};
|
EffectInStatus info{};
|
||||||
};
|
};
|
||||||
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
|
AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event,
|
std::shared_ptr<Kernel::WritableEvent> buffer_event,
|
||||||
std::size_t instance_number)
|
std::size_t instance_number)
|
||||||
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
|
: worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
|
||||||
effects(params.effect_count) {
|
effects(params.effect_count) {
|
||||||
|
|
|
@ -218,8 +218,7 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
|
||||||
class AudioRenderer {
|
class AudioRenderer {
|
||||||
public:
|
public:
|
||||||
AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
|
AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event,
|
std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
|
||||||
std::size_t instance_number);
|
|
||||||
~AudioRenderer();
|
~AudioRenderer();
|
||||||
|
|
||||||
std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
|
std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
|
||||||
|
@ -235,7 +234,7 @@ private:
|
||||||
class VoiceState;
|
class VoiceState;
|
||||||
|
|
||||||
AudioRendererParameter worker_params;
|
AudioRendererParameter worker_params;
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> buffer_event;
|
std::shared_ptr<Kernel::WritableEvent> buffer_event;
|
||||||
std::vector<VoiceState> voices;
|
std::vector<VoiceState> voices;
|
||||||
std::vector<EffectState> effects;
|
std::vector<EffectState> effects;
|
||||||
std::unique_ptr<AudioOut> audio_out;
|
std::unique_ptr<AudioOut> audio_out;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/file_sys/vfs_types.h"
|
#include "core/file_sys/vfs_types.h"
|
||||||
|
|
|
@ -203,10 +203,10 @@ public:
|
||||||
void PushRaw(const T& value);
|
void PushRaw(const T& value);
|
||||||
|
|
||||||
template <typename... O>
|
template <typename... O>
|
||||||
void PushMoveObjects(Kernel::SharedPtr<O>... pointers);
|
void PushMoveObjects(std::shared_ptr<O>... pointers);
|
||||||
|
|
||||||
template <typename... O>
|
template <typename... O>
|
||||||
void PushCopyObjects(Kernel::SharedPtr<O>... pointers);
|
void PushCopyObjects(std::shared_ptr<O>... pointers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 normal_params_size{};
|
u32 normal_params_size{};
|
||||||
|
@ -298,7 +298,7 @@ void ResponseBuilder::Push(const First& first_value, const Other&... other_value
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... O>
|
template <typename... O>
|
||||||
inline void ResponseBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {
|
inline void ResponseBuilder::PushCopyObjects(std::shared_ptr<O>... pointers) {
|
||||||
auto objects = {pointers...};
|
auto objects = {pointers...};
|
||||||
for (auto& object : objects) {
|
for (auto& object : objects) {
|
||||||
context->AddCopyObject(std::move(object));
|
context->AddCopyObject(std::move(object));
|
||||||
|
@ -306,7 +306,7 @@ inline void ResponseBuilder::PushCopyObjects(Kernel::SharedPtr<O>... pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... O>
|
template <typename... O>
|
||||||
inline void ResponseBuilder::PushMoveObjects(Kernel::SharedPtr<O>... pointers) {
|
inline void ResponseBuilder::PushMoveObjects(std::shared_ptr<O>... pointers) {
|
||||||
auto objects = {pointers...};
|
auto objects = {pointers...};
|
||||||
for (auto& object : objects) {
|
for (auto& object : objects) {
|
||||||
context->AddMoveObject(std::move(object));
|
context->AddMoveObject(std::move(object));
|
||||||
|
@ -357,10 +357,10 @@ public:
|
||||||
T PopRaw();
|
T PopRaw();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Kernel::SharedPtr<T> GetMoveObject(std::size_t index);
|
std::shared_ptr<T> GetMoveObject(std::size_t index);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Kernel::SharedPtr<T> GetCopyObject(std::size_t index);
|
std::shared_ptr<T> GetCopyObject(std::size_t index);
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::shared_ptr<T> PopIpcInterface() {
|
std::shared_ptr<T> PopIpcInterface() {
|
||||||
|
@ -465,12 +465,12 @@ void RequestParser::Pop(First& first_value, Other&... other_values) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Kernel::SharedPtr<T> RequestParser::GetMoveObject(std::size_t index) {
|
std::shared_ptr<T> RequestParser::GetMoveObject(std::size_t index) {
|
||||||
return context->GetMoveObject<T>(index);
|
return context->GetMoveObject<T>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Kernel::SharedPtr<T> RequestParser::GetCopyObject(std::size_t index) {
|
std::shared_ptr<T> RequestParser::GetCopyObject(std::size_t index) {
|
||||||
return context->GetCopyObject<T>(index);
|
return context->GetCopyObject<T>(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
namespace {
|
namespace {
|
||||||
// Wake up num_to_wake (or all) threads in a vector.
|
// Wake up num_to_wake (or all) threads in a vector.
|
||||||
void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_to_wake) {
|
void WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads, s32 num_to_wake) {
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process
|
// Only process up to 'target' threads, unless 'target' is <= 0, in which case process
|
||||||
// them all.
|
// them all.
|
||||||
|
@ -59,7 +59,8 @@ ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 v
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
|
ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
|
||||||
const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
|
const std::vector<std::shared_ptr<Thread>> waiting_threads =
|
||||||
|
GetThreadsWaitingOnAddress(address);
|
||||||
WakeThreads(waiting_threads, num_to_wake);
|
WakeThreads(waiting_threads, num_to_wake);
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +88,8 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get threads waiting on the address.
|
// Get threads waiting on the address.
|
||||||
const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
|
const std::vector<std::shared_ptr<Thread>> waiting_threads =
|
||||||
|
GetThreadsWaitingOnAddress(address);
|
||||||
|
|
||||||
// Determine the modified value depending on the waiting count.
|
// Determine the modified value depending on the waiting count.
|
||||||
s32 updated_value;
|
s32 updated_value;
|
||||||
|
@ -172,21 +174,21 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
|
ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
|
||||||
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
Thread* current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
current_thread->SetArbiterWaitAddress(address);
|
current_thread->SetArbiterWaitAddress(address);
|
||||||
current_thread->SetStatus(ThreadStatus::WaitArb);
|
current_thread->SetStatus(ThreadStatus::WaitArb);
|
||||||
current_thread->InvalidateWakeupCallback();
|
current_thread->InvalidateWakeupCallback();
|
||||||
|
|
||||||
current_thread->WakeAfterDelay(timeout);
|
current_thread->WakeAfterDelay(timeout);
|
||||||
|
|
||||||
system.PrepareReschedule(current_thread->GetProcessorID());
|
system.PrepareReschedule(current_thread->GetProcessorID());
|
||||||
return RESULT_TIMEOUT;
|
return RESULT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const {
|
std::vector<std::shared_ptr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(
|
||||||
|
VAddr address) const {
|
||||||
|
|
||||||
// Retrieve all threads that are waiting for this address.
|
// Retrieve all threads that are waiting for this address.
|
||||||
std::vector<SharedPtr<Thread>> threads;
|
std::vector<std::shared_ptr<Thread>> threads;
|
||||||
const auto& scheduler = system.GlobalScheduler();
|
const auto& scheduler = system.GlobalScheduler();
|
||||||
const auto& thread_list = scheduler.GetThreadList();
|
const auto& thread_list = scheduler.GetThreadList();
|
||||||
|
|
||||||
|
@ -198,7 +200,7 @@ std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr
|
||||||
|
|
||||||
// Sort them by priority, such that the highest priority ones come first.
|
// Sort them by priority, such that the highest priority ones come first.
|
||||||
std::sort(threads.begin(), threads.end(),
|
std::sort(threads.begin(), threads.end(),
|
||||||
[](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) {
|
[](const std::shared_ptr<Thread>& lhs, const std::shared_ptr<Thread>& rhs) {
|
||||||
return lhs->GetPriority() < rhs->GetPriority();
|
return lhs->GetPriority() < rhs->GetPriority();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ private:
|
||||||
ResultCode WaitForAddressImpl(VAddr address, s64 timeout);
|
ResultCode WaitForAddressImpl(VAddr address, s64 timeout);
|
||||||
|
|
||||||
// Gets the threads waiting on an address.
|
// Gets the threads waiting on an address.
|
||||||
std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
|
std::vector<std::shared_ptr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,11 +15,11 @@ namespace Kernel {
|
||||||
ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {}
|
ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {}
|
||||||
ClientPort::~ClientPort() = default;
|
ClientPort::~ClientPort() = default;
|
||||||
|
|
||||||
SharedPtr<ServerPort> ClientPort::GetServerPort() const {
|
std::shared_ptr<ServerPort> ClientPort::GetServerPort() const {
|
||||||
return server_port;
|
return server_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
|
||||||
// Note: Threads do not wait for the server endpoint to call
|
// Note: Threads do not wait for the server endpoint to call
|
||||||
// AcceptSession before returning from this call.
|
// AcceptSession before returning from this call.
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
||||||
active_sessions++;
|
active_sessions++;
|
||||||
|
|
||||||
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
|
// Create a new session pair, let the created sessions inherit the parent port's HLE handler.
|
||||||
auto [server, client] = ServerSession::CreateSessionPair(kernel, server_port->GetName(), this);
|
auto [server, client] =
|
||||||
|
ServerSession::CreateSessionPair(kernel, server_port->GetName(), SharedFrom(this));
|
||||||
|
|
||||||
if (server_port->HasHLEHandler()) {
|
if (server_port->HasHLEHandler()) {
|
||||||
server_port->GetHLEHandler()->ClientConnected(server);
|
server_port->GetHLEHandler()->ClientConnected(server);
|
||||||
|
|
|
@ -17,6 +17,9 @@ class ServerPort;
|
||||||
|
|
||||||
class ClientPort final : public Object {
|
class ClientPort final : public Object {
|
||||||
public:
|
public:
|
||||||
|
explicit ClientPort(KernelCore& kernel);
|
||||||
|
~ClientPort() override;
|
||||||
|
|
||||||
friend class ServerPort;
|
friend class ServerPort;
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ClientPort";
|
return "ClientPort";
|
||||||
|
@ -30,7 +33,7 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ServerPort> GetServerPort() const;
|
std::shared_ptr<ServerPort> GetServerPort() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Session pair, adds the created ServerSession to the associated ServerPort's
|
* Creates a new Session pair, adds the created ServerSession to the associated ServerPort's
|
||||||
|
@ -38,7 +41,7 @@ public:
|
||||||
* waiting on it to awake.
|
* waiting on it to awake.
|
||||||
* @returns ClientSession The client endpoint of the created Session pair, or error code.
|
* @returns ClientSession The client endpoint of the created Session pair, or error code.
|
||||||
*/
|
*/
|
||||||
ResultVal<SharedPtr<ClientSession>> Connect();
|
ResultVal<std::shared_ptr<ClientSession>> Connect();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signifies that a previously active connection has been closed,
|
* Signifies that a previously active connection has been closed,
|
||||||
|
@ -47,10 +50,7 @@ public:
|
||||||
void ConnectionClosed();
|
void ConnectionClosed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientPort(KernelCore& kernel);
|
std::shared_ptr<ServerPort> server_port; ///< ServerPort associated with this client port.
|
||||||
~ClientPort() override;
|
|
||||||
|
|
||||||
SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
|
|
||||||
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
|
u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have
|
||||||
u32 active_sessions = 0; ///< Number of currently open sessions to this port
|
u32 active_sessions = 0; ///< Number of currently open sessions to this port
|
||||||
std::string name; ///< Name of client port (optional)
|
std::string name; ///< Name of client port (optional)
|
||||||
|
|
|
@ -16,25 +16,20 @@ ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {}
|
||||||
ClientSession::~ClientSession() {
|
ClientSession::~ClientSession() {
|
||||||
// This destructor will be called automatically when the last ClientSession handle is closed by
|
// This destructor will be called automatically when the last ClientSession handle is closed by
|
||||||
// the emulated application.
|
// the emulated application.
|
||||||
|
if (parent->server) {
|
||||||
// A local reference to the ServerSession is necessary to guarantee it
|
parent->server->ClientDisconnected();
|
||||||
// will be kept alive until after ClientDisconnected() returns.
|
|
||||||
SharedPtr<ServerSession> server = parent->server;
|
|
||||||
if (server) {
|
|
||||||
server->ClientDisconnected();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->client = nullptr;
|
parent->client = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) {
|
ResultCode ClientSession::SendSyncRequest(Thread* thread) {
|
||||||
// Keep ServerSession alive until we're done working with it.
|
// Keep ServerSession alive until we're done working with it.
|
||||||
SharedPtr<ServerSession> server = parent->server;
|
if (parent->server == nullptr)
|
||||||
if (server == nullptr)
|
|
||||||
return ERR_SESSION_CLOSED_BY_REMOTE;
|
return ERR_SESSION_CLOSED_BY_REMOTE;
|
||||||
|
|
||||||
// Signal the server session that new data is available
|
// Signal the server session that new data is available
|
||||||
return server->HandleSyncRequest(std::move(thread));
|
return parent->server->HandleSyncRequest(SharedFrom(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -19,6 +19,9 @@ class Thread;
|
||||||
|
|
||||||
class ClientSession final : public Object {
|
class ClientSession final : public Object {
|
||||||
public:
|
public:
|
||||||
|
explicit ClientSession(KernelCore& kernel);
|
||||||
|
~ClientSession() override;
|
||||||
|
|
||||||
friend class ServerSession;
|
friend class ServerSession;
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
|
@ -34,12 +37,9 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode SendSyncRequest(SharedPtr<Thread> thread);
|
ResultCode SendSyncRequest(Thread* thread);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ClientSession(KernelCore& kernel);
|
|
||||||
~ClientSession() override;
|
|
||||||
|
|
||||||
/// The parent session, which links to the server endpoint.
|
/// The parent session, which links to the server endpoint.
|
||||||
std::shared_ptr<Session> parent;
|
std::shared_ptr<Session> parent;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
ResultVal<Handle> HandleTable::Create(std::shared_ptr<Object> obj) {
|
||||||
DEBUG_ASSERT(obj != nullptr);
|
DEBUG_ASSERT(obj != nullptr);
|
||||||
|
|
||||||
const u16 slot = next_free_slot;
|
const u16 slot = next_free_slot;
|
||||||
|
@ -70,7 +70,7 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
|
||||||
SharedPtr<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;
|
||||||
|
@ -99,11 +99,11 @@ bool HandleTable::IsValid(Handle handle) const {
|
||||||
return slot < table_size && objects[slot] != nullptr && generations[slot] == generation;
|
return slot < table_size && objects[slot] != nullptr && generations[slot] == generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
|
std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
|
||||||
if (handle == CurrentThread) {
|
if (handle == CurrentThread) {
|
||||||
return GetCurrentThread();
|
return SharedFrom(GetCurrentThread());
|
||||||
} else if (handle == CurrentProcess) {
|
} else if (handle == CurrentProcess) {
|
||||||
return Core::System::GetInstance().CurrentProcess();
|
return SharedFrom(Core::System::GetInstance().CurrentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid(handle)) {
|
if (!IsValid(handle)) {
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
* @return The created Handle or one of the following errors:
|
* @return The created Handle or one of the following errors:
|
||||||
* - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded.
|
* - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded.
|
||||||
*/
|
*/
|
||||||
ResultVal<Handle> Create(SharedPtr<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.
|
||||||
|
@ -92,7 +92,7 @@ public:
|
||||||
* Looks up a handle.
|
* Looks up a handle.
|
||||||
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
|
* @return Pointer to the looked-up object, or `nullptr` if the handle is not valid.
|
||||||
*/
|
*/
|
||||||
SharedPtr<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.
|
||||||
|
@ -100,7 +100,7 @@ public:
|
||||||
* type differs from the requested one.
|
* type differs from the requested one.
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
SharedPtr<T> Get(Handle handle) const {
|
std::shared_ptr<T> Get(Handle handle) const {
|
||||||
return DynamicObjectCast<T>(GetGeneric(handle));
|
return DynamicObjectCast<T>(GetGeneric(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// 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<SharedPtr<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
|
||||||
|
|
|
@ -32,23 +32,25 @@ SessionRequestHandler::SessionRequestHandler() = default;
|
||||||
|
|
||||||
SessionRequestHandler::~SessionRequestHandler() = default;
|
SessionRequestHandler::~SessionRequestHandler() = default;
|
||||||
|
|
||||||
void SessionRequestHandler::ClientConnected(SharedPtr<ServerSession> server_session) {
|
void SessionRequestHandler::ClientConnected(std::shared_ptr<ServerSession> server_session) {
|
||||||
server_session->SetHleHandler(shared_from_this());
|
server_session->SetHleHandler(shared_from_this());
|
||||||
connected_sessions.push_back(std::move(server_session));
|
connected_sessions.push_back(std::move(server_session));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& server_session) {
|
void SessionRequestHandler::ClientDisconnected(
|
||||||
|
const std::shared_ptr<ServerSession>& server_session) {
|
||||||
server_session->SetHleHandler(nullptr);
|
server_session->SetHleHandler(nullptr);
|
||||||
boost::range::remove_erase(connected_sessions, server_session);
|
boost::range::remove_erase(connected_sessions, server_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
|
std::shared_ptr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||||
const std::string& reason, u64 timeout, WakeupCallback&& callback,
|
const std::string& reason, u64 timeout, WakeupCallback&& callback,
|
||||||
SharedPtr<WritableEvent> writable_event) {
|
std::shared_ptr<WritableEvent> writable_event) {
|
||||||
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
|
// Put the client thread to sleep until the wait event is signaled or the timeout expires.
|
||||||
thread->SetWakeupCallback([context = *this, callback](
|
thread->SetWakeupCallback([context = *this, callback](ThreadWakeupReason reason,
|
||||||
ThreadWakeupReason reason, SharedPtr<Thread> thread,
|
std::shared_ptr<Thread> thread,
|
||||||
SharedPtr<WaitObject> object, std::size_t index) mutable -> bool {
|
std::shared_ptr<WaitObject> object,
|
||||||
|
std::size_t index) mutable -> bool {
|
||||||
ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent);
|
ASSERT(thread->GetStatus() == ThreadStatus::WaitHLEEvent);
|
||||||
callback(thread, context, reason);
|
callback(thread, context, reason);
|
||||||
context.WriteToOutgoingCommandBuffer(*thread);
|
context.WriteToOutgoingCommandBuffer(*thread);
|
||||||
|
@ -75,8 +77,8 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
|
||||||
return writable_event;
|
return writable_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session,
|
HLERequestContext::HLERequestContext(std::shared_ptr<Kernel::ServerSession> server_session,
|
||||||
SharedPtr<Thread> thread)
|
std::shared_ptr<Thread> thread)
|
||||||
: server_session(std::move(server_session)), thread(std::move(thread)) {
|
: server_session(std::move(server_session)), thread(std::move(thread)) {
|
||||||
cmd_buf[0] = 0;
|
cmd_buf[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -60,20 +61,20 @@ public:
|
||||||
* associated ServerSession alive for the duration of the connection.
|
* associated ServerSession alive for the duration of the connection.
|
||||||
* @param server_session Owning pointer to the ServerSession associated with the connection.
|
* @param server_session Owning pointer to the ServerSession associated with the connection.
|
||||||
*/
|
*/
|
||||||
void ClientConnected(SharedPtr<ServerSession> server_session);
|
void ClientConnected(std::shared_ptr<ServerSession> server_session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that a client has just disconnected from this HLE handler and releases the
|
* Signals that a client has just disconnected from this HLE handler and releases the
|
||||||
* associated ServerSession.
|
* associated ServerSession.
|
||||||
* @param server_session ServerSession associated with the connection.
|
* @param server_session ServerSession associated with the connection.
|
||||||
*/
|
*/
|
||||||
void ClientDisconnected(const SharedPtr<ServerSession>& server_session);
|
void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// List of sessions that are connected to this handler.
|
/// List of sessions that are connected to this handler.
|
||||||
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
|
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
|
||||||
/// for the duration of the connection.
|
/// for the duration of the connection.
|
||||||
std::vector<SharedPtr<ServerSession>> connected_sessions;
|
std::vector<std::shared_ptr<ServerSession>> connected_sessions;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +98,8 @@ protected:
|
||||||
*/
|
*/
|
||||||
class HLERequestContext {
|
class HLERequestContext {
|
||||||
public:
|
public:
|
||||||
explicit HLERequestContext(SharedPtr<ServerSession> session, SharedPtr<Thread> thread);
|
explicit HLERequestContext(std::shared_ptr<ServerSession> session,
|
||||||
|
std::shared_ptr<Thread> thread);
|
||||||
~HLERequestContext();
|
~HLERequestContext();
|
||||||
|
|
||||||
/// Returns a pointer to the IPC command buffer for this request.
|
/// Returns a pointer to the IPC command buffer for this request.
|
||||||
|
@ -109,12 +111,12 @@ public:
|
||||||
* Returns the session through which this request was made. This can be used as a map key to
|
* Returns the session through which this request was made. This can be used as a map key to
|
||||||
* access per-client data on services.
|
* access per-client data on services.
|
||||||
*/
|
*/
|
||||||
const SharedPtr<Kernel::ServerSession>& Session() const {
|
const std::shared_ptr<Kernel::ServerSession>& Session() const {
|
||||||
return server_session;
|
return server_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
using WakeupCallback = std::function<void(SharedPtr<Thread> thread, HLERequestContext& context,
|
using WakeupCallback = std::function<void(
|
||||||
ThreadWakeupReason reason)>;
|
std::shared_ptr<Thread> thread, HLERequestContext& context, ThreadWakeupReason reason)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts the specified guest thread to sleep until the returned event is signaled or until the
|
* Puts the specified guest thread to sleep until the returned event is signaled or until the
|
||||||
|
@ -129,9 +131,9 @@ public:
|
||||||
* created.
|
* created.
|
||||||
* @returns Event that when signaled will resume the thread and call the callback function.
|
* @returns Event that when signaled will resume the thread and call the callback function.
|
||||||
*/
|
*/
|
||||||
SharedPtr<WritableEvent> SleepClientThread(const std::string& reason, u64 timeout,
|
std::shared_ptr<WritableEvent> SleepClientThread(
|
||||||
WakeupCallback&& callback,
|
const std::string& reason, u64 timeout, WakeupCallback&& callback,
|
||||||
SharedPtr<WritableEvent> writable_event = nullptr);
|
std::shared_ptr<WritableEvent> writable_event = nullptr);
|
||||||
|
|
||||||
/// Populates this context with data from the requesting process/thread.
|
/// Populates this context with data from the requesting process/thread.
|
||||||
ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
|
ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
|
||||||
|
@ -209,20 +211,20 @@ public:
|
||||||
std::size_t GetWriteBufferSize(int buffer_index = 0) const;
|
std::size_t GetWriteBufferSize(int buffer_index = 0) const;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SharedPtr<T> GetCopyObject(std::size_t index) {
|
std::shared_ptr<T> GetCopyObject(std::size_t index) {
|
||||||
return DynamicObjectCast<T>(copy_objects.at(index));
|
return DynamicObjectCast<T>(copy_objects.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SharedPtr<T> GetMoveObject(std::size_t index) {
|
std::shared_ptr<T> GetMoveObject(std::size_t index) {
|
||||||
return DynamicObjectCast<T>(move_objects.at(index));
|
return DynamicObjectCast<T>(move_objects.at(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMoveObject(SharedPtr<Object> object) {
|
void AddMoveObject(std::shared_ptr<Object> object) {
|
||||||
move_objects.emplace_back(std::move(object));
|
move_objects.emplace_back(std::move(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddCopyObject(SharedPtr<Object> object) {
|
void AddCopyObject(std::shared_ptr<Object> object) {
|
||||||
copy_objects.emplace_back(std::move(object));
|
copy_objects.emplace_back(std::move(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,11 +268,11 @@ private:
|
||||||
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
|
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
|
||||||
|
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
SharedPtr<Kernel::ServerSession> server_session;
|
std::shared_ptr<Kernel::ServerSession> server_session;
|
||||||
SharedPtr<Thread> thread;
|
std::shared_ptr<Thread> thread;
|
||||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
||||||
boost::container::small_vector<SharedPtr<Object>, 8> move_objects;
|
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
|
||||||
boost::container::small_vector<SharedPtr<Object>, 8> copy_objects;
|
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
|
||||||
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
|
||||||
|
|
||||||
std::optional<IPC::CommandHeader> command_header;
|
std::optional<IPC::CommandHeader> command_header;
|
||||||
|
|
|
@ -40,7 +40,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
|
||||||
// Lock the global kernel mutex when we enter the kernel HLE.
|
// Lock the global kernel mutex when we enter the kernel HLE.
|
||||||
std::lock_guard lock{HLE::g_hle_lock};
|
std::lock_guard lock{HLE::g_hle_lock};
|
||||||
|
|
||||||
SharedPtr<Thread> thread =
|
std::shared_ptr<Thread> thread =
|
||||||
system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle);
|
system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle);
|
||||||
if (thread == nullptr) {
|
if (thread == nullptr) {
|
||||||
LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
|
LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
|
||||||
|
@ -53,7 +53,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
|
||||||
thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
|
thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
|
||||||
// Remove the thread from each of its waiting objects' waitlists
|
// Remove the thread from each of its waiting objects' waitlists
|
||||||
for (const auto& object : thread->GetWaitObjects()) {
|
for (const auto& object : thread->GetWaitObjects()) {
|
||||||
object->RemoveWaitingThread(thread.get());
|
object->RemoveWaitingThread(thread);
|
||||||
}
|
}
|
||||||
thread->ClearWaitObjects();
|
thread->ClearWaitObjects();
|
||||||
|
|
||||||
|
@ -160,11 +160,11 @@ struct KernelCore::Impl {
|
||||||
std::atomic<u64> next_thread_id{1};
|
std::atomic<u64> next_thread_id{1};
|
||||||
|
|
||||||
// Lists all processes that exist in the current session.
|
// Lists all processes that exist in the current session.
|
||||||
std::vector<SharedPtr<Process>> process_list;
|
std::vector<std::shared_ptr<Process>> process_list;
|
||||||
Process* current_process = nullptr;
|
Process* current_process = nullptr;
|
||||||
Kernel::GlobalScheduler global_scheduler;
|
Kernel::GlobalScheduler global_scheduler;
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> system_resource_limit;
|
std::shared_ptr<ResourceLimit> system_resource_limit;
|
||||||
|
|
||||||
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
|
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
|
||||||
Core::Timing::EventType* preemption_event = nullptr;
|
Core::Timing::EventType* preemption_event = nullptr;
|
||||||
|
@ -193,15 +193,16 @@ void KernelCore::Shutdown() {
|
||||||
impl->Shutdown();
|
impl->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
|
std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const {
|
||||||
return impl->system_resource_limit;
|
return impl->system_resource_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const {
|
std::shared_ptr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(
|
||||||
|
Handle handle) const {
|
||||||
return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
|
return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
|
void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) {
|
||||||
impl->process_list.push_back(std::move(process));
|
impl->process_list.push_back(std::move(process));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +224,7 @@ const Process* KernelCore::CurrentProcess() const {
|
||||||
return impl->current_process;
|
return impl->current_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SharedPtr<Process>>& KernelCore::GetProcessList() const {
|
const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const {
|
||||||
return impl->process_list;
|
return impl->process_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
|
||||||
return impl->global_scheduler;
|
return impl->global_scheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
|
void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
|
||||||
impl->named_ports.emplace(std::move(name), std::move(port));
|
impl->named_ports.emplace(std::move(name), std::move(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -30,7 +31,7 @@ class Thread;
|
||||||
/// Represents a single instance of the kernel.
|
/// Represents a single instance of the kernel.
|
||||||
class KernelCore {
|
class KernelCore {
|
||||||
private:
|
private:
|
||||||
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
|
using NamedPortTable = std::unordered_map<std::string, std::shared_ptr<ClientPort>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructs an instance of the kernel using the given System
|
/// Constructs an instance of the kernel using the given System
|
||||||
|
@ -56,13 +57,13 @@ public:
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
/// Retrieves a shared pointer to the system resource limit instance.
|
/// Retrieves a shared pointer to the system resource limit instance.
|
||||||
SharedPtr<ResourceLimit> GetSystemResourceLimit() const;
|
std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const;
|
||||||
|
|
||||||
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
|
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
|
||||||
SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
|
std::shared_ptr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
|
||||||
|
|
||||||
/// Adds the given shared pointer to an internal list of active processes.
|
/// Adds the given shared pointer to an internal list of active processes.
|
||||||
void AppendNewProcess(SharedPtr<Process> process);
|
void AppendNewProcess(std::shared_ptr<Process> process);
|
||||||
|
|
||||||
/// Makes the given process the new current process.
|
/// Makes the given process the new current process.
|
||||||
void MakeCurrentProcess(Process* process);
|
void MakeCurrentProcess(Process* process);
|
||||||
|
@ -74,7 +75,7 @@ public:
|
||||||
const Process* CurrentProcess() const;
|
const Process* CurrentProcess() const;
|
||||||
|
|
||||||
/// Retrieves the list of processes.
|
/// Retrieves the list of processes.
|
||||||
const std::vector<SharedPtr<Process>>& GetProcessList() const;
|
const std::vector<std::shared_ptr<Process>>& GetProcessList() const;
|
||||||
|
|
||||||
/// Gets the sole instance of the global scheduler
|
/// Gets the sole instance of the global scheduler
|
||||||
Kernel::GlobalScheduler& GlobalScheduler();
|
Kernel::GlobalScheduler& GlobalScheduler();
|
||||||
|
@ -83,7 +84,7 @@ public:
|
||||||
const Kernel::GlobalScheduler& GlobalScheduler() const;
|
const Kernel::GlobalScheduler& GlobalScheduler() const;
|
||||||
|
|
||||||
/// Adds a port to the named port table
|
/// Adds a port to the named port table
|
||||||
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
|
void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
|
||||||
|
|
||||||
/// Finds a port within the named port table with the given name.
|
/// Finds a port within the named port table with the given name.
|
||||||
NamedPortTable::iterator FindNamedPort(const std::string& name);
|
NamedPortTable::iterator FindNamedPort(const std::string& name);
|
||||||
|
|
|
@ -22,10 +22,10 @@ namespace Kernel {
|
||||||
|
|
||||||
/// Returns the number of threads that are waiting for a mutex, and the highest priority one among
|
/// Returns the number of threads that are waiting for a mutex, and the highest priority one among
|
||||||
/// those.
|
/// those.
|
||||||
static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
|
static std::pair<std::shared_ptr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
|
||||||
const SharedPtr<Thread>& current_thread, VAddr mutex_addr) {
|
const std::shared_ptr<Thread>& current_thread, VAddr mutex_addr) {
|
||||||
|
|
||||||
SharedPtr<Thread> highest_priority_thread;
|
std::shared_ptr<Thread> highest_priority_thread;
|
||||||
u32 num_waiters = 0;
|
u32 num_waiters = 0;
|
||||||
|
|
||||||
for (const auto& thread : current_thread->GetMutexWaitingThreads()) {
|
for (const auto& thread : current_thread->GetMutexWaitingThreads()) {
|
||||||
|
@ -45,14 +45,14 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the mutex owner field of all threads waiting on the mutex to point to the new owner.
|
/// Update the mutex owner field of all threads waiting on the mutex to point to the new owner.
|
||||||
static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_thread,
|
static void TransferMutexOwnership(VAddr mutex_addr, std::shared_ptr<Thread> current_thread,
|
||||||
SharedPtr<Thread> new_owner) {
|
std::shared_ptr<Thread> new_owner) {
|
||||||
const auto threads = current_thread->GetMutexWaitingThreads();
|
const auto threads = current_thread->GetMutexWaitingThreads();
|
||||||
for (const auto& thread : threads) {
|
for (const auto& thread : threads) {
|
||||||
if (thread->GetMutexWaitAddress() != mutex_addr)
|
if (thread->GetMutexWaitAddress() != mutex_addr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ASSERT(thread->GetLockOwner() == current_thread);
|
ASSERT(thread->GetLockOwner() == current_thread.get());
|
||||||
current_thread->RemoveMutexWaiter(thread);
|
current_thread->RemoveMutexWaiter(thread);
|
||||||
if (new_owner != thread)
|
if (new_owner != thread)
|
||||||
new_owner->AddMutexWaiter(thread);
|
new_owner->AddMutexWaiter(thread);
|
||||||
|
@ -70,9 +70,10 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
Thread* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
std::shared_ptr<Thread> current_thread =
|
||||||
SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
|
SharedFrom(system.CurrentScheduler().GetCurrentThread());
|
||||||
SharedPtr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle);
|
std::shared_ptr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
|
||||||
|
std::shared_ptr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle);
|
||||||
|
|
||||||
// TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another
|
// TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another
|
||||||
// thread.
|
// thread.
|
||||||
|
@ -110,7 +111,8 @@ ResultCode Mutex::Release(VAddr address) {
|
||||||
return ERR_INVALID_ADDRESS;
|
return ERR_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
std::shared_ptr<Thread> current_thread =
|
||||||
|
SharedFrom(system.CurrentScheduler().GetCurrentThread());
|
||||||
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address);
|
auto [thread, num_waiters] = GetHighestPriorityMutexWaitingThread(current_thread, address);
|
||||||
|
|
||||||
// There are no more threads waiting for the mutex, release it completely.
|
// There are no more threads waiting for the mutex, release it completely.
|
||||||
|
|
|
@ -5,10 +5,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/smart_ptr/intrusive_ptr.hpp>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -32,7 +31,7 @@ enum class HandleType : u32 {
|
||||||
ServerSession,
|
ServerSession,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Object : NonCopyable {
|
class Object : NonCopyable, public std::enable_shared_from_this<Object> {
|
||||||
public:
|
public:
|
||||||
explicit Object(KernelCore& kernel);
|
explicit Object(KernelCore& kernel);
|
||||||
virtual ~Object();
|
virtual ~Object();
|
||||||
|
@ -61,35 +60,24 @@ protected:
|
||||||
KernelCore& kernel;
|
KernelCore& kernel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend void intrusive_ptr_add_ref(Object*);
|
|
||||||
friend void intrusive_ptr_release(Object*);
|
|
||||||
|
|
||||||
std::atomic<u32> ref_count{0};
|
|
||||||
std::atomic<u32> object_id{0};
|
std::atomic<u32> object_id{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special functions used by boost::instrusive_ptr to do automatic ref-counting
|
|
||||||
inline void intrusive_ptr_add_ref(Object* object) {
|
|
||||||
object->ref_count.fetch_add(1, std::memory_order_relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void intrusive_ptr_release(Object* object) {
|
|
||||||
if (object->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
|
|
||||||
delete object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using SharedPtr = boost::intrusive_ptr<T>;
|
std::shared_ptr<T> SharedFrom(T* raw) {
|
||||||
|
if (raw == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
return std::static_pointer_cast<T>(raw->shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to downcast the given Object pointer to a pointer to T.
|
* Attempts to downcast the given Object pointer to a pointer to T.
|
||||||
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
* @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) {
|
inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, u32 priority) {
|
||||||
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0,
|
auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0,
|
||||||
owner_process.GetIdealCore(), stack_top, owner_process);
|
owner_process.GetIdealCore(), stack_top, owner_process);
|
||||||
|
|
||||||
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
|
std::shared_ptr<Thread> thread = std::move(thread_res).Unwrap();
|
||||||
|
|
||||||
// Register 1 must be a handle to the main thread
|
// Register 1 must be a handle to the main thread
|
||||||
const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
|
const Handle thread_handle = owner_process.GetHandleTable().Create(thread).Unwrap();
|
||||||
|
@ -100,10 +100,10 @@ private:
|
||||||
std::bitset<num_slot_entries> is_slot_used;
|
std::bitset<num_slot_entries> is_slot_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
SharedPtr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) {
|
std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, ProcessType type) {
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
SharedPtr<Process> process(new Process(system));
|
std::shared_ptr<Process> process = std::make_shared<Process>(system);
|
||||||
process->name = std::move(name);
|
process->name = std::move(name);
|
||||||
process->resource_limit = kernel.GetSystemResourceLimit();
|
process->resource_limit = kernel.GetSystemResourceLimit();
|
||||||
process->status = ProcessStatus::Created;
|
process->status = ProcessStatus::Created;
|
||||||
|
@ -121,7 +121,7 @@ SharedPtr<Process> Process::Create(Core::System& system, std::string name, Proce
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> Process::GetResourceLimit() const {
|
std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const {
|
||||||
return resource_limit;
|
return resource_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,12 +142,12 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
|
||||||
return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
|
return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) {
|
void Process::InsertConditionVariableThread(std::shared_ptr<Thread> thread) {
|
||||||
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
|
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
|
||||||
std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
||||||
auto it = thread_list.begin();
|
auto it = thread_list.begin();
|
||||||
while (it != thread_list.end()) {
|
while (it != thread_list.end()) {
|
||||||
const SharedPtr<Thread> current_thread = *it;
|
const std::shared_ptr<Thread> current_thread = *it;
|
||||||
if (current_thread->GetPriority() > thread->GetPriority()) {
|
if (current_thread->GetPriority() > thread->GetPriority()) {
|
||||||
thread_list.insert(it, thread);
|
thread_list.insert(it, thread);
|
||||||
return;
|
return;
|
||||||
|
@ -157,12 +157,12 @@ void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) {
|
||||||
thread_list.push_back(thread);
|
thread_list.push_back(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
|
void Process::RemoveConditionVariableThread(std::shared_ptr<Thread> thread) {
|
||||||
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
|
VAddr cond_var_addr = thread->GetCondVarWaitAddress();
|
||||||
std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
||||||
auto it = thread_list.begin();
|
auto it = thread_list.begin();
|
||||||
while (it != thread_list.end()) {
|
while (it != thread_list.end()) {
|
||||||
const SharedPtr<Thread> current_thread = *it;
|
const std::shared_ptr<Thread> current_thread = *it;
|
||||||
if (current_thread.get() == thread.get()) {
|
if (current_thread.get() == thread.get()) {
|
||||||
thread_list.erase(it);
|
thread_list.erase(it);
|
||||||
return;
|
return;
|
||||||
|
@ -172,12 +172,13 @@ void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) {
|
std::vector<std::shared_ptr<Thread>> Process::GetConditionVariableThreads(
|
||||||
std::vector<SharedPtr<Thread>> result{};
|
const VAddr cond_var_addr) {
|
||||||
std::list<SharedPtr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
std::vector<std::shared_ptr<Thread>> result{};
|
||||||
|
std::list<std::shared_ptr<Thread>>& thread_list = cond_var_threads[cond_var_addr];
|
||||||
auto it = thread_list.begin();
|
auto it = thread_list.begin();
|
||||||
while (it != thread_list.end()) {
|
while (it != thread_list.end()) {
|
||||||
SharedPtr<Thread> current_thread = *it;
|
std::shared_ptr<Thread> current_thread = *it;
|
||||||
result.push_back(current_thread);
|
result.push_back(current_thread);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -239,12 +240,12 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) {
|
||||||
void Process::PrepareForTermination() {
|
void Process::PrepareForTermination() {
|
||||||
ChangeStatus(ProcessStatus::Exiting);
|
ChangeStatus(ProcessStatus::Exiting);
|
||||||
|
|
||||||
const auto stop_threads = [this](const std::vector<SharedPtr<Thread>>& thread_list) {
|
const auto stop_threads = [this](const std::vector<std::shared_ptr<Thread>>& thread_list) {
|
||||||
for (auto& thread : thread_list) {
|
for (auto& thread : thread_list) {
|
||||||
if (thread->GetOwnerProcess() != this)
|
if (thread->GetOwnerProcess() != this)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (thread == system.CurrentScheduler().GetCurrentThread())
|
if (thread.get() == system.CurrentScheduler().GetCurrentThread())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// TODO(Subv): When are the other running/ready threads terminated?
|
// TODO(Subv): When are the other running/ready threads terminated?
|
||||||
|
|
|
@ -62,6 +62,9 @@ enum class ProcessStatus {
|
||||||
|
|
||||||
class Process final : public WaitObject {
|
class Process final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
|
explicit Process(Core::System& system);
|
||||||
|
~Process() override;
|
||||||
|
|
||||||
enum : u64 {
|
enum : u64 {
|
||||||
/// Lowest allowed process ID for a kernel initial process.
|
/// Lowest allowed process ID for a kernel initial process.
|
||||||
InitialKIPIDMin = 1,
|
InitialKIPIDMin = 1,
|
||||||
|
@ -82,7 +85,8 @@ public:
|
||||||
|
|
||||||
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
||||||
|
|
||||||
static SharedPtr<Process> Create(Core::System& system, std::string name, ProcessType type);
|
static std::shared_ptr<Process> Create(Core::System& system, std::string name,
|
||||||
|
ProcessType type);
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Process";
|
return "Process";
|
||||||
|
@ -157,7 +161,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the resource limit descriptor for this process
|
/// Gets the resource limit descriptor for this process
|
||||||
SharedPtr<ResourceLimit> GetResourceLimit() const;
|
std::shared_ptr<ResourceLimit> GetResourceLimit() const;
|
||||||
|
|
||||||
/// Gets the ideal CPU core ID for this process
|
/// Gets the ideal CPU core ID for this process
|
||||||
u8 GetIdealCore() const {
|
u8 GetIdealCore() const {
|
||||||
|
@ -234,13 +238,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a thread into the condition variable wait container
|
/// Insert a thread into the condition variable wait container
|
||||||
void InsertConditionVariableThread(SharedPtr<Thread> thread);
|
void InsertConditionVariableThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Remove a thread from the condition variable wait container
|
/// Remove a thread from the condition variable wait container
|
||||||
void RemoveConditionVariableThread(SharedPtr<Thread> thread);
|
void RemoveConditionVariableThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Obtain all condition variable threads waiting for some address
|
/// Obtain all condition variable threads waiting for some address
|
||||||
std::vector<SharedPtr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr);
|
std::vector<std::shared_ptr<Thread>> GetConditionVariableThreads(VAddr cond_var_addr);
|
||||||
|
|
||||||
/// Registers a thread as being created under this process,
|
/// Registers a thread as being created under this process,
|
||||||
/// adding it to this process' thread list.
|
/// adding it to this process' thread list.
|
||||||
|
@ -297,9 +301,6 @@ public:
|
||||||
void FreeTLSRegion(VAddr tls_address);
|
void FreeTLSRegion(VAddr tls_address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Process(Core::System& system);
|
|
||||||
~Process() override;
|
|
||||||
|
|
||||||
/// Checks if the specified thread should wait until this process is available.
|
/// Checks if the specified thread should wait until this process is available.
|
||||||
bool ShouldWait(const Thread* thread) const override;
|
bool ShouldWait(const Thread* thread) const override;
|
||||||
|
|
||||||
|
@ -338,7 +339,7 @@ private:
|
||||||
u32 system_resource_size = 0;
|
u32 system_resource_size = 0;
|
||||||
|
|
||||||
/// Resource limit descriptor for this process
|
/// Resource limit descriptor for this process
|
||||||
SharedPtr<ResourceLimit> resource_limit;
|
std::shared_ptr<ResourceLimit> resource_limit;
|
||||||
|
|
||||||
/// The ideal CPU core for this process, threads are scheduled on this core by default.
|
/// The ideal CPU core for this process, threads are scheduled on this core by default.
|
||||||
u8 ideal_core = 0;
|
u8 ideal_core = 0;
|
||||||
|
@ -386,7 +387,7 @@ private:
|
||||||
std::list<const Thread*> thread_list;
|
std::list<const Thread*> thread_list;
|
||||||
|
|
||||||
/// List of threads waiting for a condition variable
|
/// List of threads waiting for a condition variable
|
||||||
std::unordered_map<VAddr, std::list<SharedPtr<Thread>>> cond_var_threads;
|
std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads;
|
||||||
|
|
||||||
/// System context
|
/// System context
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
|
@ -16,8 +16,8 @@ constexpr std::size_t ResourceTypeToIndex(ResourceType type) {
|
||||||
ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
|
ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
|
||||||
ResourceLimit::~ResourceLimit() = default;
|
ResourceLimit::~ResourceLimit() = default;
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
|
std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) {
|
||||||
return new ResourceLimit(kernel);
|
return std::make_shared<ResourceLimit>(kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
|
s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
|
||||||
|
|
|
@ -31,8 +31,11 @@ constexpr bool IsValidResourceType(ResourceType type) {
|
||||||
|
|
||||||
class ResourceLimit final : public Object {
|
class ResourceLimit final : public Object {
|
||||||
public:
|
public:
|
||||||
|
explicit ResourceLimit(KernelCore& kernel);
|
||||||
|
~ResourceLimit() override;
|
||||||
|
|
||||||
/// Creates a resource limit object.
|
/// Creates a resource limit object.
|
||||||
static SharedPtr<ResourceLimit> Create(KernelCore& kernel);
|
static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel);
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ResourceLimit";
|
return "ResourceLimit";
|
||||||
|
@ -76,9 +79,6 @@ public:
|
||||||
ResultCode SetLimitValue(ResourceType resource, s64 value);
|
ResultCode SetLimitValue(ResourceType resource, s64 value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ResourceLimit(KernelCore& kernel);
|
|
||||||
~ResourceLimit() override;
|
|
||||||
|
|
||||||
// TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
|
// TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create
|
||||||
// functions
|
// functions
|
||||||
//
|
//
|
||||||
|
|
|
@ -26,11 +26,11 @@ GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {}
|
||||||
|
|
||||||
GlobalScheduler::~GlobalScheduler() = default;
|
GlobalScheduler::~GlobalScheduler() = default;
|
||||||
|
|
||||||
void GlobalScheduler::AddThread(SharedPtr<Thread> thread) {
|
void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) {
|
||||||
thread_list.push_back(std::move(thread));
|
thread_list.push_back(std::move(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalScheduler::RemoveThread(const Thread* thread) {
|
void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) {
|
||||||
thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
|
thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
|
||||||
thread_list.end());
|
thread_list.end());
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ void GlobalScheduler::UnloadThread(std::size_t core) {
|
||||||
|
|
||||||
void GlobalScheduler::SelectThread(std::size_t core) {
|
void GlobalScheduler::SelectThread(std::size_t core) {
|
||||||
const auto update_thread = [](Thread* thread, Scheduler& sched) {
|
const auto update_thread = [](Thread* thread, Scheduler& sched) {
|
||||||
if (thread != sched.selected_thread) {
|
if (thread != sched.selected_thread.get()) {
|
||||||
if (thread == nullptr) {
|
if (thread == nullptr) {
|
||||||
++sched.idle_selection_count;
|
++sched.idle_selection_count;
|
||||||
}
|
}
|
||||||
sched.selected_thread = thread;
|
sched.selected_thread = SharedFrom(thread);
|
||||||
}
|
}
|
||||||
sched.is_context_switch_pending = sched.selected_thread != sched.current_thread;
|
sched.is_context_switch_pending = sched.selected_thread != sched.current_thread;
|
||||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||||
|
@ -446,7 +446,7 @@ void Scheduler::SwitchContext() {
|
||||||
|
|
||||||
// Cancel any outstanding wakeup events for this thread
|
// Cancel any outstanding wakeup events for this thread
|
||||||
new_thread->CancelWakeupTimer();
|
new_thread->CancelWakeupTimer();
|
||||||
current_thread = new_thread;
|
current_thread = SharedFrom(new_thread);
|
||||||
new_thread->SetStatus(ThreadStatus::Running);
|
new_thread->SetStatus(ThreadStatus::Running);
|
||||||
new_thread->SetIsRunning(true);
|
new_thread->SetIsRunning(true);
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@ public:
|
||||||
~GlobalScheduler();
|
~GlobalScheduler();
|
||||||
|
|
||||||
/// Adds a new thread to the scheduler
|
/// Adds a new thread to the scheduler
|
||||||
void AddThread(SharedPtr<Thread> thread);
|
void AddThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Removes a thread from the scheduler
|
/// Removes a thread from the scheduler
|
||||||
void RemoveThread(const Thread* thread);
|
void RemoveThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Returns a list of all threads managed by the scheduler
|
/// Returns a list of all threads managed by the scheduler
|
||||||
const std::vector<SharedPtr<Thread>>& GetThreadList() const {
|
const std::vector<std::shared_ptr<Thread>>& GetThreadList() const {
|
||||||
return thread_list;
|
return thread_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ private:
|
||||||
std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};
|
std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};
|
||||||
|
|
||||||
/// Lists all thread ids that aren't deleted/etc.
|
/// Lists all thread ids that aren't deleted/etc.
|
||||||
std::vector<SharedPtr<Thread>> thread_list;
|
std::vector<std::shared_ptr<Thread>> thread_list;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,8 +213,8 @@ private:
|
||||||
*/
|
*/
|
||||||
void UpdateLastContextSwitchTime(Thread* thread, Process* process);
|
void UpdateLastContextSwitchTime(Thread* thread, Process* process);
|
||||||
|
|
||||||
SharedPtr<Thread> current_thread = nullptr;
|
std::shared_ptr<Thread> current_thread = nullptr;
|
||||||
SharedPtr<Thread> selected_thread = nullptr;
|
std::shared_ptr<Thread> selected_thread = nullptr;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
Core::ARM_Interface& cpu_core;
|
Core::ARM_Interface& cpu_core;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Kernel {
|
||||||
ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {}
|
ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {}
|
||||||
ServerPort::~ServerPort() = default;
|
ServerPort::~ServerPort() = default;
|
||||||
|
|
||||||
ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
|
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
|
||||||
if (pending_sessions.empty()) {
|
if (pending_sessions.empty()) {
|
||||||
return ERR_NOT_FOUND;
|
return ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
|
||||||
return MakeResult(std::move(session));
|
return MakeResult(std::move(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerPort::AppendPendingSession(SharedPtr<ServerSession> pending_session) {
|
void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) {
|
||||||
pending_sessions.push_back(std::move(pending_session));
|
pending_sessions.push_back(std::move(pending_session));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ void ServerPort::Acquire(Thread* thread) {
|
||||||
|
|
||||||
ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions,
|
ServerPort::PortPair ServerPort::CreatePortPair(KernelCore& kernel, u32 max_sessions,
|
||||||
std::string name) {
|
std::string name) {
|
||||||
SharedPtr<ServerPort> server_port(new ServerPort(kernel));
|
std::shared_ptr<ServerPort> server_port = std::make_shared<ServerPort>(kernel);
|
||||||
SharedPtr<ClientPort> client_port(new ClientPort(kernel));
|
std::shared_ptr<ClientPort> client_port = std::make_shared<ClientPort>(kernel);
|
||||||
|
|
||||||
server_port->name = name + "_Server";
|
server_port->name = name + "_Server";
|
||||||
client_port->name = name + "_Client";
|
client_port->name = name + "_Client";
|
||||||
|
|
|
@ -22,8 +22,11 @@ class SessionRequestHandler;
|
||||||
|
|
||||||
class ServerPort final : public WaitObject {
|
class ServerPort final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
|
explicit ServerPort(KernelCore& kernel);
|
||||||
|
~ServerPort() override;
|
||||||
|
|
||||||
using HLEHandler = std::shared_ptr<SessionRequestHandler>;
|
using HLEHandler = std::shared_ptr<SessionRequestHandler>;
|
||||||
using PortPair = std::pair<SharedPtr<ServerPort>, SharedPtr<ClientPort>>;
|
using PortPair = std::pair<std::shared_ptr<ServerPort>, std::shared_ptr<ClientPort>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a pair of ServerPort and an associated ClientPort.
|
* Creates a pair of ServerPort and an associated ClientPort.
|
||||||
|
@ -52,7 +55,7 @@ public:
|
||||||
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
|
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
|
||||||
* return ERR_NO_PENDING_SESSIONS.
|
* return ERR_NO_PENDING_SESSIONS.
|
||||||
*/
|
*/
|
||||||
ResultVal<SharedPtr<ServerSession>> Accept();
|
ResultVal<std::shared_ptr<ServerSession>> Accept();
|
||||||
|
|
||||||
/// Whether or not this server port has an HLE handler available.
|
/// Whether or not this server port has an HLE handler available.
|
||||||
bool HasHLEHandler() const {
|
bool HasHLEHandler() const {
|
||||||
|
@ -74,17 +77,14 @@ public:
|
||||||
|
|
||||||
/// Appends a ServerSession to the collection of ServerSessions
|
/// Appends a ServerSession to the collection of ServerSessions
|
||||||
/// waiting to be accepted by this port.
|
/// waiting to be accepted by this port.
|
||||||
void AppendPendingSession(SharedPtr<ServerSession> pending_session);
|
void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
|
||||||
|
|
||||||
bool ShouldWait(const Thread* thread) const override;
|
bool ShouldWait(const Thread* thread) const override;
|
||||||
void Acquire(Thread* thread) override;
|
void Acquire(Thread* thread) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ServerPort(KernelCore& kernel);
|
|
||||||
~ServerPort() override;
|
|
||||||
|
|
||||||
/// ServerSessions waiting to be accepted by the port
|
/// ServerSessions waiting to be accepted by the port
|
||||||
std::vector<SharedPtr<ServerSession>> pending_sessions;
|
std::vector<std::shared_ptr<ServerSession>> pending_sessions;
|
||||||
|
|
||||||
/// This session's HLE request handler template (optional)
|
/// This session's HLE request handler template (optional)
|
||||||
/// ServerSessions created from this port inherit a reference to this handler.
|
/// ServerSessions created from this port inherit a reference to this handler.
|
||||||
|
|
|
@ -35,8 +35,9 @@ ServerSession::~ServerSession() {
|
||||||
parent->server = nullptr;
|
parent->server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelCore& kernel, std::string name) {
|
ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,
|
||||||
SharedPtr<ServerSession> server_session(new ServerSession(kernel));
|
std::string name) {
|
||||||
|
std::shared_ptr<ServerSession> server_session = std::make_shared<ServerSession>(kernel);
|
||||||
|
|
||||||
server_session->name = std::move(name);
|
server_session->name = std::move(name);
|
||||||
server_session->parent = nullptr;
|
server_session->parent = nullptr;
|
||||||
|
@ -69,7 +70,7 @@ void ServerSession::ClientDisconnected() {
|
||||||
if (handler) {
|
if (handler) {
|
||||||
// Note that after this returns, this server session's hle_handler is
|
// Note that after this returns, this server session's hle_handler is
|
||||||
// invalidated (set to null).
|
// invalidated (set to null).
|
||||||
handler->ClientDisconnected(this);
|
handler->ClientDisconnected(SharedFrom(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the list of client threads with pending requests, they are unneeded now that the
|
// Clean up the list of client threads with pending requests, they are unneeded now that the
|
||||||
|
@ -126,11 +127,11 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
|
ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
|
||||||
// The ServerSession received a sync request, this means that there's new data available
|
// The ServerSession received a sync request, this means that there's new data available
|
||||||
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
|
// from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
|
||||||
// similar.
|
// similar.
|
||||||
Kernel::HLERequestContext context(this, thread);
|
Kernel::HLERequestContext context(SharedFrom(this), thread);
|
||||||
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
|
u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
|
||||||
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
context.PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
||||||
|
|
||||||
|
@ -186,9 +187,9 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
|
||||||
|
|
||||||
ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel,
|
ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
SharedPtr<ClientPort> port) {
|
std::shared_ptr<ClientPort> port) {
|
||||||
auto server_session = ServerSession::Create(kernel, name + "_Server").Unwrap();
|
auto server_session = ServerSession::Create(kernel, name + "_Server").Unwrap();
|
||||||
SharedPtr<ClientSession> client_session(new ClientSession(kernel));
|
std::shared_ptr<ClientSession> client_session = std::make_shared<ClientSession>(kernel);
|
||||||
client_session->name = name + "_Client";
|
client_session->name = name + "_Client";
|
||||||
|
|
||||||
std::shared_ptr<Session> parent(new Session);
|
std::shared_ptr<Session> parent(new Session);
|
||||||
|
|
|
@ -38,6 +38,9 @@ class Thread;
|
||||||
*/
|
*/
|
||||||
class ServerSession final : public WaitObject {
|
class ServerSession final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
|
explicit ServerSession(KernelCore& kernel);
|
||||||
|
~ServerSession() override;
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ServerSession";
|
return "ServerSession";
|
||||||
}
|
}
|
||||||
|
@ -59,7 +62,7 @@ public:
|
||||||
return parent.get();
|
return parent.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
using SessionPair = std::pair<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
|
using SessionPair = std::pair<std::shared_ptr<ServerSession>, std::shared_ptr<ClientSession>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a pair of ServerSession and an associated ClientSession.
|
* Creates a pair of ServerSession and an associated ClientSession.
|
||||||
|
@ -69,7 +72,7 @@ public:
|
||||||
* @return The created session tuple
|
* @return The created session tuple
|
||||||
*/
|
*/
|
||||||
static SessionPair CreateSessionPair(KernelCore& kernel, const std::string& name = "Unknown",
|
static SessionPair CreateSessionPair(KernelCore& kernel, const std::string& name = "Unknown",
|
||||||
SharedPtr<ClientPort> client_port = nullptr);
|
std::shared_ptr<ClientPort> client_port = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
||||||
|
@ -85,7 +88,7 @@ public:
|
||||||
* @param thread Thread that initiated the request.
|
* @param thread Thread that initiated the request.
|
||||||
* @returns ResultCode from the operation.
|
* @returns ResultCode from the operation.
|
||||||
*/
|
*/
|
||||||
ResultCode HandleSyncRequest(SharedPtr<Thread> thread);
|
ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
bool ShouldWait(const Thread* thread) const override;
|
bool ShouldWait(const Thread* thread) const override;
|
||||||
|
|
||||||
|
@ -118,9 +121,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ServerSession(KernelCore& kernel);
|
|
||||||
~ServerSession() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a server session. The server session can have an optional HLE handler,
|
* Creates a server session. The server session can have an optional HLE handler,
|
||||||
* which will be invoked to handle the IPC requests that this session receives.
|
* which will be invoked to handle the IPC requests that this session receives.
|
||||||
|
@ -128,8 +128,8 @@ private:
|
||||||
* @param name Optional name of the server session.
|
* @param name Optional name of the server session.
|
||||||
* @return The created server session
|
* @return The created server session
|
||||||
*/
|
*/
|
||||||
static ResultVal<SharedPtr<ServerSession>> Create(KernelCore& kernel,
|
static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel,
|
||||||
std::string name = "Unknown");
|
std::string name = "Unknown");
|
||||||
|
|
||||||
/// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
|
/// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
|
||||||
/// object handle.
|
/// object handle.
|
||||||
|
@ -147,12 +147,12 @@ private:
|
||||||
/// List of threads that are pending a response after a sync request. This list is processed in
|
/// List of threads that are pending a response after a sync request. This list is processed in
|
||||||
/// a LIFO manner, thus, the last request will be dispatched first.
|
/// a LIFO manner, thus, the last request will be dispatched first.
|
||||||
/// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test.
|
/// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test.
|
||||||
std::vector<SharedPtr<Thread>> pending_requesting_threads;
|
std::vector<std::shared_ptr<Thread>> pending_requesting_threads;
|
||||||
|
|
||||||
/// Thread whose request is currently being handled. A request is considered "handled" when a
|
/// Thread whose request is currently being handled. A request is considered "handled" when a
|
||||||
/// response is sent via svcReplyAndReceive.
|
/// response is sent via svcReplyAndReceive.
|
||||||
/// TODO(Subv): Find a better name for this.
|
/// TODO(Subv): Find a better name for this.
|
||||||
SharedPtr<Thread> currently_handling;
|
std::shared_ptr<Thread> currently_handling;
|
||||||
|
|
||||||
/// When set to True, converts the session to a domain at the end of the command
|
/// When set to True, converts the session to a domain at the end of the command
|
||||||
bool convert_to_domain{};
|
bool convert_to_domain{};
|
||||||
|
|
|
@ -20,8 +20,8 @@ class ServerSession;
|
||||||
*/
|
*/
|
||||||
class Session final {
|
class Session final {
|
||||||
public:
|
public:
|
||||||
ClientSession* client = nullptr; ///< The client endpoint of the session.
|
ClientSession* client = nullptr; ///< The client endpoint of the session.
|
||||||
ServerSession* server = nullptr; ///< The server endpoint of the session.
|
ServerSession* server = nullptr; ///< The server endpoint of the session.
|
||||||
SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional).
|
std::shared_ptr<ClientPort> port; ///< The port that this session is associated with (optional).
|
||||||
};
|
};
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -15,11 +15,12 @@ namespace Kernel {
|
||||||
SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {}
|
SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {}
|
||||||
SharedMemory::~SharedMemory() = default;
|
SharedMemory::~SharedMemory() = default;
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process, u64 size,
|
std::shared_ptr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_process,
|
||||||
MemoryPermission permissions,
|
u64 size, MemoryPermission permissions,
|
||||||
MemoryPermission other_permissions, VAddr address,
|
MemoryPermission other_permissions,
|
||||||
MemoryRegion region, std::string name) {
|
VAddr address, MemoryRegion region,
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
|
std::string name) {
|
||||||
|
std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel);
|
||||||
|
|
||||||
shared_memory->owner_process = owner_process;
|
shared_memory->owner_process = owner_process;
|
||||||
shared_memory->name = std::move(name);
|
shared_memory->name = std::move(name);
|
||||||
|
@ -58,10 +59,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, Process* owner_
|
||||||
return shared_memory;
|
return shared_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
|
std::shared_ptr<SharedMemory> SharedMemory::CreateForApplet(
|
||||||
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
||||||
u64 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
|
u64 size, MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
|
std::shared_ptr<SharedMemory> shared_memory = std::make_shared<SharedMemory>(kernel);
|
||||||
|
|
||||||
shared_memory->owner_process = nullptr;
|
shared_memory->owner_process = nullptr;
|
||||||
shared_memory->name = std::move(name);
|
shared_memory->name = std::move(name);
|
||||||
|
|
|
@ -33,6 +33,9 @@ enum class MemoryPermission : u32 {
|
||||||
|
|
||||||
class SharedMemory final : public Object {
|
class SharedMemory final : public Object {
|
||||||
public:
|
public:
|
||||||
|
explicit SharedMemory(KernelCore& kernel);
|
||||||
|
~SharedMemory() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a shared memory object.
|
* Creates a shared memory object.
|
||||||
* @param kernel The kernel instance to create a shared memory instance under.
|
* @param kernel The kernel instance to create a shared memory instance under.
|
||||||
|
@ -46,11 +49,12 @@ public:
|
||||||
* linear heap.
|
* linear heap.
|
||||||
* @param name Optional object name, used for debugging purposes.
|
* @param name Optional object name, used for debugging purposes.
|
||||||
*/
|
*/
|
||||||
static SharedPtr<SharedMemory> Create(KernelCore& kernel, Process* owner_process, u64 size,
|
static std::shared_ptr<SharedMemory> Create(KernelCore& kernel, Process* owner_process,
|
||||||
MemoryPermission permissions,
|
u64 size, MemoryPermission permissions,
|
||||||
MemoryPermission other_permissions, VAddr address = 0,
|
MemoryPermission other_permissions,
|
||||||
MemoryRegion region = MemoryRegion::BASE,
|
VAddr address = 0,
|
||||||
std::string name = "Unknown");
|
MemoryRegion region = MemoryRegion::BASE,
|
||||||
|
std::string name = "Unknown");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a shared memory object from a block of memory managed by an HLE applet.
|
* Creates a shared memory object from a block of memory managed by an HLE applet.
|
||||||
|
@ -63,7 +67,7 @@ public:
|
||||||
* block.
|
* block.
|
||||||
* @param name Optional object name, used for debugging purposes.
|
* @param name Optional object name, used for debugging purposes.
|
||||||
*/
|
*/
|
||||||
static SharedPtr<SharedMemory> CreateForApplet(
|
static std::shared_ptr<SharedMemory> CreateForApplet(
|
||||||
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
KernelCore& kernel, std::shared_ptr<Kernel::PhysicalMemory> heap_block, std::size_t offset,
|
||||||
u64 size, MemoryPermission permissions, MemoryPermission other_permissions,
|
u64 size, MemoryPermission permissions, MemoryPermission other_permissions,
|
||||||
std::string name = "Unknown Applet");
|
std::string name = "Unknown Applet");
|
||||||
|
@ -130,9 +134,6 @@ public:
|
||||||
const u8* GetPointer(std::size_t offset = 0) const;
|
const u8* GetPointer(std::size_t offset = 0) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit SharedMemory(KernelCore& kernel);
|
|
||||||
~SharedMemory() override;
|
|
||||||
|
|
||||||
/// Backing memory for this shared memory block.
|
/// Backing memory for this shared memory block.
|
||||||
std::shared_ptr<PhysicalMemory> backing_block;
|
std::shared_ptr<PhysicalMemory> backing_block;
|
||||||
/// Offset into the backing block for this shared memory.
|
/// Offset into the backing block for this shared memory.
|
||||||
|
|
|
@ -359,7 +359,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
||||||
|
|
||||||
auto client_port = it->second;
|
auto client_port = it->second;
|
||||||
|
|
||||||
SharedPtr<ClientSession> client_session;
|
std::shared_ptr<ClientSession> client_session;
|
||||||
CASCADE_RESULT(client_session, client_port->Connect());
|
CASCADE_RESULT(client_session, client_port->Connect());
|
||||||
|
|
||||||
// Return the client session
|
// Return the client session
|
||||||
|
@ -371,7 +371,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
||||||
/// Makes a blocking IPC call to an OS service.
|
/// Makes a blocking IPC call to an OS service.
|
||||||
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
SharedPtr<ClientSession> session = handle_table.Get<ClientSession>(handle);
|
std::shared_ptr<ClientSession> session = handle_table.Get<ClientSession>(handle);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -391,7 +391,7 @@ static ResultCode GetThreadId(Core::System& system, u64* thread_id, Handle threa
|
||||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", thread_handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -406,13 +406,13 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
|
||||||
LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
|
LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle);
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const SharedPtr<Process> process = handle_table.Get<Process>(handle);
|
const std::shared_ptr<Process> process = handle_table.Get<Process>(handle);
|
||||||
if (process) {
|
if (process) {
|
||||||
*process_id = process->GetProcessID();
|
*process_id = process->GetProcessID();
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
|
||||||
if (thread) {
|
if (thread) {
|
||||||
const Process* const owner_process = thread->GetOwnerProcess();
|
const Process* const owner_process = thread->GetOwnerProcess();
|
||||||
if (!owner_process) {
|
if (!owner_process) {
|
||||||
|
@ -431,8 +431,8 @@ static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle han
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default thread wakeup callback for WaitSynchronization
|
/// Default thread wakeup callback for WaitSynchronization
|
||||||
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
|
static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||||
SharedPtr<WaitObject> object, std::size_t index) {
|
std::shared_ptr<WaitObject> object, std::size_t index) {
|
||||||
ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
|
ASSERT(thread->GetStatus() == ThreadStatus::WaitSynch);
|
||||||
|
|
||||||
if (reason == ThreadWakeupReason::Timeout) {
|
if (reason == ThreadWakeupReason::Timeout) {
|
||||||
|
@ -512,7 +512,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& object : objects) {
|
for (auto& object : objects) {
|
||||||
object->AddWaitingThread(thread);
|
object->AddWaitingThread(SharedFrom(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->SetWaitObjects(std::move(objects));
|
thread->SetWaitObjects(std::move(objects));
|
||||||
|
@ -532,7 +532,7 @@ static ResultCode CancelSynchronization(Core::System& system, Handle thread_hand
|
||||||
LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
|
LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
||||||
thread_handle);
|
thread_handle);
|
||||||
|
@ -941,7 +941,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 ha
|
||||||
const auto& core_timing = system.CoreTiming();
|
const auto& core_timing = system.CoreTiming();
|
||||||
const auto& scheduler = system.CurrentScheduler();
|
const auto& scheduler = system.CurrentScheduler();
|
||||||
const auto* const current_thread = scheduler.GetCurrentThread();
|
const auto* const current_thread = scheduler.GetCurrentThread();
|
||||||
const bool same_thread = current_thread == thread;
|
const bool same_thread = current_thread == thread.get();
|
||||||
|
|
||||||
const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks();
|
const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks();
|
||||||
u64 out_ticks = 0;
|
u64 out_ticks = 0;
|
||||||
|
@ -1051,7 +1051,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* current_process = system.Kernel().CurrentProcess();
|
const auto* current_process = system.Kernel().CurrentProcess();
|
||||||
const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -1067,7 +1067,7 @@ static ResultCode SetThreadActivity(Core::System& system, Handle handle, u32 act
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread == system.CurrentScheduler().GetCurrentThread()) {
|
if (thread.get() == system.CurrentScheduler().GetCurrentThread()) {
|
||||||
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
|
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
|
||||||
return ERR_BUSY;
|
return ERR_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -1083,7 +1083,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
|
||||||
LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
|
LOG_DEBUG(Kernel_SVC, "called, context=0x{:08X}, thread=0x{:X}", thread_context, handle);
|
||||||
|
|
||||||
const auto* current_process = system.Kernel().CurrentProcess();
|
const auto* current_process = system.Kernel().CurrentProcess();
|
||||||
const SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
const std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -1099,7 +1099,7 @@ static ResultCode GetThreadContext(Core::System& system, VAddr thread_context, H
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread == system.CurrentScheduler().GetCurrentThread()) {
|
if (thread.get() == system.CurrentScheduler().GetCurrentThread()) {
|
||||||
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
|
LOG_ERROR(Kernel_SVC, "The thread handle specified is the current running thread");
|
||||||
return ERR_BUSY;
|
return ERR_BUSY;
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1124,7 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle
|
||||||
LOG_TRACE(Kernel_SVC, "called");
|
LOG_TRACE(Kernel_SVC, "called");
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -1148,7 +1148,7 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
|
||||||
|
|
||||||
const auto* const current_process = system.Kernel().CurrentProcess();
|
const auto* const current_process = system.Kernel().CurrentProcess();
|
||||||
|
|
||||||
SharedPtr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
std::shared_ptr<Thread> thread = current_process->GetHandleTable().Get<Thread>(handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
|
||||||
return ERR_INVALID_HANDLE;
|
return ERR_INVALID_HANDLE;
|
||||||
|
@ -1268,7 +1268,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add
|
||||||
VAddr address) {
|
VAddr address) {
|
||||||
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
SharedPtr<Process> process = handle_table.Get<Process>(process_handle);
|
std::shared_ptr<Process> process = handle_table.Get<Process>(process_handle);
|
||||||
if (!process) {
|
if (!process) {
|
||||||
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
|
||||||
process_handle);
|
process_handle);
|
||||||
|
@ -1496,7 +1496,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& kernel = system.Kernel();
|
auto& kernel = system.Kernel();
|
||||||
CASCADE_RESULT(SharedPtr<Thread> thread,
|
CASCADE_RESULT(std::shared_ptr<Thread> thread,
|
||||||
Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top,
|
Thread::Create(kernel, "", entry_point, priority, arg, processor_id, stack_top,
|
||||||
*current_process));
|
*current_process));
|
||||||
|
|
||||||
|
@ -1522,7 +1522,7 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) {
|
||||||
LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
||||||
thread_handle);
|
thread_handle);
|
||||||
|
@ -1546,7 +1546,7 @@ static void ExitThread(Core::System& system) {
|
||||||
|
|
||||||
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
auto* const current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
current_thread->Stop();
|
current_thread->Stop();
|
||||||
system.GlobalScheduler().RemoveThread(current_thread);
|
system.GlobalScheduler().RemoveThread(SharedFrom(current_thread));
|
||||||
system.PrepareReschedule();
|
system.PrepareReschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,7 +1618,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
|
||||||
|
|
||||||
auto* const current_process = system.Kernel().CurrentProcess();
|
auto* const current_process = system.Kernel().CurrentProcess();
|
||||||
const auto& handle_table = current_process->GetHandleTable();
|
const auto& handle_table = current_process->GetHandleTable();
|
||||||
SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
ASSERT(thread);
|
ASSERT(thread);
|
||||||
|
|
||||||
const auto release_result = current_process->GetMutex().Release(mutex_addr);
|
const auto release_result = current_process->GetMutex().Release(mutex_addr);
|
||||||
|
@ -1626,13 +1626,13 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add
|
||||||
return release_result;
|
return release_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
Thread* current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
current_thread->SetCondVarWaitAddress(condition_variable_addr);
|
current_thread->SetCondVarWaitAddress(condition_variable_addr);
|
||||||
current_thread->SetMutexWaitAddress(mutex_addr);
|
current_thread->SetMutexWaitAddress(mutex_addr);
|
||||||
current_thread->SetWaitHandle(thread_handle);
|
current_thread->SetWaitHandle(thread_handle);
|
||||||
current_thread->SetStatus(ThreadStatus::WaitCondVar);
|
current_thread->SetStatus(ThreadStatus::WaitCondVar);
|
||||||
current_thread->InvalidateWakeupCallback();
|
current_thread->InvalidateWakeupCallback();
|
||||||
current_process->InsertConditionVariableThread(current_thread);
|
current_process->InsertConditionVariableThread(SharedFrom(current_thread));
|
||||||
|
|
||||||
current_thread->WakeAfterDelay(nano_seconds);
|
current_thread->WakeAfterDelay(nano_seconds);
|
||||||
|
|
||||||
|
@ -1652,7 +1652,7 @@ static ResultCode SignalProcessWideKey(Core::System& system, VAddr condition_var
|
||||||
|
|
||||||
// Retrieve a list of all threads that are waiting for this condition variable.
|
// Retrieve a list of all threads that are waiting for this condition variable.
|
||||||
auto* const current_process = system.Kernel().CurrentProcess();
|
auto* const current_process = system.Kernel().CurrentProcess();
|
||||||
std::vector<SharedPtr<Thread>> waiting_threads =
|
std::vector<std::shared_ptr<Thread>> waiting_threads =
|
||||||
current_process->GetConditionVariableThreads(condition_variable_addr);
|
current_process->GetConditionVariableThreads(condition_variable_addr);
|
||||||
|
|
||||||
// Only process up to 'target' threads, unless 'target' is less equal 0, in which case process
|
// Only process up to 'target' threads, unless 'target' is less equal 0, in which case process
|
||||||
|
@ -1969,7 +1969,7 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
|
||||||
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
|
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
|
||||||
|
|
||||||
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
||||||
thread_handle);
|
thread_handle);
|
||||||
|
@ -2028,7 +2028,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& handle_table = current_process->GetHandleTable();
|
const auto& handle_table = current_process->GetHandleTable();
|
||||||
const SharedPtr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(thread_handle);
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
|
||||||
thread_handle);
|
thread_handle);
|
||||||
|
|
|
@ -50,7 +50,7 @@ void Thread::Stop() {
|
||||||
|
|
||||||
// Clean up any dangling references in objects that this thread was waiting for
|
// Clean up any dangling references in objects that this thread was waiting for
|
||||||
for (auto& wait_object : wait_objects) {
|
for (auto& wait_object : wait_objects) {
|
||||||
wait_object->RemoveWaitingThread(this);
|
wait_object->RemoveWaitingThread(SharedFrom(this));
|
||||||
}
|
}
|
||||||
wait_objects.clear();
|
wait_objects.clear();
|
||||||
|
|
||||||
|
@ -147,9 +147,10 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd
|
||||||
context.fpcr = 0x03C00000;
|
context.fpcr = 0x03C00000;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
|
ResultVal<std::shared_ptr<Thread>> Thread::Create(KernelCore& kernel, std::string name,
|
||||||
u32 priority, u64 arg, s32 processor_id,
|
VAddr entry_point, u32 priority, u64 arg,
|
||||||
VAddr stack_top, Process& owner_process) {
|
s32 processor_id, VAddr stack_top,
|
||||||
|
Process& owner_process) {
|
||||||
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
// Check if priority is in ranged. Lowest priority -> highest priority id.
|
||||||
if (priority > THREADPRIO_LOWEST) {
|
if (priority > THREADPRIO_LOWEST) {
|
||||||
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
|
||||||
|
@ -168,7 +169,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
SharedPtr<Thread> thread(new Thread(kernel));
|
std::shared_ptr<Thread> thread = std::make_shared<Thread>(kernel);
|
||||||
|
|
||||||
thread->thread_id = kernel.CreateNewThreadID();
|
thread->thread_id = kernel.CreateNewThreadID();
|
||||||
thread->status = ThreadStatus::Dormant;
|
thread->status = ThreadStatus::Dormant;
|
||||||
|
@ -197,7 +198,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
|
||||||
// to initialize the context
|
// to initialize the context
|
||||||
ResetThreadContext(thread->context, stack_top, entry_point, arg);
|
ResetThreadContext(thread->context, stack_top, entry_point, arg);
|
||||||
|
|
||||||
return MakeResult<SharedPtr<Thread>>(std::move(thread));
|
return MakeResult<std::shared_ptr<Thread>>(std::move(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::SetPriority(u32 priority) {
|
void Thread::SetPriority(u32 priority) {
|
||||||
|
@ -215,7 +216,7 @@ void Thread::SetWaitSynchronizationOutput(s32 output) {
|
||||||
context.cpu_registers[1] = output;
|
context.cpu_registers[1] = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Thread::GetWaitObjectIndex(const WaitObject* object) const {
|
s32 Thread::GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const {
|
||||||
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
|
ASSERT_MSG(!wait_objects.empty(), "Thread is not waiting for anything");
|
||||||
const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
|
const auto match = std::find(wait_objects.rbegin(), wait_objects.rend(), object);
|
||||||
return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
|
return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
|
||||||
|
@ -255,8 +256,8 @@ void Thread::SetStatus(ThreadStatus new_status) {
|
||||||
status = new_status;
|
status = new_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
|
void Thread::AddMutexWaiter(std::shared_ptr<Thread> thread) {
|
||||||
if (thread->lock_owner == this) {
|
if (thread->lock_owner.get() == this) {
|
||||||
// If the thread is already waiting for this thread to release the mutex, ensure that the
|
// If the thread is already waiting for this thread to release the mutex, ensure that the
|
||||||
// waiters list is consistent and return without doing anything.
|
// waiters list is consistent and return without doing anything.
|
||||||
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
|
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
|
||||||
|
@ -276,13 +277,13 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
|
||||||
wait_mutex_threads.begin(), wait_mutex_threads.end(),
|
wait_mutex_threads.begin(), wait_mutex_threads.end(),
|
||||||
[&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); });
|
[&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); });
|
||||||
wait_mutex_threads.insert(insertion_point, thread);
|
wait_mutex_threads.insert(insertion_point, thread);
|
||||||
thread->lock_owner = this;
|
thread->lock_owner = SharedFrom(this);
|
||||||
|
|
||||||
UpdatePriority();
|
UpdatePriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) {
|
void Thread::RemoveMutexWaiter(std::shared_ptr<Thread> thread) {
|
||||||
ASSERT(thread->lock_owner == this);
|
ASSERT(thread->lock_owner.get() == this);
|
||||||
|
|
||||||
// Ensure that the thread is in the list of mutex waiters
|
// Ensure that the thread is in the list of mutex waiters
|
||||||
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
|
const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
|
||||||
|
@ -310,13 +311,13 @@ void Thread::UpdatePriority() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetStatus() == ThreadStatus::WaitCondVar) {
|
if (GetStatus() == ThreadStatus::WaitCondVar) {
|
||||||
owner_process->RemoveConditionVariableThread(this);
|
owner_process->RemoveConditionVariableThread(SharedFrom(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCurrentPriority(new_priority);
|
SetCurrentPriority(new_priority);
|
||||||
|
|
||||||
if (GetStatus() == ThreadStatus::WaitCondVar) {
|
if (GetStatus() == ThreadStatus::WaitCondVar) {
|
||||||
owner_process->InsertConditionVariableThread(this);
|
owner_process->InsertConditionVariableThread(SharedFrom(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lock_owner) {
|
if (!lock_owner) {
|
||||||
|
@ -325,8 +326,8 @@ void Thread::UpdatePriority() {
|
||||||
|
|
||||||
// Ensure that the thread is within the correct location in the waiting list.
|
// Ensure that the thread is within the correct location in the waiting list.
|
||||||
auto old_owner = lock_owner;
|
auto old_owner = lock_owner;
|
||||||
lock_owner->RemoveMutexWaiter(this);
|
lock_owner->RemoveMutexWaiter(SharedFrom(this));
|
||||||
old_owner->AddMutexWaiter(this);
|
old_owner->AddMutexWaiter(SharedFrom(this));
|
||||||
|
|
||||||
// Recursively update the priority of the thread that depends on the priority of this one.
|
// Recursively update the priority of the thread that depends on the priority of this one.
|
||||||
lock_owner->UpdatePriority();
|
lock_owner->UpdatePriority();
|
||||||
|
@ -339,11 +340,11 @@ void Thread::ChangeCore(u32 core, u64 mask) {
|
||||||
bool Thread::AllWaitObjectsReady() const {
|
bool Thread::AllWaitObjectsReady() const {
|
||||||
return std::none_of(
|
return std::none_of(
|
||||||
wait_objects.begin(), wait_objects.end(),
|
wait_objects.begin(), wait_objects.end(),
|
||||||
[this](const SharedPtr<WaitObject>& object) { return object->ShouldWait(this); });
|
[this](const std::shared_ptr<WaitObject>& object) { return object->ShouldWait(this); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
|
bool Thread::InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||||
SharedPtr<WaitObject> object, std::size_t index) {
|
std::shared_ptr<WaitObject> object, std::size_t index) {
|
||||||
ASSERT(wakeup_callback);
|
ASSERT(wakeup_callback);
|
||||||
return wakeup_callback(reason, std::move(thread), std::move(object), index);
|
return wakeup_callback(reason, std::move(thread), std::move(object), index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,14 +97,18 @@ enum class ThreadSchedMasks : u32 {
|
||||||
|
|
||||||
class Thread final : public WaitObject {
|
class Thread final : public WaitObject {
|
||||||
public:
|
public:
|
||||||
using MutexWaitingThreads = std::vector<SharedPtr<Thread>>;
|
explicit Thread(KernelCore& kernel);
|
||||||
|
~Thread() override;
|
||||||
|
|
||||||
|
using MutexWaitingThreads = std::vector<std::shared_ptr<Thread>>;
|
||||||
|
|
||||||
using ThreadContext = Core::ARM_Interface::ThreadContext;
|
using ThreadContext = Core::ARM_Interface::ThreadContext;
|
||||||
|
|
||||||
using ThreadWaitObjects = std::vector<SharedPtr<WaitObject>>;
|
using ThreadWaitObjects = std::vector<std::shared_ptr<WaitObject>>;
|
||||||
|
|
||||||
using WakeupCallback = std::function<bool(ThreadWakeupReason reason, SharedPtr<Thread> thread,
|
using WakeupCallback =
|
||||||
SharedPtr<WaitObject> object, std::size_t index)>;
|
std::function<bool(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||||
|
std::shared_ptr<WaitObject> object, std::size_t index)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a new thread. The new thread is immediately scheduled
|
* Creates and returns a new thread. The new thread is immediately scheduled
|
||||||
|
@ -118,10 +122,10 @@ public:
|
||||||
* @param owner_process The parent process for the thread
|
* @param owner_process The parent process for the thread
|
||||||
* @return A shared pointer to the newly created thread
|
* @return A shared pointer to the newly created thread
|
||||||
*/
|
*/
|
||||||
static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name,
|
static ResultVal<std::shared_ptr<Thread>> Create(KernelCore& kernel, std::string name,
|
||||||
VAddr entry_point, u32 priority, u64 arg,
|
VAddr entry_point, u32 priority, u64 arg,
|
||||||
s32 processor_id, VAddr stack_top,
|
s32 processor_id, VAddr stack_top,
|
||||||
Process& owner_process);
|
Process& owner_process);
|
||||||
|
|
||||||
std::string GetName() const override {
|
std::string GetName() const override {
|
||||||
return name;
|
return name;
|
||||||
|
@ -166,10 +170,10 @@ public:
|
||||||
void SetPriority(u32 priority);
|
void SetPriority(u32 priority);
|
||||||
|
|
||||||
/// Adds a thread to the list of threads that are waiting for a lock held by this thread.
|
/// Adds a thread to the list of threads that are waiting for a lock held by this thread.
|
||||||
void AddMutexWaiter(SharedPtr<Thread> thread);
|
void AddMutexWaiter(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Removes a thread from the list of threads that are waiting for a lock held by this thread.
|
/// Removes a thread from the list of threads that are waiting for a lock held by this thread.
|
||||||
void RemoveMutexWaiter(SharedPtr<Thread> thread);
|
void RemoveMutexWaiter(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Recalculates the current priority taking into account priority inheritance.
|
/// Recalculates the current priority taking into account priority inheritance.
|
||||||
void UpdatePriority();
|
void UpdatePriority();
|
||||||
|
@ -229,7 +233,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param object Object to query the index of.
|
* @param object Object to query the index of.
|
||||||
*/
|
*/
|
||||||
s32 GetWaitObjectIndex(const WaitObject* object) const;
|
s32 GetWaitObjectIndex(std::shared_ptr<WaitObject> object) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops a thread, invalidating it from further use
|
* Stops a thread, invalidating it from further use
|
||||||
|
@ -320,7 +324,7 @@ public:
|
||||||
|
|
||||||
void ClearWaitObjects() {
|
void ClearWaitObjects() {
|
||||||
for (const auto& waiting_object : wait_objects) {
|
for (const auto& waiting_object : wait_objects) {
|
||||||
waiting_object->RemoveWaitingThread(this);
|
waiting_object->RemoveWaitingThread(SharedFrom(this));
|
||||||
}
|
}
|
||||||
wait_objects.clear();
|
wait_objects.clear();
|
||||||
}
|
}
|
||||||
|
@ -336,7 +340,7 @@ public:
|
||||||
return lock_owner.get();
|
return lock_owner.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetLockOwner(SharedPtr<Thread> owner) {
|
void SetLockOwner(std::shared_ptr<Thread> owner) {
|
||||||
lock_owner = std::move(owner);
|
lock_owner = std::move(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,8 +394,8 @@ public:
|
||||||
* @pre A valid wakeup callback has been set. Violating this precondition
|
* @pre A valid wakeup callback has been set. Violating this precondition
|
||||||
* will cause an assertion to trigger.
|
* will cause an assertion to trigger.
|
||||||
*/
|
*/
|
||||||
bool InvokeWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread,
|
bool InvokeWakeupCallback(ThreadWakeupReason reason, std::shared_ptr<Thread> thread,
|
||||||
SharedPtr<WaitObject> object, std::size_t index);
|
std::shared_ptr<WaitObject> object, std::size_t index);
|
||||||
|
|
||||||
u32 GetIdealCore() const {
|
u32 GetIdealCore() const {
|
||||||
return ideal_core;
|
return ideal_core;
|
||||||
|
@ -449,9 +453,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Thread(KernelCore& kernel);
|
|
||||||
~Thread() override;
|
|
||||||
|
|
||||||
void SetSchedulingStatus(ThreadSchedStatus new_status);
|
void SetSchedulingStatus(ThreadSchedStatus new_status);
|
||||||
void SetCurrentPriority(u32 new_priority);
|
void SetCurrentPriority(u32 new_priority);
|
||||||
ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
|
ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
|
||||||
|
@ -499,7 +500,7 @@ private:
|
||||||
MutexWaitingThreads wait_mutex_threads;
|
MutexWaitingThreads wait_mutex_threads;
|
||||||
|
|
||||||
/// Thread that owns the lock that this thread is waiting for.
|
/// Thread that owns the lock that this thread is waiting for.
|
||||||
SharedPtr<Thread> lock_owner;
|
std::shared_ptr<Thread> lock_owner;
|
||||||
|
|
||||||
/// If waiting on a ConditionVariable, this is the ConditionVariable address
|
/// If waiting on a ConditionVariable, this is the ConditionVariable address
|
||||||
VAddr condvar_wait_address = 0;
|
VAddr condvar_wait_address = 0;
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace Kernel {
|
||||||
TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
|
TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
|
||||||
TransferMemory::~TransferMemory() = default;
|
TransferMemory::~TransferMemory() = default;
|
||||||
|
|
||||||
SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address, u64 size,
|
std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
|
||||||
MemoryPermission permissions) {
|
u64 size, MemoryPermission permissions) {
|
||||||
SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
|
std::shared_ptr<TransferMemory> transfer_memory{std::make_shared<TransferMemory>(kernel)};
|
||||||
|
|
||||||
transfer_memory->base_address = base_address;
|
transfer_memory->base_address = base_address;
|
||||||
transfer_memory->memory_size = size;
|
transfer_memory->memory_size = size;
|
||||||
|
|
|
@ -27,10 +27,13 @@ enum class MemoryPermission : u32;
|
||||||
///
|
///
|
||||||
class TransferMemory final : public Object {
|
class TransferMemory final : public Object {
|
||||||
public:
|
public:
|
||||||
|
explicit TransferMemory(KernelCore& kernel);
|
||||||
|
~TransferMemory() override;
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
|
static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
|
||||||
|
|
||||||
static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size,
|
static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, u64 size,
|
||||||
MemoryPermission permissions);
|
MemoryPermission permissions);
|
||||||
|
|
||||||
TransferMemory(const TransferMemory&) = delete;
|
TransferMemory(const TransferMemory&) = delete;
|
||||||
TransferMemory& operator=(const TransferMemory&) = delete;
|
TransferMemory& operator=(const TransferMemory&) = delete;
|
||||||
|
@ -79,9 +82,6 @@ public:
|
||||||
ResultCode UnmapMemory(VAddr address, u64 size);
|
ResultCode UnmapMemory(VAddr address, u64 size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit TransferMemory(KernelCore& kernel);
|
|
||||||
~TransferMemory() override;
|
|
||||||
|
|
||||||
/// Memory block backing this instance.
|
/// Memory block backing this instance.
|
||||||
std::shared_ptr<PhysicalMemory> backing_block;
|
std::shared_ptr<PhysicalMemory> backing_block;
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,13 @@ namespace Kernel {
|
||||||
WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {}
|
WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {}
|
||||||
WaitObject::~WaitObject() = default;
|
WaitObject::~WaitObject() = default;
|
||||||
|
|
||||||
void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
|
void WaitObject::AddWaitingThread(std::shared_ptr<Thread> thread) {
|
||||||
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
||||||
if (itr == waiting_threads.end())
|
if (itr == waiting_threads.end())
|
||||||
waiting_threads.push_back(std::move(thread));
|
waiting_threads.push_back(std::move(thread));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitObject::RemoveWaitingThread(Thread* thread) {
|
void WaitObject::RemoveWaitingThread(std::shared_ptr<Thread> thread) {
|
||||||
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
|
||||||
// If a thread passed multiple handles to the same object,
|
// If a thread passed multiple handles to the same object,
|
||||||
// the kernel might attempt to remove the thread from the object's
|
// the kernel might attempt to remove the thread from the object's
|
||||||
|
@ -33,7 +33,7 @@ void WaitObject::RemoveWaitingThread(Thread* thread) {
|
||||||
waiting_threads.erase(itr);
|
waiting_threads.erase(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
|
std::shared_ptr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
|
||||||
Thread* candidate = nullptr;
|
Thread* candidate = nullptr;
|
||||||
u32 candidate_priority = THREADPRIO_LOWEST + 1;
|
u32 candidate_priority = THREADPRIO_LOWEST + 1;
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidate;
|
return SharedFrom(candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
|
void WaitObject::WakeupWaitingThread(std::shared_ptr<Thread> thread) {
|
||||||
ASSERT(!ShouldWait(thread.get()));
|
ASSERT(!ShouldWait(thread.get()));
|
||||||
|
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
@ -83,7 +83,7 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
|
||||||
Acquire(thread.get());
|
Acquire(thread.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::size_t index = thread->GetWaitObjectIndex(this);
|
const std::size_t index = thread->GetWaitObjectIndex(SharedFrom(this));
|
||||||
|
|
||||||
thread->ClearWaitObjects();
|
thread->ClearWaitObjects();
|
||||||
|
|
||||||
|
@ -91,7 +91,8 @@ void WaitObject::WakeupWaitingThread(SharedPtr<Thread> thread) {
|
||||||
|
|
||||||
bool resume = true;
|
bool resume = true;
|
||||||
if (thread->HasWakeupCallback()) {
|
if (thread->HasWakeupCallback()) {
|
||||||
resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, this, index);
|
resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Signal, thread, SharedFrom(this),
|
||||||
|
index);
|
||||||
}
|
}
|
||||||
if (resume) {
|
if (resume) {
|
||||||
thread->ResumeFromWait();
|
thread->ResumeFromWait();
|
||||||
|
@ -105,7 +106,7 @@ void WaitObject::WakeupAllWaitingThreads() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SharedPtr<Thread>>& WaitObject::GetWaitingThreads() const {
|
const std::vector<std::shared_ptr<Thread>>& WaitObject::GetWaitingThreads() const {
|
||||||
return waiting_threads;
|
return waiting_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,13 @@ public:
|
||||||
* Add a thread to wait on this object
|
* Add a thread to wait on this object
|
||||||
* @param thread Pointer to thread to add
|
* @param thread Pointer to thread to add
|
||||||
*/
|
*/
|
||||||
void AddWaitingThread(SharedPtr<Thread> thread);
|
void AddWaitingThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a thread from waiting on this object (e.g. if it was resumed already)
|
* Removes a thread from waiting on this object (e.g. if it was resumed already)
|
||||||
* @param thread Pointer to thread to remove
|
* @param thread Pointer to thread to remove
|
||||||
*/
|
*/
|
||||||
void RemoveWaitingThread(Thread* thread);
|
void RemoveWaitingThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wake up all threads waiting on this object that can be awoken, in priority order,
|
* Wake up all threads waiting on this object that can be awoken, in priority order,
|
||||||
|
@ -51,24 +51,24 @@ public:
|
||||||
* Wakes up a single thread waiting on this object.
|
* Wakes up a single thread waiting on this object.
|
||||||
* @param thread Thread that is waiting on this object to wakeup.
|
* @param thread Thread that is waiting on this object to wakeup.
|
||||||
*/
|
*/
|
||||||
void WakeupWaitingThread(SharedPtr<Thread> thread);
|
void WakeupWaitingThread(std::shared_ptr<Thread> thread);
|
||||||
|
|
||||||
/// Obtains the highest priority thread that is ready to run from this object's waiting list.
|
/// Obtains the highest priority thread that is ready to run from this object's waiting list.
|
||||||
SharedPtr<Thread> GetHighestPriorityReadyThread() const;
|
std::shared_ptr<Thread> GetHighestPriorityReadyThread() const;
|
||||||
|
|
||||||
/// Get a const reference to the waiting threads list for debug use
|
/// Get a const reference to the waiting threads list for debug use
|
||||||
const std::vector<SharedPtr<Thread>>& GetWaitingThreads() const;
|
const std::vector<std::shared_ptr<Thread>>& GetWaitingThreads() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Threads waiting for this object to become available
|
/// Threads waiting for this object to become available
|
||||||
std::vector<SharedPtr<Thread>> waiting_threads;
|
std::vector<std::shared_ptr<Thread>> waiting_threads;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialization of DynamicObjectCast for WaitObjects
|
// Specialization of DynamicObjectCast for WaitObjects
|
||||||
template <>
|
template <>
|
||||||
inline SharedPtr<WaitObject> DynamicObjectCast<WaitObject>(SharedPtr<Object> object) {
|
inline std::shared_ptr<WaitObject> DynamicObjectCast<WaitObject>(std::shared_ptr<Object> object) {
|
||||||
if (object != nullptr && object->IsWaitable()) {
|
if (object != nullptr && object->IsWaitable()) {
|
||||||
return boost::static_pointer_cast<WaitObject>(object);
|
return std::static_pointer_cast<WaitObject>(object);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
|
||||||
WritableEvent::~WritableEvent() = default;
|
WritableEvent::~WritableEvent() = default;
|
||||||
|
|
||||||
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
|
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
|
||||||
SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
|
std::shared_ptr<WritableEvent> writable_event(new WritableEvent(kernel));
|
||||||
SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
|
std::shared_ptr<ReadableEvent> readable_event(new ReadableEvent(kernel));
|
||||||
|
|
||||||
writable_event->name = name + ":Writable";
|
writable_event->name = name + ":Writable";
|
||||||
writable_event->readable = readable_event;
|
writable_event->readable = readable_event;
|
||||||
|
@ -27,7 +27,7 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) {
|
||||||
return {std::move(readable_event), std::move(writable_event)};
|
return {std::move(readable_event), std::move(writable_event)};
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const {
|
std::shared_ptr<ReadableEvent> WritableEvent::GetReadableEvent() const {
|
||||||
return readable;
|
return readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ class ReadableEvent;
|
||||||
class WritableEvent;
|
class WritableEvent;
|
||||||
|
|
||||||
struct EventPair {
|
struct EventPair {
|
||||||
SharedPtr<ReadableEvent> readable;
|
std::shared_ptr<ReadableEvent> readable;
|
||||||
SharedPtr<WritableEvent> writable;
|
std::shared_ptr<WritableEvent> writable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WritableEvent final : public Object {
|
class WritableEvent final : public Object {
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ReadableEvent> GetReadableEvent() const;
|
std::shared_ptr<ReadableEvent> GetReadableEvent() const;
|
||||||
|
|
||||||
void Signal();
|
void Signal();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit WritableEvent(KernelCore& kernel);
|
explicit WritableEvent(KernelCore& kernel);
|
||||||
|
|
||||||
SharedPtr<ReadableEvent> readable;
|
std::shared_ptr<ReadableEvent> readable;
|
||||||
|
|
||||||
std::string name; ///< Name of event (optional)
|
std::string name; ///< Name of event (optional)
|
||||||
};
|
};
|
||||||
|
|
|
@ -531,12 +531,11 @@ AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
|
||||||
|
|
||||||
AppletMessageQueue::~AppletMessageQueue() = default;
|
AppletMessageQueue::~AppletMessageQueue() = default;
|
||||||
|
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent()
|
const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent() const {
|
||||||
const {
|
|
||||||
return on_new_message.readable;
|
return on_new_message.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
|
const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
|
||||||
const {
|
const {
|
||||||
return on_operation_mode_changed.readable;
|
return on_operation_mode_changed.readable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ public:
|
||||||
explicit AppletMessageQueue(Kernel::KernelCore& kernel);
|
explicit AppletMessageQueue(Kernel::KernelCore& kernel);
|
||||||
~AppletMessageQueue();
|
~AppletMessageQueue();
|
||||||
|
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
|
const std::shared_ptr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const;
|
const std::shared_ptr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const;
|
||||||
void PushMessage(AppletMessage msg);
|
void PushMessage(AppletMessage msg);
|
||||||
AppletMessage PopMessage();
|
AppletMessage PopMessage();
|
||||||
std::size_t GetMessageCount() const;
|
std::size_t GetMessageCount() const;
|
||||||
|
|
|
@ -108,15 +108,15 @@ void AppletDataBroker::SignalStateChanged() const {
|
||||||
state_changed_event.writable->Signal();
|
state_changed_event.writable->Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
|
||||||
return pop_out_data_event.readable;
|
return pop_out_data_event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
|
||||||
return pop_interactive_out_data_event.readable;
|
return pop_interactive_out_data_event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
|
||||||
return state_changed_event.readable;
|
return state_changed_event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,9 @@ public:
|
||||||
|
|
||||||
void SignalStateChanged() const;
|
void SignalStateChanged() const;
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetNormalDataEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetNormalDataEvent() const;
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetInteractiveDataEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetInteractiveDataEvent() const;
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetStateChangedEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetStateChangedEvent() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Queues are named from applet's perspective
|
// Queues are named from applet's perspective
|
||||||
|
|
|
@ -16,7 +16,7 @@ ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
|
||||||
kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
|
kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const {
|
||||||
return event.readable;
|
return event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
|
explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetEvent() const;
|
||||||
DeliveryCacheProgressImpl& GetImpl();
|
DeliveryCacheProgressImpl& GetImpl();
|
||||||
|
|
||||||
void SignalUpdate() const;
|
void SignalUpdate() const;
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct DeliveryCacheDirectoryEntry {
|
||||||
|
|
||||||
class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
|
class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
|
||||||
public:
|
public:
|
||||||
IDeliveryCacheProgressService(Kernel::SharedPtr<Kernel::ReadableEvent> event,
|
IDeliveryCacheProgressService(std::shared_ptr<Kernel::ReadableEvent> event,
|
||||||
const DeliveryCacheProgressImpl& impl)
|
const DeliveryCacheProgressImpl& impl)
|
||||||
: ServiceFramework{"IDeliveryCacheProgressService"}, event(std::move(event)), impl(impl) {
|
: ServiceFramework{"IDeliveryCacheProgressService"}, event(std::move(event)), impl(impl) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
@ -118,7 +118,7 @@ private:
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> event;
|
std::shared_ptr<Kernel::ReadableEvent> event;
|
||||||
const DeliveryCacheProgressImpl& impl;
|
const DeliveryCacheProgressImpl& impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -501,8 +501,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
|
||||||
last_processed_vibration = vibrations.back();
|
last_processed_vibration = vibrations.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(
|
std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const {
|
||||||
u32 npad_id) const {
|
|
||||||
// TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
|
// TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
|
||||||
// be signalled at least once, and signaled after a new controller is connected?
|
// be signalled at least once, and signaled after a new controller is connected?
|
||||||
const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];
|
const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)];
|
||||||
|
|
|
@ -109,7 +109,7 @@ public:
|
||||||
void VibrateController(const std::vector<u32>& controller_ids,
|
void VibrateController(const std::vector<u32>& controller_ids,
|
||||||
const std::vector<Vibration>& vibrations);
|
const std::vector<Vibration>& vibrations);
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
|
std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
|
||||||
Vibration GetLastVibration() const;
|
Vibration GetLastVibration() const;
|
||||||
|
|
||||||
void AddNewController(NPadControllerType controller);
|
void AddNewController(NPadControllerType controller);
|
||||||
|
|
|
@ -67,7 +67,7 @@ private:
|
||||||
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||||
void UpdateControllers(u64 userdata, s64 cycles_late);
|
void UpdateControllers(u64 userdata, s64 cycles_late);
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
|
std::shared_ptr<Kernel::SharedMemory> shared_mem;
|
||||||
|
|
||||||
Core::Timing::EventType* pad_update_event;
|
Core::Timing::EventType* pad_update_event;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
|
@ -37,7 +37,7 @@ private:
|
||||||
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
|
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
|
||||||
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
|
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
|
||||||
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
|
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
|
std::shared_ptr<Kernel::SharedMemory> shared_mem;
|
||||||
const u32 device_handle{0xABCD};
|
const u32 device_handle{0xABCD};
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
|
@ -342,7 +342,7 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const {
|
const std::shared_ptr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const {
|
||||||
return nfc_tag_load.readable;
|
return nfc_tag_load.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
|
|
||||||
void CreateUserInterface(Kernel::HLERequestContext& ctx);
|
void CreateUserInterface(Kernel::HLERequestContext& ctx);
|
||||||
bool LoadAmiibo(const std::vector<u8>& buffer);
|
bool LoadAmiibo(const std::vector<u8>& buffer);
|
||||||
const Kernel::SharedPtr<Kernel::ReadableEvent>& GetNFCEvent() const;
|
const std::shared_ptr<Kernel::ReadableEvent>& GetNFCEvent() const;
|
||||||
const AmiiboFile& GetAmiiboBuffer() const;
|
const AmiiboFile& GetAmiiboBuffer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -141,7 +141,7 @@ struct PL_U::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle to shared memory region designated for a shared font
|
/// Handle to shared memory region designated for a shared font
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
|
std::shared_ptr<Kernel::SharedMemory> shared_font_mem;
|
||||||
|
|
||||||
/// Backing memory for the shared font data
|
/// Backing memory for the shared font data
|
||||||
std::shared_ptr<Kernel::PhysicalMemory> shared_font;
|
std::shared_ptr<Kernel::PhysicalMemory> shared_font;
|
||||||
|
|
|
@ -61,7 +61,7 @@ void NVDRV::IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version) {
|
||||||
if (ctrl.must_delay) {
|
if (ctrl.must_delay) {
|
||||||
ctrl.fresh_call = false;
|
ctrl.fresh_call = false;
|
||||||
ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout,
|
ctx.SleepClientThread("NVServices::DelayedResponse", ctrl.timeout,
|
||||||
[=](Kernel::SharedPtr<Kernel::Thread> thread,
|
[=](std::shared_ptr<Kernel::Thread> thread,
|
||||||
Kernel::HLERequestContext& ctx,
|
Kernel::HLERequestContext& ctx,
|
||||||
Kernel::ThreadWakeupReason reason) {
|
Kernel::ThreadWakeupReason reason) {
|
||||||
IoctlCtrl ctrl2{ctrl};
|
IoctlCtrl ctrl2{ctrl};
|
||||||
|
|
|
@ -100,11 +100,11 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const {
|
std::shared_ptr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const {
|
||||||
return events_interface.events[event_id].readable;
|
return events_interface.events[event_id].readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const {
|
std::shared_ptr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const {
|
||||||
return events_interface.events[event_id].writable;
|
return events_interface.events[event_id].writable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,9 +114,9 @@ public:
|
||||||
|
|
||||||
void SignalSyncpt(const u32 syncpoint_id, const u32 value);
|
void SignalSyncpt(const u32 syncpoint_id, const u32 value);
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(u32 event_id) const;
|
std::shared_ptr<Kernel::ReadableEvent> GetEvent(u32 event_id) const;
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const;
|
std::shared_ptr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Id to use for the next open file descriptor.
|
/// Id to use for the next open file descriptor.
|
||||||
|
|
|
@ -117,11 +117,11 @@ u32 BufferQueue::Query(QueryType type) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
|
std::shared_ptr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
|
||||||
return buffer_wait_event.writable;
|
return buffer_wait_event.writable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const {
|
||||||
return buffer_wait_event.readable;
|
return buffer_wait_event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,9 +93,9 @@ public:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const;
|
std::shared_ptr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const;
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetBufferWaitEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetBufferWaitEvent() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u32 id;
|
u32 id;
|
||||||
|
|
|
@ -98,7 +98,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
|
||||||
return layer->GetBufferQueue().GetId();
|
return layer->GetBufferQueue().GetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
|
std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
|
||||||
auto* const display = FindDisplay(display_id);
|
auto* const display = FindDisplay(display_id);
|
||||||
|
|
||||||
if (display == nullptr) {
|
if (display == nullptr) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ public:
|
||||||
/// Gets the vsync event for the specified display.
|
/// Gets the vsync event for the specified display.
|
||||||
///
|
///
|
||||||
/// If an invalid display ID is provided, then nullptr is returned.
|
/// If an invalid display ID is provided, then nullptr is returned.
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
|
std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
|
||||||
|
|
||||||
/// Obtains a buffer queue identified by the ID.
|
/// Obtains a buffer queue identified by the ID.
|
||||||
BufferQueue& FindBufferQueue(u32 id);
|
BufferQueue& FindBufferQueue(u32 id);
|
||||||
|
|
|
@ -16,9 +16,9 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
|
||||||
|
|
||||||
constexpr u64 NO_PROCESS_FOUND_PID{0};
|
constexpr u64 NO_PROCESS_FOUND_PID{0};
|
||||||
|
|
||||||
std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
|
std::optional<std::shared_ptr<Kernel::Process>> SearchProcessList(
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list,
|
const std::vector<std::shared_ptr<Kernel::Process>>& process_list,
|
||||||
std::function<bool(const Kernel::SharedPtr<Kernel::Process>&)> predicate) {
|
std::function<bool(const std::shared_ptr<Kernel::Process>&)> predicate) {
|
||||||
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
|
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
|
||||||
|
|
||||||
if (iter == process_list.end()) {
|
if (iter == process_list.end()) {
|
||||||
|
@ -29,7 +29,7 @@ std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list) {
|
const std::vector<std::shared_ptr<Kernel::Process>>& process_list) {
|
||||||
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
||||||
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
|
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
|
||||||
});
|
});
|
||||||
|
@ -124,7 +124,7 @@ private:
|
||||||
|
|
||||||
class Info final : public ServiceFramework<Info> {
|
class Info final : public ServiceFramework<Info> {
|
||||||
public:
|
public:
|
||||||
explicit Info(const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list)
|
explicit Info(const std::vector<std::shared_ptr<Kernel::Process>>& process_list)
|
||||||
: ServiceFramework{"pm:info"}, process_list(process_list) {
|
: ServiceFramework{"pm:info"}, process_list(process_list) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &Info::GetTitleId, "GetTitleId"},
|
{0, &Info::GetTitleId, "GetTitleId"},
|
||||||
|
@ -154,7 +154,7 @@ private:
|
||||||
rb.Push((*process)->GetTitleID());
|
rb.Push((*process)->GetTitleID());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list;
|
const std::vector<std::shared_ptr<Kernel::Process>>& process_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shell final : public ServiceFramework<Shell> {
|
class Shell final : public ServiceFramework<Shell> {
|
||||||
|
|
|
@ -116,7 +116,7 @@ void ServiceFrameworkBase::InstallAsNamedPort() {
|
||||||
port_installed = true;
|
port_installed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
|
std::shared_ptr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
|
||||||
ASSERT(!port_installed);
|
ASSERT(!port_installed);
|
||||||
|
|
||||||
auto& kernel = Core::System::GetInstance().Kernel();
|
auto& kernel = Core::System::GetInstance().Kernel();
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
/// Creates a port pair and registers it on the kernel's global port registry.
|
/// Creates a port pair and registers it on the kernel's global port registry.
|
||||||
void InstallAsNamedPort();
|
void InstallAsNamedPort();
|
||||||
/// Creates and returns an unregistered port for the service.
|
/// Creates and returns an unregistered port for the service.
|
||||||
Kernel::SharedPtr<Kernel::ClientPort> CreatePort();
|
std::shared_ptr<Kernel::ClientPort> CreatePort();
|
||||||
|
|
||||||
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
void InvokeRequest(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client};
|
std::shared_ptr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client};
|
||||||
rb.PushMoveObjects(session);
|
rb.PushMoveObjects(session);
|
||||||
|
|
||||||
LOG_DEBUG(Service, "session={}", session->GetObjectId());
|
LOG_DEBUG(Service, "session={}", session->GetObjectId());
|
||||||
|
|
|
@ -45,7 +45,7 @@ void ServiceManager::InstallInterfaces(std::shared_ptr<ServiceManager> self) {
|
||||||
self->controller_interface = std::make_unique<Controller>();
|
self->controller_interface = std::make_unique<Controller>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService(
|
ResultVal<std::shared_ptr<Kernel::ServerPort>> ServiceManager::RegisterService(
|
||||||
std::string name, unsigned int max_sessions) {
|
std::string name, unsigned int max_sessions) {
|
||||||
|
|
||||||
CASCADE_CODE(ValidateServiceName(name));
|
CASCADE_CODE(ValidateServiceName(name));
|
||||||
|
@ -72,7 +72,7 @@ ResultCode ServiceManager::UnregisterService(const std::string& name) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort(
|
ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
|
|
||||||
CASCADE_CODE(ValidateServiceName(name));
|
CASCADE_CODE(ValidateServiceName(name));
|
||||||
|
@ -84,7 +84,7 @@ ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> ServiceManager::GetServicePort(
|
||||||
return MakeResult(it->second);
|
return MakeResult(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ServiceManager::ConnectToService(
|
ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService(
|
||||||
const std::string& name) {
|
const std::string& name) {
|
||||||
|
|
||||||
CASCADE_RESULT(auto client_port, GetServicePort(name));
|
CASCADE_RESULT(auto client_port, GetServicePort(name));
|
||||||
|
|
|
@ -48,11 +48,11 @@ public:
|
||||||
ServiceManager();
|
ServiceManager();
|
||||||
~ServiceManager();
|
~ServiceManager();
|
||||||
|
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> RegisterService(std::string name,
|
ResultVal<std::shared_ptr<Kernel::ServerPort>> RegisterService(std::string name,
|
||||||
unsigned int max_sessions);
|
unsigned int max_sessions);
|
||||||
ResultCode UnregisterService(const std::string& name);
|
ResultCode UnregisterService(const std::string& name);
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ClientPort>> GetServicePort(const std::string& name);
|
ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);
|
||||||
ResultVal<Kernel::SharedPtr<Kernel::ClientSession>> ConnectToService(const std::string& name);
|
ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::shared_ptr<T> GetService(const std::string& service_name) const {
|
std::shared_ptr<T> GetService(const std::string& service_name) const {
|
||||||
|
@ -77,7 +77,7 @@ private:
|
||||||
std::unique_ptr<Controller> controller_interface;
|
std::unique_ptr<Controller> controller_interface;
|
||||||
|
|
||||||
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
|
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
|
||||||
std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> registered_services;
|
std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::SM
|
} // namespace Service::SM
|
||||||
|
|
|
@ -21,7 +21,7 @@ SharedMemory::SharedMemory(Core::System& system) : system(system) {
|
||||||
|
|
||||||
SharedMemory::~SharedMemory() = default;
|
SharedMemory::~SharedMemory() = default;
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const {
|
std::shared_ptr<Kernel::SharedMemory> SharedMemory::GetSharedMemoryHolder() const {
|
||||||
return shared_memory_holder;
|
return shared_memory_holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
~SharedMemory();
|
~SharedMemory();
|
||||||
|
|
||||||
// Return the shared memory handle
|
// Return the shared memory handle
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> GetSharedMemoryHolder() const;
|
std::shared_ptr<Kernel::SharedMemory> GetSharedMemoryHolder() const;
|
||||||
|
|
||||||
// Set memory barriers in shared memory and update them
|
// Set memory barriers in shared memory and update them
|
||||||
void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint);
|
void SetStandardSteadyClockTimepoint(const SteadyClockTimePoint& timepoint);
|
||||||
|
@ -66,7 +66,7 @@ public:
|
||||||
static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");
|
static_assert(sizeof(Format) == 0xd8, "Format is an invalid size");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_memory_holder{};
|
std::shared_ptr<Kernel::SharedMemory> shared_memory_holder{};
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
Format shared_memory_format{};
|
Format shared_memory_format{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ const Layer& Display::GetLayer(std::size_t index) const {
|
||||||
return layers.at(index);
|
return layers.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> Display::GetVSyncEvent() const {
|
std::shared_ptr<Kernel::ReadableEvent> Display::GetVSyncEvent() const {
|
||||||
return vsync_event.readable;
|
return vsync_event.readable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
const Layer& GetLayer(std::size_t index) const;
|
const Layer& GetLayer(std::size_t index) const;
|
||||||
|
|
||||||
/// Gets the readable vsync event.
|
/// Gets the readable vsync event.
|
||||||
Kernel::SharedPtr<Kernel::ReadableEvent> GetVSyncEvent() const;
|
std::shared_ptr<Kernel::ReadableEvent> GetVSyncEvent() const;
|
||||||
|
|
||||||
/// Signals the internal vsync event.
|
/// Signals the internal vsync event.
|
||||||
void SignalVSyncEvent();
|
void SignalVSyncEvent();
|
||||||
|
|
|
@ -542,7 +542,7 @@ private:
|
||||||
// Wait the current thread until a buffer becomes available
|
// Wait the current thread until a buffer becomes available
|
||||||
ctx.SleepClientThread(
|
ctx.SleepClientThread(
|
||||||
"IHOSBinderDriver::DequeueBuffer", UINT64_MAX,
|
"IHOSBinderDriver::DequeueBuffer", UINT64_MAX,
|
||||||
[=](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
|
[=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx,
|
||||||
Kernel::ThreadWakeupReason reason) {
|
Kernel::ThreadWakeupReason reason) {
|
||||||
// Repeat TransactParcel DequeueBuffer when a buffer is available
|
// Repeat TransactParcel DequeueBuffer when a buffer is available
|
||||||
auto& buffer_queue = nv_flinger->FindBufferQueue(id);
|
auto& buffer_queue = nv_flinger->FindBufferQueue(id);
|
||||||
|
|
|
@ -57,7 +57,7 @@ std::size_t WaitTreeItem::Row() const {
|
||||||
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList() {
|
std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList() {
|
||||||
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
|
std::vector<std::unique_ptr<WaitTreeThread>> item_list;
|
||||||
std::size_t row = 0;
|
std::size_t row = 0;
|
||||||
auto add_threads = [&](const std::vector<Kernel::SharedPtr<Kernel::Thread>>& threads) {
|
auto add_threads = [&](const std::vector<std::shared_ptr<Kernel::Thread>>& threads) {
|
||||||
for (std::size_t i = 0; i < threads.size(); ++i) {
|
for (std::size_t i = 0; i < threads.size(); ++i) {
|
||||||
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[i]));
|
item_list.push_back(std::make_unique<WaitTreeThread>(*threads[i]));
|
||||||
item_list.back()->row = row;
|
item_list.back()->row = row;
|
||||||
|
@ -172,8 +172,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitTreeObjectList::WaitTreeObjectList(
|
WaitTreeObjectList::WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::WaitObject>>& list,
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& list, bool w_all)
|
bool w_all)
|
||||||
: object_list(list), wait_all(w_all) {}
|
: object_list(list), wait_all(w_all) {}
|
||||||
|
|
||||||
WaitTreeObjectList::~WaitTreeObjectList() = default;
|
WaitTreeObjectList::~WaitTreeObjectList() = default;
|
||||||
|
@ -325,7 +325,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
|
||||||
WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {}
|
WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) : WaitTreeWaitObject(object) {}
|
||||||
WaitTreeEvent::~WaitTreeEvent() = default;
|
WaitTreeEvent::~WaitTreeEvent() = default;
|
||||||
|
|
||||||
WaitTreeThreadList::WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list)
|
WaitTreeThreadList::WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list)
|
||||||
: thread_list(list) {}
|
: thread_list(list) {}
|
||||||
WaitTreeThreadList::~WaitTreeThreadList() = default;
|
WaitTreeThreadList::~WaitTreeThreadList() = default;
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ private:
|
||||||
VAddr mutex_address;
|
VAddr mutex_address;
|
||||||
u32 mutex_value;
|
u32 mutex_value;
|
||||||
Kernel::Handle owner_handle;
|
Kernel::Handle owner_handle;
|
||||||
Kernel::SharedPtr<Kernel::Thread> owner;
|
std::shared_ptr<Kernel::Thread> owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitTreeCallstack : public WaitTreeExpandableItem {
|
class WaitTreeCallstack : public WaitTreeExpandableItem {
|
||||||
|
@ -116,15 +116,14 @@ protected:
|
||||||
class WaitTreeObjectList : public WaitTreeExpandableItem {
|
class WaitTreeObjectList : public WaitTreeExpandableItem {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
WaitTreeObjectList(const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& list,
|
WaitTreeObjectList(const std::vector<std::shared_ptr<Kernel::WaitObject>>& list, bool wait_all);
|
||||||
bool wait_all);
|
|
||||||
~WaitTreeObjectList() override;
|
~WaitTreeObjectList() override;
|
||||||
|
|
||||||
QString GetText() const override;
|
QString GetText() const override;
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::WaitObject>>& object_list;
|
const std::vector<std::shared_ptr<Kernel::WaitObject>>& object_list;
|
||||||
bool wait_all;
|
bool wait_all;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -149,14 +148,14 @@ public:
|
||||||
class WaitTreeThreadList : public WaitTreeExpandableItem {
|
class WaitTreeThreadList : public WaitTreeExpandableItem {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WaitTreeThreadList(const std::vector<Kernel::SharedPtr<Kernel::Thread>>& list);
|
explicit WaitTreeThreadList(const std::vector<std::shared_ptr<Kernel::Thread>>& list);
|
||||||
~WaitTreeThreadList() override;
|
~WaitTreeThreadList() override;
|
||||||
|
|
||||||
QString GetText() const override;
|
QString GetText() const override;
|
||||||
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<Kernel::SharedPtr<Kernel::Thread>>& thread_list;
|
const std::vector<std::shared_ptr<Kernel::Thread>>& thread_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WaitTreeModel : public QAbstractItemModel {
|
class WaitTreeModel : public QAbstractItemModel {
|
||||||
|
|
Loading…
Reference in a new issue