mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-10 07:06:34 +00:00
kern: devirtualize KReadableEvent::Reset, KWorkerTask::DoWorkerTask
This commit is contained in:
parent
fd187f952e
commit
54dde406bc
12 changed files with 62 additions and 24 deletions
|
@ -96,7 +96,7 @@ namespace ams::kern {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
for (const auto &obj : list) {
|
for (const auto &obj : list) {
|
||||||
AMS_AUDIT(obj.DynamicCast<const U *>() != nullptr);
|
MESOSPHERE_AUDIT(obj.DynamicCast<const U *>() != nullptr);
|
||||||
if (static_cast<const U &>(obj).GetOwner() == owner) {
|
if (static_cast<const U &>(obj).GetOwner() == owner) {
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,16 @@ namespace ams::kern {
|
||||||
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
|
Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type);
|
||||||
void Finalize();
|
void Finalize();
|
||||||
|
|
||||||
virtual Result Reset() override;
|
Result Reset();
|
||||||
|
|
||||||
|
Result Clear() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Try to perform a reset, succeeding unconditionally. */
|
||||||
|
this->Reset();
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
bool IsInitialized() const { return m_is_initialized; }
|
bool IsInitialized() const { return m_is_initialized; }
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>, public KWorkerTask {
|
class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject);
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -399,7 +399,7 @@ namespace ams::kern {
|
||||||
return m_is_signaled;
|
return m_is_signaled;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DoWorkerTask() override;
|
void DoWorkerTaskImpl();
|
||||||
private:
|
private:
|
||||||
void ChangeState(State new_state) {
|
void ChangeState(State new_state) {
|
||||||
if (m_state != new_state) {
|
if (m_state != new_state) {
|
||||||
|
|
|
@ -36,11 +36,22 @@ namespace ams::kern {
|
||||||
constexpr KEvent *GetParent() const { return m_parent; }
|
constexpr KEvent *GetParent() const { return m_parent; }
|
||||||
|
|
||||||
Result Signal();
|
Result Signal();
|
||||||
Result Clear();
|
Result Reset();
|
||||||
|
|
||||||
|
Result Clear() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Try to perform a reset, succeeding unconditionally. */
|
||||||
|
this->Reset();
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
virtual void Destroy() override;
|
virtual void Destroy() override;
|
||||||
virtual Result Reset();
|
|
||||||
|
/* NOTE: This is a virtual function in Nintendo's kernel. */
|
||||||
|
/* virtual Result Reset(); */
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
using KThreadFunction = void (*)(uintptr_t);
|
using KThreadFunction = void (*)(uintptr_t);
|
||||||
|
|
||||||
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, public util::IntrusiveListBaseNode<KThread>, public KTimerTask, public KWorkerTask {
|
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, public util::IntrusiveListBaseNode<KThread>, public KTimerTask {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
|
||||||
private:
|
private:
|
||||||
friend class KProcess;
|
friend class KProcess;
|
||||||
|
@ -235,7 +235,7 @@ namespace ams::kern {
|
||||||
bool m_resource_limit_release_hint;
|
bool m_resource_limit_release_hint;
|
||||||
public:
|
public:
|
||||||
constexpr explicit KThread(util::ConstantInitializeTag)
|
constexpr explicit KThread(util::ConstantInitializeTag)
|
||||||
: KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>(util::ConstantInitialize), KTimerTask(util::ConstantInitialize),
|
: KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>(util::ConstantInitialize), KTimerTask(util::ConstantInitialize),
|
||||||
m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{},
|
m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{},
|
||||||
m_thread_context{util::ConstantInitialize}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null<KProcessAddress>}, m_parent{},
|
m_thread_context{util::ConstantInitialize}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null<KProcessAddress>}, m_parent{},
|
||||||
m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null<KProcessAddress>}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize},
|
m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null<KProcessAddress>}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize},
|
||||||
|
@ -622,7 +622,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
virtual bool IsSignaled() const override;
|
virtual bool IsSignaled() const override;
|
||||||
void OnTimer();
|
void OnTimer();
|
||||||
virtual void DoWorkerTask() override;
|
void DoWorkerTaskImpl();
|
||||||
public:
|
public:
|
||||||
static constexpr bool IsConditionVariableThreadTreeValid() {
|
static constexpr bool IsConditionVariableThreadTreeValid() {
|
||||||
return ConditionVariableThreadTreeTraits::IsValid();
|
return ConditionVariableThreadTreeTraits::IsValid();
|
||||||
|
|
|
@ -18,16 +18,23 @@
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
class KWorkerTask {
|
/* NOTE: We inherit KWorkerTask from KSynchronizationObject in order to devirtualize DoWorkerTask, which is exclusive to KThread/KProcess. */
|
||||||
|
/* This should be reverted, if Nintendo adds new types of worker tasks in the future. */
|
||||||
|
|
||||||
|
/* Nintendo has class KWorkerTask { ... } with identical interface but DoWorkerTask() virtual. */
|
||||||
|
|
||||||
|
class KWorkerTask : public KSynchronizationObject {
|
||||||
private:
|
private:
|
||||||
KWorkerTask *m_next_task;
|
KWorkerTask *m_next_task;
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE KWorkerTask() : m_next_task(nullptr) { /* ... */ }
|
constexpr ALWAYS_INLINE explicit KWorkerTask(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_next_task(nullptr) { /* ... */ }
|
||||||
|
|
||||||
|
ALWAYS_INLINE explicit KWorkerTask() : m_next_task(nullptr) { /* ... */ }
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE KWorkerTask *GetNextTask() const { return m_next_task; }
|
constexpr ALWAYS_INLINE KWorkerTask *GetNextTask() const { return m_next_task; }
|
||||||
constexpr ALWAYS_INLINE void SetNextTask(KWorkerTask *task) { m_next_task = task; }
|
constexpr ALWAYS_INLINE void SetNextTask(KWorkerTask *task) { m_next_task = task; }
|
||||||
|
|
||||||
virtual void DoWorkerTask() = 0;
|
void DoWorkerTask();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -432,7 +432,7 @@ namespace ams::kern {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KProcess::DoWorkerTask() {
|
void KProcess::DoWorkerTaskImpl() {
|
||||||
/* Terminate child threads. */
|
/* Terminate child threads. */
|
||||||
TerminateChildren(this, nullptr);
|
TerminateChildren(this, nullptr);
|
||||||
|
|
||||||
|
|
|
@ -59,14 +59,6 @@ namespace ams::kern {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result KReadableEvent::Clear() {
|
|
||||||
MESOSPHERE_ASSERT_THIS();
|
|
||||||
|
|
||||||
this->Reset();
|
|
||||||
|
|
||||||
return ResultSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result KReadableEvent::Reset() {
|
Result KReadableEvent::Reset() {
|
||||||
MESOSPHERE_ASSERT_THIS();
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
|
|
@ -406,7 +406,7 @@ namespace ams::kern {
|
||||||
this->Close();
|
this->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KThread::DoWorkerTask() {
|
void KThread::DoWorkerTaskImpl() {
|
||||||
/* Finish the termination that was begun by Exit(). */
|
/* Finish the termination that was begun by Exit(). */
|
||||||
this->FinishTermination();
|
this->FinishTermination();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,17 @@ namespace ams::kern {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KWorkerTask::DoWorkerTask() {
|
||||||
|
if (auto * const thread = this->DynamicCast<KThread *>(); thread != nullptr) {
|
||||||
|
return thread->DoWorkerTaskImpl();
|
||||||
|
} else {
|
||||||
|
auto * const process = this->DynamicCast<KProcess *>();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(process != nullptr);
|
||||||
|
|
||||||
|
return process->DoWorkerTaskImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KWorkerTaskManager::Initialize(s32 priority) {
|
void KWorkerTaskManager::Initialize(s32 priority) {
|
||||||
/* Reserve a thread from the system limit. */
|
/* Reserve a thread from the system limit. */
|
||||||
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_ThreadCountMax, 1));
|
MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_ThreadCountMax, 1));
|
||||||
|
|
|
@ -48,9 +48,13 @@ namespace ams::kern::svc {
|
||||||
{
|
{
|
||||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
|
||||||
if (readable_event.IsNotNull()) {
|
if (readable_event.IsNotNull()) {
|
||||||
|
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
|
||||||
|
return interrupt_event->Clear();
|
||||||
|
} else {
|
||||||
return readable_event->Clear();
|
return readable_event->Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return svc::ResultInvalidHandle();
|
return svc::ResultInvalidHandle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,13 @@ namespace ams::kern::svc {
|
||||||
{
|
{
|
||||||
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle);
|
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle);
|
||||||
if (readable_event.IsNotNull()) {
|
if (readable_event.IsNotNull()) {
|
||||||
|
if (auto * const interrupt_event = readable_event->DynamicCast<KInterruptEvent *>(); interrupt_event != nullptr) {
|
||||||
|
return interrupt_event->Reset();
|
||||||
|
} else {
|
||||||
return readable_event->Reset();
|
return readable_event->Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to reset as process. */
|
/* Try to reset as process. */
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue