kernel: convert KPort, KSession

This commit is contained in:
Liam 2023-03-06 20:34:25 -05:00
parent d24ab14126
commit 097c25b164
28 changed files with 196 additions and 226 deletions

View File

@ -13,40 +13,40 @@ class KAffinityMask {
public: public:
constexpr KAffinityMask() = default; constexpr KAffinityMask() = default;
[[nodiscard]] constexpr u64 GetAffinityMask() const { constexpr u64 GetAffinityMask() const {
return this->mask; return m_mask;
} }
constexpr void SetAffinityMask(u64 new_mask) { constexpr void SetAffinityMask(u64 new_mask) {
ASSERT((new_mask & ~AllowedAffinityMask) == 0); ASSERT((new_mask & ~AllowedAffinityMask) == 0);
this->mask = new_mask; m_mask = new_mask;
} }
[[nodiscard]] constexpr bool GetAffinity(s32 core) const { constexpr bool GetAffinity(s32 core) const {
return (this->mask & GetCoreBit(core)) != 0; return (m_mask & GetCoreBit(core)) != 0;
} }
constexpr void SetAffinity(s32 core, bool set) { constexpr void SetAffinity(s32 core, bool set) {
if (set) { if (set) {
this->mask |= GetCoreBit(core); m_mask |= GetCoreBit(core);
} else { } else {
this->mask &= ~GetCoreBit(core); m_mask &= ~GetCoreBit(core);
} }
} }
constexpr void SetAll() { constexpr void SetAll() {
this->mask = AllowedAffinityMask; m_mask = AllowedAffinityMask;
} }
private: private:
[[nodiscard]] static constexpr u64 GetCoreBit(s32 core) { static constexpr u64 GetCoreBit(s32 core) {
ASSERT(0 <= core && core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES)); ASSERT(0 <= core && core < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
return (1ULL << core); return (1ULL << core);
} }
static constexpr u64 AllowedAffinityMask = (1ULL << Core::Hardware::NUM_CPU_CORES) - 1; static constexpr u64 AllowedAffinityMask = (1ULL << Core::Hardware::NUM_CPU_CORES) - 1;
u64 mask{}; u64 m_mask{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -164,17 +164,12 @@ public:
} }
} }
const std::string& GetName() const {
return name;
}
private: private:
void RegisterWithKernel(); void RegisterWithKernel();
void UnregisterWithKernel(); void UnregisterWithKernel();
protected: protected:
KernelCore& kernel; KernelCore& kernel;
std::string name;
private: private:
std::atomic<u32> m_ref_count{}; std::atomic<u32> m_ref_count{};
@ -208,10 +203,6 @@ public:
return reinterpret_cast<u64>(this); return reinterpret_cast<u64>(this);
} }
virtual const std::string& GetName() const {
return name;
}
private: private:
friend class KAutoObjectWithListContainer; friend class KAutoObjectWithListContainer;
}; };

View File

@ -11,7 +11,7 @@
namespace Kernel { namespace Kernel {
Result KCapabilities::InitializeForKIP(std::span<const u32> kern_caps, KPageTable* page_table) { Result KCapabilities::InitializeForKip(std::span<const u32> kern_caps, KPageTable* page_table) {
// We're initializing an initial process. // We're initializing an initial process.
m_svc_access_flags.reset(); m_svc_access_flags.reset();
m_irq_access_flags.reset(); m_irq_access_flags.reset();

View File

@ -22,7 +22,7 @@ class KCapabilities {
public: public:
constexpr explicit KCapabilities() = default; constexpr explicit KCapabilities() = default;
Result InitializeForKIP(std::span<const u32> kern_caps, KPageTable* page_table); Result InitializeForKip(std::span<const u32> kern_caps, KPageTable* page_table);
Result InitializeForUser(std::span<const u32> user_caps, KPageTable* page_table); Result InitializeForUser(std::span<const u32> user_caps, KPageTable* page_table);
static Result CheckCapabilities(KernelCore& kernel, std::span<const u32> user_caps); static Result CheckCapabilities(KernelCore& kernel, std::span<const u32> user_caps);

View File

@ -14,23 +14,18 @@ namespace Kernel {
KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
KClientPort::~KClientPort() = default; KClientPort::~KClientPort() = default;
void KClientPort::Initialize(KPort* parent_port_, s32 max_sessions_, std::string&& name_) { void KClientPort::Initialize(KPort* parent, s32 max_sessions) {
// Set member variables. // Set member variables.
num_sessions = 0; m_num_sessions = 0;
peak_sessions = 0; m_peak_sessions = 0;
parent = parent_port_; m_parent = parent;
max_sessions = max_sessions_; m_max_sessions = max_sessions;
name = std::move(name_);
} }
void KClientPort::OnSessionFinalized() { void KClientPort::OnSessionFinalized() {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// This might happen if a session was improperly used with this port. if (const auto prev = m_num_sessions--; prev == m_max_sessions) {
ASSERT_MSG(num_sessions > 0, "num_sessions is invalid");
const auto prev = num_sessions--;
if (prev == max_sessions) {
this->NotifyAvailable(); this->NotifyAvailable();
} }
} }
@ -47,81 +42,81 @@ bool KClientPort::IsServerClosed() const {
void KClientPort::Destroy() { void KClientPort::Destroy() {
// Note with our parent that we're closed. // Note with our parent that we're closed.
parent->OnClientClosed(); m_parent->OnClientClosed();
// Close our reference to our parent. // Close our reference to our parent.
parent->Close(); m_parent->Close();
} }
bool KClientPort::IsSignaled() const { bool KClientPort::IsSignaled() const {
return num_sessions < max_sessions; return m_num_sessions.load() < m_max_sessions;
} }
Result KClientPort::CreateSession(KClientSession** out) { Result KClientPort::CreateSession(KClientSession** out) {
// Declare the session we're going to allocate.
KSession* session{};
// Reserve a new session from the resource limit. // Reserve a new session from the resource limit.
//! FIXME: we are reserving this from the wrong resource limit! //! FIXME: we are reserving this from the wrong resource limit!
KScopedResourceReservation session_reservation(kernel.ApplicationProcess()->GetResourceLimit(), KScopedResourceReservation session_reservation(kernel.ApplicationProcess()->GetResourceLimit(),
LimitableResource::SessionCountMax); LimitableResource::SessionCountMax);
R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);
// Allocate a session normally.
session = KSession::Create(kernel);
// Check that we successfully created a session.
R_UNLESS(session != nullptr, ResultOutOfResource);
// Update the session counts. // Update the session counts.
{ {
ON_RESULT_FAILURE {
session->Close();
};
// Atomically increment the number of sessions. // Atomically increment the number of sessions.
s32 new_sessions{}; s32 new_sessions{};
{ {
const auto max = max_sessions; const auto max = m_max_sessions;
auto cur_sessions = num_sessions.load(std::memory_order_acquire); auto cur_sessions = m_num_sessions.load(std::memory_order_acquire);
do { do {
R_UNLESS(cur_sessions < max, ResultOutOfSessions); R_UNLESS(cur_sessions < max, ResultOutOfSessions);
new_sessions = cur_sessions + 1; new_sessions = cur_sessions + 1;
} while (!num_sessions.compare_exchange_weak(cur_sessions, new_sessions, } while (!m_num_sessions.compare_exchange_weak(cur_sessions, new_sessions,
std::memory_order_relaxed)); std::memory_order_relaxed));
} }
// Atomically update the peak session tracking. // Atomically update the peak session tracking.
{ {
auto peak = peak_sessions.load(std::memory_order_acquire); auto peak = m_peak_sessions.load(std::memory_order_acquire);
do { do {
if (peak >= new_sessions) { if (peak >= new_sessions) {
break; break;
} }
} while (!peak_sessions.compare_exchange_weak(peak, new_sessions, } while (!m_peak_sessions.compare_exchange_weak(peak, new_sessions,
std::memory_order_relaxed)); std::memory_order_relaxed));
} }
} }
// Create a new session.
KSession* session = KSession::Create(kernel);
if (session == nullptr) {
// Decrement the session count.
const auto prev = num_sessions--;
if (prev == max_sessions) {
this->NotifyAvailable();
}
return ResultOutOfResource;
}
// Initialize the session. // Initialize the session.
session->Initialize(this, parent->GetName()); session->Initialize(this, m_parent->GetName());
// Commit the session reservation. // Commit the session reservation.
session_reservation.Commit(); session_reservation.Commit();
// Register the session. // Register the session.
KSession::Register(kernel, session); KSession::Register(kernel, session);
auto session_guard = SCOPE_GUARD({ ON_RESULT_FAILURE {
session->GetClientSession().Close(); session->GetClientSession().Close();
session->GetServerSession().Close(); session->GetServerSession().Close();
}); };
// Enqueue the session with our parent. // Enqueue the session with our parent.
R_TRY(parent->EnqueueSession(std::addressof(session->GetServerSession()))); R_TRY(m_parent->EnqueueSession(std::addressof(session->GetServerSession())));
// We succeeded, so set the output. // We succeeded, so set the output.
session_guard.Cancel();
*out = std::addressof(session->GetClientSession()); *out = std::addressof(session->GetClientSession());
return ResultSuccess; R_SUCCEED();
} }
} // namespace Kernel } // namespace Kernel

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <string>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_synchronization_object.h"
@ -20,28 +19,28 @@ class KClientPort final : public KSynchronizationObject {
KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject); KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
public: public:
explicit KClientPort(KernelCore& kernel_); explicit KClientPort(KernelCore& kernel);
~KClientPort() override; ~KClientPort() override;
void Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_); void Initialize(KPort* parent, s32 max_sessions);
void OnSessionFinalized(); void OnSessionFinalized();
void OnServerClosed(); void OnServerClosed();
const KPort* GetParent() const { const KPort* GetParent() const {
return parent; return m_parent;
} }
KPort* GetParent() { KPort* GetParent() {
return parent; return m_parent;
} }
s32 GetNumSessions() const { s32 GetNumSessions() const {
return num_sessions; return m_num_sessions;
} }
s32 GetPeakSessions() const { s32 GetPeakSessions() const {
return peak_sessions; return m_peak_sessions;
} }
s32 GetMaxSessions() const { s32 GetMaxSessions() const {
return max_sessions; return m_max_sessions;
} }
bool IsLight() const; bool IsLight() const;
@ -54,10 +53,10 @@ public:
Result CreateSession(KClientSession** out); Result CreateSession(KClientSession** out);
private: private:
std::atomic<s32> num_sessions{}; std::atomic<s32> m_num_sessions{};
std::atomic<s32> peak_sessions{}; std::atomic<s32> m_peak_sessions{};
s32 max_sessions{}; s32 m_max_sessions{};
KPort* parent{}; KPort* m_parent{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -17,8 +17,8 @@ KClientSession::KClientSession(KernelCore& kernel_)
KClientSession::~KClientSession() = default; KClientSession::~KClientSession() = default;
void KClientSession::Destroy() { void KClientSession::Destroy() {
parent->OnClientClosed(); m_parent->OnClientClosed();
parent->Close(); m_parent->Close();
} }
void KClientSession::OnServerClosed() {} void KClientSession::OnServerClosed() {}
@ -33,7 +33,7 @@ Result KClientSession::SendSyncRequest() {
request->Initialize(nullptr, GetCurrentThread(kernel).GetTLSAddress(), MessageBufferSize); request->Initialize(nullptr, GetCurrentThread(kernel).GetTLSAddress(), MessageBufferSize);
// Send the request. // Send the request.
return parent->GetServerSession().OnRequest(request); R_RETURN(m_parent->GetServerSession().OnRequest(request));
} }
} // namespace Kernel } // namespace Kernel

View File

@ -33,17 +33,16 @@ public:
explicit KClientSession(KernelCore& kernel_); explicit KClientSession(KernelCore& kernel_);
~KClientSession() override; ~KClientSession() override;
void Initialize(KSession* parent_session_, std::string&& name_) { void Initialize(KSession* parent) {
// Set member variables. // Set member variables.
parent = parent_session_; m_parent = parent;
name = std::move(name_);
} }
void Destroy() override; void Destroy() override;
static void PostDestroy([[maybe_unused]] uintptr_t arg) {} static void PostDestroy(uintptr_t arg) {}
KSession* GetParent() const { KSession* GetParent() const {
return parent; return m_parent;
} }
Result SendSyncRequest(); Result SendSyncRequest();
@ -51,7 +50,7 @@ public:
void OnServerClosed(); void OnServerClosed();
private: private:
KSession* parent{}; KSession* m_parent{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -8,55 +8,54 @@
namespace Kernel { namespace Kernel {
KPort::KPort(KernelCore& kernel_) KPort::KPort(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {} : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_server{kernel_}, m_client{kernel_} {}
KPort::~KPort() = default; KPort::~KPort() = default;
void KPort::Initialize(s32 max_sessions_, bool is_light_, const std::string& name_) { void KPort::Initialize(s32 max_sessions, bool is_light, uintptr_t name) {
// Open a new reference count to the initialized port. // Open a new reference count to the initialized port.
Open(); this->Open();
// Create and initialize our server/client pair. // Create and initialize our server/client pair.
KAutoObject::Create(std::addressof(server)); KAutoObject::Create(std::addressof(m_server));
KAutoObject::Create(std::addressof(client)); KAutoObject::Create(std::addressof(m_client));
server.Initialize(this, name_ + ":Server"); m_server.Initialize(this);
client.Initialize(this, max_sessions_, name_ + ":Client"); m_client.Initialize(this, max_sessions);
// Set our member variables. // Set our member variables.
is_light = is_light_; m_is_light = is_light;
name = name_; m_name = name;
state = State::Normal; m_state = State::Normal;
} }
void KPort::OnClientClosed() { void KPort::OnClientClosed() {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
if (state == State::Normal) { if (m_state == State::Normal) {
state = State::ClientClosed; m_state = State::ClientClosed;
} }
} }
void KPort::OnServerClosed() { void KPort::OnServerClosed() {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
if (state == State::Normal) { if (m_state == State::Normal) {
state = State::ServerClosed; m_state = State::ServerClosed;
} }
} }
bool KPort::IsServerClosed() const { bool KPort::IsServerClosed() const {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
return state == State::ServerClosed; return m_state == State::ServerClosed;
} }
Result KPort::EnqueueSession(KServerSession* session) { Result KPort::EnqueueSession(KServerSession* session) {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
R_UNLESS(state == State::Normal, ResultPortClosed); R_UNLESS(m_state == State::Normal, ResultPortClosed);
server.EnqueueSession(session); m_server.EnqueueSession(session);
R_SUCCEED();
return ResultSuccess;
} }
} // namespace Kernel } // namespace Kernel

View File

@ -22,14 +22,17 @@ public:
explicit KPort(KernelCore& kernel_); explicit KPort(KernelCore& kernel_);
~KPort() override; ~KPort() override;
static void PostDestroy([[maybe_unused]] uintptr_t arg) {} static void PostDestroy(uintptr_t arg) {}
void Initialize(s32 max_sessions_, bool is_light_, const std::string& name_); void Initialize(s32 max_sessions, bool is_light, uintptr_t name);
void OnClientClosed(); void OnClientClosed();
void OnServerClosed(); void OnServerClosed();
uintptr_t GetName() const {
return m_name;
}
bool IsLight() const { bool IsLight() const {
return is_light; return m_is_light;
} }
bool IsServerClosed() const; bool IsServerClosed() const;
@ -37,16 +40,16 @@ public:
Result EnqueueSession(KServerSession* session); Result EnqueueSession(KServerSession* session);
KClientPort& GetClientPort() { KClientPort& GetClientPort() {
return client; return m_client;
} }
KServerPort& GetServerPort() { KServerPort& GetServerPort() {
return server; return m_server;
} }
const KClientPort& GetClientPort() const { const KClientPort& GetClientPort() const {
return client; return m_client;
} }
const KServerPort& GetServerPort() const { const KServerPort& GetServerPort() const {
return server; return m_server;
} }
private: private:
@ -57,10 +60,11 @@ private:
ServerClosed = 3, ServerClosed = 3,
}; };
KServerPort server; KServerPort m_server;
KClientPort client; KClientPort m_client;
State state{State::Invalid}; uintptr_t m_name;
bool is_light{}; State m_state{State::Invalid};
bool m_is_light{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -395,6 +395,10 @@ public:
return watchpoints; return watchpoints;
} }
const std::string& GetName() {
return name;
}
private: private:
void PinThread(s32 core_id, KThread* thread) { void PinThread(s32 core_id, KThread* thread) {
ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES)); ASSERT(0 <= core_id && core_id < static_cast<s32>(Core::Hardware::NUM_CPU_CORES));
@ -499,6 +503,8 @@ private:
size_t memory_release_hint{}; size_t memory_release_hint{};
std::string name{};
bool is_signaled{}; bool is_signaled{};
bool is_suspended{}; bool is_suspended{};
bool is_immortal{}; bool is_immortal{};

View File

@ -15,10 +15,9 @@ namespace Kernel {
KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
KServerPort::~KServerPort() = default; KServerPort::~KServerPort() = default;
void KServerPort::Initialize(KPort* parent_port_, std::string&& name_) { void KServerPort::Initialize(KPort* parent) {
// Set member variables. // Set member variables.
parent = parent_port_; m_parent = parent;
name = std::move(name_);
} }
bool KServerPort::IsLight() const { bool KServerPort::IsLight() const {
@ -37,9 +36,9 @@ void KServerPort::CleanupSessions() {
KServerSession* session = nullptr; KServerSession* session = nullptr;
{ {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
if (!session_list.empty()) { if (!m_session_list.empty()) {
session = std::addressof(session_list.front()); session = std::addressof(m_session_list.front());
session_list.pop_front(); m_session_list.pop_front();
} }
} }
@ -54,13 +53,13 @@ void KServerPort::CleanupSessions() {
void KServerPort::Destroy() { void KServerPort::Destroy() {
// Note with our parent that we're closed. // Note with our parent that we're closed.
parent->OnServerClosed(); m_parent->OnServerClosed();
// Perform necessary cleanup of our session lists. // Perform necessary cleanup of our session lists.
this->CleanupSessions(); this->CleanupSessions();
// Close our reference to our parent. // Close our reference to our parent.
parent->Close(); m_parent->Close();
} }
bool KServerPort::IsSignaled() const { bool KServerPort::IsSignaled() const {
@ -68,7 +67,7 @@ bool KServerPort::IsSignaled() const {
UNIMPLEMENTED(); UNIMPLEMENTED();
return false; return false;
} else { } else {
return !session_list.empty(); return !m_session_list.empty();
} }
} }
@ -78,8 +77,8 @@ void KServerPort::EnqueueSession(KServerSession* session) {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// Add the session to our queue. // Add the session to our queue.
session_list.push_back(*session); m_session_list.push_back(*session);
if (session_list.size() == 1) { if (m_session_list.size() == 1) {
this->NotifyAvailable(); this->NotifyAvailable();
} }
} }
@ -90,12 +89,12 @@ KServerSession* KServerPort::AcceptSession() {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// Return the first session in the list. // Return the first session in the list.
if (session_list.empty()) { if (m_session_list.empty()) {
return nullptr; return nullptr;
} }
KServerSession* session = std::addressof(session_list.front()); KServerSession* session = std::addressof(m_session_list.front());
session_list.pop_front(); m_session_list.pop_front();
return session; return session;
} }

View File

@ -25,14 +25,14 @@ public:
explicit KServerPort(KernelCore& kernel_); explicit KServerPort(KernelCore& kernel_);
~KServerPort() override; ~KServerPort() override;
void Initialize(KPort* parent_port_, std::string&& name_); void Initialize(KPort* parent);
void EnqueueSession(KServerSession* pending_session); void EnqueueSession(KServerSession* session);
KServerSession* AcceptSession(); KServerSession* AcceptSession();
const KPort* GetParent() const { const KPort* GetParent() const {
return parent; return m_parent;
} }
bool IsLight() const; bool IsLight() const;
@ -46,8 +46,8 @@ private:
void CleanupSessions(); void CleanupSessions();
SessionList session_list; SessionList m_session_list{};
KPort* parent{}; KPort* m_parent{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -33,18 +33,12 @@ KServerSession::KServerSession(KernelCore& kernel_)
KServerSession::~KServerSession() = default; KServerSession::~KServerSession() = default;
void KServerSession::Initialize(KSession* parent_session_, std::string&& name_) {
// Set member variables.
parent = parent_session_;
name = std::move(name_);
}
void KServerSession::Destroy() { void KServerSession::Destroy() {
parent->OnServerClosed(); m_parent->OnServerClosed();
this->CleanupRequests(); this->CleanupRequests();
parent->Close(); m_parent->Close();
} }
void KServerSession::OnClientClosed() { void KServerSession::OnClientClosed() {
@ -144,7 +138,7 @@ bool KServerSession::IsSignaled() const {
ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
// If the client is closed, we're always signaled. // If the client is closed, we're always signaled.
if (parent->IsClientClosed()) { if (m_parent->IsClientClosed()) {
return true; return true;
} }
@ -161,7 +155,7 @@ Result KServerSession::OnRequest(KSessionRequest* request) {
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// Ensure that we can handle new requests. // Ensure that we can handle new requests.
R_UNLESS(!parent->IsServerClosed(), ResultSessionClosed); R_UNLESS(!m_parent->IsServerClosed(), ResultSessionClosed);
// Check that we're not terminating. // Check that we're not terminating.
R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested);
@ -219,7 +213,7 @@ Result KServerSession::SendReply(bool is_hle) {
KEvent* event = request->GetEvent(); KEvent* event = request->GetEvent();
// Check whether we're closed. // Check whether we're closed.
const bool closed = (client_thread == nullptr || parent->IsClientClosed()); const bool closed = (client_thread == nullptr || m_parent->IsClientClosed());
Result result = ResultSuccess; Result result = ResultSuccess;
if (!closed) { if (!closed) {
@ -294,7 +288,7 @@ Result KServerSession::ReceiveRequest(std::shared_ptr<Service::HLERequestContext
KScopedSchedulerLock sl{kernel}; KScopedSchedulerLock sl{kernel};
// Ensure that we can service the request. // Ensure that we can service the request.
R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed); R_UNLESS(!m_parent->IsClientClosed(), ResultSessionClosed);
// Ensure we aren't already servicing a request. // Ensure we aren't already servicing a request.
R_UNLESS(m_current_request == nullptr, ResultNotFound); R_UNLESS(m_current_request == nullptr, ResultNotFound);

View File

@ -38,14 +38,12 @@ public:
void Destroy() override; void Destroy() override;
void Initialize(KSession* parent_session_, std::string&& name_); void Initialize(KSession* p) {
m_parent = p;
KSession* GetParent() {
return parent;
} }
const KSession* GetParent() const { const KSession* GetParent() const {
return parent; return m_parent;
} }
bool IsSignaled() const override; bool IsSignaled() const override;
@ -66,10 +64,10 @@ private:
void CleanupRequests(); void CleanupRequests();
/// KSession that owns this KServerSession /// KSession that owns this KServerSession
KSession* parent{}; KSession* m_parent{};
/// List of threads which are pending a reply. /// List of threads which are pending a reply.
boost::intrusive::list<KSessionRequest> m_request_list; boost::intrusive::list<KSessionRequest> m_request_list{};
KSessionRequest* m_current_request{}; KSessionRequest* m_current_request{};
KLightLock m_lock; KLightLock m_lock;

View File

@ -10,68 +10,62 @@
namespace Kernel { namespace Kernel {
KSession::KSession(KernelCore& kernel_) KSession::KSession(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {} : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_server{kernel_}, m_client{kernel_} {}
KSession::~KSession() = default; KSession::~KSession() = default;
void KSession::Initialize(KClientPort* port_, const std::string& name_) { void KSession::Initialize(KClientPort* client_port, uintptr_t name) {
// Increment reference count. // Increment reference count.
// Because reference count is one on creation, this will result // Because reference count is one on creation, this will result
// in a reference count of two. Thus, when both server and client are closed // in a reference count of two. Thus, when both server and client are closed
// this object will be destroyed. // this object will be destroyed.
Open(); this->Open();
// Create our sub sessions. // Create our sub sessions.
KAutoObject::Create(std::addressof(server)); KAutoObject::Create(std::addressof(m_server));
KAutoObject::Create(std::addressof(client)); KAutoObject::Create(std::addressof(m_client));
// Initialize our sub sessions. // Initialize our sub sessions.
server.Initialize(this, name_ + ":Server"); m_server.Initialize(this);
client.Initialize(this, name_ + ":Client"); m_client.Initialize(this);
// Set state and name. // Set state and name.
SetState(State::Normal); this->SetState(State::Normal);
name = name_; m_name = name;
// Set our owner process. // Set our owner process.
//! FIXME: this is the wrong process! //! FIXME: this is the wrong process!
process = kernel.ApplicationProcess(); m_process = kernel.ApplicationProcess();
process->Open(); m_process->Open();
// Set our port. // Set our port.
port = port_; m_port = client_port;
if (port != nullptr) { if (m_port != nullptr) {
port->Open(); m_port->Open();
} }
// Mark initialized. // Mark initialized.
initialized = true; m_initialized = true;
} }
void KSession::Finalize() { void KSession::Finalize() {
if (port == nullptr) { if (m_port != nullptr) {
return; m_port->OnSessionFinalized();
m_port->Close();
} }
port->OnSessionFinalized();
port->Close();
} }
void KSession::OnServerClosed() { void KSession::OnServerClosed() {
if (GetState() != State::Normal) { if (this->GetState() == State::Normal) {
return; this->SetState(State::ServerClosed);
m_client.OnServerClosed();
} }
SetState(State::ServerClosed);
client.OnServerClosed();
} }
void KSession::OnClientClosed() { void KSession::OnClientClosed() {
if (GetState() != State::Normal) { if (this->GetState() == State::Normal) {
return; SetState(State::ClientClosed);
m_server.OnClientClosed();
} }
SetState(State::ClientClosed);
server.OnClientClosed();
} }
void KSession::PostDestroy(uintptr_t arg) { void KSession::PostDestroy(uintptr_t arg) {

View File

@ -21,16 +21,15 @@ public:
explicit KSession(KernelCore& kernel_); explicit KSession(KernelCore& kernel_);
~KSession() override; ~KSession() override;
void Initialize(KClientPort* port_, const std::string& name_); void Initialize(KClientPort* port, uintptr_t name);
void Finalize() override; void Finalize() override;
bool IsInitialized() const override { bool IsInitialized() const override {
return initialized; return m_initialized;
} }
uintptr_t GetPostDestroyArgument() const override { uintptr_t GetPostDestroyArgument() const override {
return reinterpret_cast<uintptr_t>(process); return reinterpret_cast<uintptr_t>(m_process);
} }
static void PostDestroy(uintptr_t arg); static void PostDestroy(uintptr_t arg);
@ -48,27 +47,23 @@ public:
} }
KClientSession& GetClientSession() { KClientSession& GetClientSession() {
return client; return m_client;
} }
KServerSession& GetServerSession() { KServerSession& GetServerSession() {
return server; return m_server;
} }
const KClientSession& GetClientSession() const { const KClientSession& GetClientSession() const {
return client; return m_client;
} }
const KServerSession& GetServerSession() const { const KServerSession& GetServerSession() const {
return server; return m_server;
} }
const KClientPort* GetParent() const { const KClientPort* GetParent() const {
return port; return m_port;
}
KClientPort* GetParent() {
return port;
} }
private: private:
@ -80,20 +75,20 @@ private:
}; };
void SetState(State state) { void SetState(State state) {
atomic_state = static_cast<u8>(state); m_atomic_state = static_cast<u8>(state);
} }
State GetState() const { State GetState() const {
return static_cast<State>(atomic_state.load(std::memory_order_relaxed)); return static_cast<State>(m_atomic_state.load());
} }
KServerSession server; KServerSession m_server;
KClientSession client; KClientSession m_client;
std::atomic<std::underlying_type_t<State>> atomic_state{ KClientPort* m_port{};
static_cast<std::underlying_type_t<State>>(State::Invalid)}; uintptr_t m_name{};
KClientPort* port{}; KProcess* m_process{};
KProcess* process{}; std::atomic<u8> m_atomic_state{static_cast<u8>(State::Invalid)};
bool initialized{}; bool m_initialized{};
}; };
} // namespace Kernel } // namespace Kernel

View File

@ -17,15 +17,13 @@ KSharedMemory::~KSharedMemory() = default;
Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
Svc::MemoryPermission owner_permission_, Svc::MemoryPermission owner_permission_,
Svc::MemoryPermission user_permission_, std::size_t size_, Svc::MemoryPermission user_permission_, std::size_t size_) {
std::string name_) {
// Set members. // Set members.
owner_process = owner_process_; owner_process = owner_process_;
device_memory = &device_memory_; device_memory = &device_memory_;
owner_permission = owner_permission_; owner_permission = owner_permission_;
user_permission = user_permission_; user_permission = user_permission_;
size = Common::AlignUp(size_, PageSize); size = Common::AlignUp(size_, PageSize);
name = std::move(name_);
const size_t num_pages = Common::DivideUp(size, PageSize); const size_t num_pages = Common::DivideUp(size, PageSize);
@ -64,7 +62,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
std::memset(device_memory_.GetPointer<void>(block.GetAddress()), 0, block.GetSize()); std::memset(device_memory_.GetPointer<void>(block.GetAddress()), 0, block.GetSize());
} }
return ResultSuccess; R_SUCCEED();
} }
void KSharedMemory::Finalize() { void KSharedMemory::Finalize() {
@ -94,15 +92,15 @@ Result KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t m
R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission); R_UNLESS(map_perm == test_perm, ResultInvalidNewMemoryPermission);
} }
return target_process.PageTable().MapPageGroup(address, *page_group, KMemoryState::Shared, R_RETURN(target_process.PageTable().MapPageGroup(address, *page_group, KMemoryState::Shared,
ConvertToKMemoryPermission(map_perm)); ConvertToKMemoryPermission(map_perm)));
} }
Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) { Result KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) {
// Validate the size. // Validate the size.
R_UNLESS(size == unmap_size, ResultInvalidSize); R_UNLESS(size == unmap_size, ResultInvalidSize);
return target_process.PageTable().UnmapPageGroup(address, *page_group, KMemoryState::Shared); R_RETURN(target_process.PageTable().UnmapPageGroup(address, *page_group, KMemoryState::Shared));
} }
} // namespace Kernel } // namespace Kernel

View File

@ -28,7 +28,7 @@ public:
Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
Svc::MemoryPermission owner_permission_, Svc::MemoryPermission owner_permission_,
Svc::MemoryPermission user_permission_, std::size_t size_, std::string name_); Svc::MemoryPermission user_permission_, std::size_t size_);
/** /**
* Maps a shared memory block to an address in the target process' address space * Maps a shared memory block to an address in the target process' address space

View File

@ -926,6 +926,7 @@ private:
ThreadWaitReasonForDebugging wait_reason_for_debugging{}; ThreadWaitReasonForDebugging wait_reason_for_debugging{};
uintptr_t argument{}; uintptr_t argument{};
VAddr stack_top{}; VAddr stack_top{};
std::string name{};
public: public:
using ConditionVariableThreadTreeType = ConditionVariableThreadTree; using ConditionVariableThreadTreeType = ConditionVariableThreadTree;

View File

@ -742,16 +742,15 @@ struct KernelCore::Impl {
hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); hidbus_shared_mem = KSharedMemory::Create(system.Kernel());
hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
Svc::MemoryPermission::Read, hid_size, "HID:SharedMemory"); Svc::MemoryPermission::Read, hid_size);
font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
Svc::MemoryPermission::Read, font_size, "Font:SharedMemory"); Svc::MemoryPermission::Read, font_size);
irs_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, irs_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
Svc::MemoryPermission::Read, irs_size, "IRS:SharedMemory"); Svc::MemoryPermission::Read, irs_size);
time_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, time_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
Svc::MemoryPermission::Read, time_size, "Time:SharedMemory"); Svc::MemoryPermission::Read, time_size);
hidbus_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, hidbus_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
Svc::MemoryPermission::Read, hidbus_size, Svc::MemoryPermission::Read, hidbus_size);
"HidBus:SharedMemory");
} }
std::mutex registered_objects_lock; std::mutex registered_objects_lock;

View File

@ -81,7 +81,7 @@ Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t
R_UNLESS(port != nullptr, ResultOutOfResource); R_UNLESS(port != nullptr, ResultOutOfResource);
// Initialize the new port. // Initialize the new port.
port->Initialize(max_sessions, false, ""); port->Initialize(max_sessions, false, 0);
// Register the port. // Register the port.
KPort::Register(system.Kernel(), port); KPort::Register(system.Kernel(), port);

View File

@ -12,7 +12,7 @@ namespace Kernel::Svc {
namespace { namespace {
template <typename T> template <typename T>
Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) { Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, uint64_t name) {
auto& process = GetCurrentProcess(system.Kernel()); auto& process = GetCurrentProcess(system.Kernel());
auto& handle_table = process.GetHandleTable(); auto& handle_table = process.GetHandleTable();
@ -59,7 +59,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien
R_UNLESS(session != nullptr, ResultOutOfResource); R_UNLESS(session != nullptr, ResultOutOfResource);
// Initialize the session. // Initialize the session.
session->Initialize(nullptr, fmt::format("{}", name)); session->Initialize(nullptr, name);
// Commit the session reservation. // Commit the session reservation.
session_reservation.Commit(); session_reservation.Commit();

View File

@ -155,7 +155,7 @@ public:
Kernel::LimitableResource::SessionCountMax, 1); Kernel::LimitableResource::SessionCountMax, 1);
auto* session = Kernel::KSession::Create(kernel); auto* session = Kernel::KSession::Create(kernel);
session->Initialize(nullptr, iface->GetServiceName()); session->Initialize(nullptr, 0);
auto next_manager = std::make_shared<Service::SessionRequestManager>( auto next_manager = std::make_shared<Service::SessionRequestManager>(
kernel, manager->GetServerManager()); kernel, manager->GetServerManager());

View File

@ -124,7 +124,7 @@ Result ServerManager::ManageNamedPort(const std::string& service_name,
// Create a new port. // Create a new port.
auto* port = Kernel::KPort::Create(m_system.Kernel()); auto* port = Kernel::KPort::Create(m_system.Kernel());
port->Initialize(max_sessions, false, service_name); port->Initialize(max_sessions, false, 0);
// Register the port. // Register the port.
Kernel::KPort::Register(m_system.Kernel(), port); Kernel::KPort::Register(m_system.Kernel(), port);

View File

@ -62,7 +62,7 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
} }
auto* port = Kernel::KPort::Create(kernel); auto* port = Kernel::KPort::Create(kernel);
port->Initialize(ServerSessionCountMax, false, name); port->Initialize(ServerSessionCountMax, false, 0);
service_ports.emplace(name, port); service_ports.emplace(name, port);
registered_services.emplace(name, handler); registered_services.emplace(name, handler);
@ -211,7 +211,7 @@ void SM::RegisterService(HLERequestContext& ctx) {
} }
auto* port = Kernel::KPort::Create(kernel); auto* port = Kernel::KPort::Create(kernel);
port->Initialize(ServerSessionCountMax, is_light, name); port->Initialize(ServerSessionCountMax, is_light, 0);
SCOPE_EXIT({ port->GetClientPort().Close(); }); SCOPE_EXIT({ port->GetClientPort().Close(); });
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};

View File

@ -44,7 +44,7 @@ void Controller::CloneCurrentObject(HLERequestContext& ctx) {
ASSERT(session != nullptr); ASSERT(session != nullptr);
// Initialize the session. // Initialize the session.
session->Initialize(nullptr, ""); session->Initialize(nullptr, 0);
// Commit the session reservation. // Commit the session reservation.
session_reservation.Commit(); session_reservation.Commit();

View File

@ -182,10 +182,9 @@ bool WaitTreeExpandableItem::IsExpandable() const {
} }
QString WaitTreeSynchronizationObject::GetText() const { QString WaitTreeSynchronizationObject::GetText() const {
return tr("[%1] %2 %3") return tr("[%1] %2")
.arg(object.GetId()) .arg(object.GetId())
.arg(QString::fromStdString(object.GetTypeObj().GetName()), .arg(QString::fromStdString(object.GetTypeObj().GetName()));
QString::fromStdString(object.GetName()));
} }
std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make( std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make(