mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-31 23:08:22 -04:00
kern: implement thread pinning/SvcSynchronizePreemptionState
This commit is contained in:
parent
b1f38be3ae
commit
787964f7e7
10 changed files with 230 additions and 19 deletions
|
@ -221,6 +221,12 @@ namespace ams::kern {
|
|||
data[id / BitsPerWord] &= ~(1ul << (id % BitsPerWord));
|
||||
}
|
||||
|
||||
static constexpr ALWAYS_INLINE bool GetSvcAllowedImpl(u8 *data, u32 id) {
|
||||
constexpr size_t BitsPerWord = BITSIZEOF(*data);
|
||||
MESOSPHERE_ASSERT(id < svc::SvcId_Count);
|
||||
return (data[id / BitsPerWord] & (1ul << (id % BitsPerWord))) != 0;
|
||||
}
|
||||
|
||||
bool SetSvcAllowed(u32 id) {
|
||||
if (id < BITSIZEOF(this->svc_access_flags)) {
|
||||
SetSvcAllowedImpl(this->svc_access_flags, id);
|
||||
|
@ -266,16 +272,46 @@ namespace ams::kern {
|
|||
|
||||
ALWAYS_INLINE void CopySvcPermissionsTo(KThread::StackParameters &sp) const {
|
||||
static_assert(sizeof(svc_access_flags) == sizeof(sp.svc_permission));
|
||||
/* Copy permissions. */
|
||||
std::memcpy(sp.svc_permission, this->svc_access_flags, sizeof(this->svc_access_flags));
|
||||
|
||||
/* Clear specific SVCs based on our state. */
|
||||
ClearSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException);
|
||||
ClearSvcAllowedImpl(sp.svc_permission, svc::SvcId_SynchronizePreemptionState);
|
||||
if (sp.is_preemption_state_pinned) {
|
||||
if (sp.is_pinned) {
|
||||
ClearSvcAllowedImpl(sp.svc_permission, svc::SvcId_GetInfo);
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void CopyPinnedSvcPermissionsTo(KThread::StackParameters &sp) const {
|
||||
static_assert(sizeof(svc_access_flags) == sizeof(sp.svc_permission));
|
||||
/* Clear all permissions. */
|
||||
std::memset(sp.svc_permission, 0, sizeof(this->svc_access_flags));
|
||||
|
||||
/* Set specific SVCs based on our state. */
|
||||
SetSvcAllowedImpl(sp.svc_permission, svc::SvcId_SynchronizePreemptionState);
|
||||
if (GetSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException)) {
|
||||
SetSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException);
|
||||
SetSvcAllowedImpl(sp.svc_permission, svc::SvcId_GetInfo);
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void CopyUnpinnedSvcPermissionsTo(KThread::StackParameters &sp) const {
|
||||
static_assert(sizeof(svc_access_flags) == sizeof(sp.svc_permission));
|
||||
/* Get whether we have access to return from exception. */
|
||||
const bool return_from_exception = GetSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException);
|
||||
|
||||
/* Copy permissions. */
|
||||
std::memcpy(sp.svc_permission, this->svc_access_flags, sizeof(this->svc_access_flags));
|
||||
|
||||
/* Clear/Set specific SVCs based on our state. */
|
||||
ClearSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException);
|
||||
ClearSvcAllowedImpl(sp.svc_permission, svc::SvcId_SynchronizePreemptionState);
|
||||
if (return_from_exception) {
|
||||
SetSvcAllowedImpl(sp.svc_permission, svc::SvcId_ReturnFromException);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool IsPermittedInterrupt(u32 id) const {
|
||||
constexpr size_t BitsPerWord = BITSIZEOF(this->irq_access_flags[0]);
|
||||
if (id < BITSIZEOF(this->irq_access_flags)) {
|
||||
|
|
|
@ -204,10 +204,32 @@ namespace ams::kern {
|
|||
return this->pinned_threads[core_id];
|
||||
}
|
||||
|
||||
void PinThread(s32 core_id, KThread *thread) {
|
||||
MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
|
||||
MESOSPHERE_ASSERT(thread != nullptr);
|
||||
MESOSPHERE_ASSERT(this->pinned_threads[core_id] == nullptr);
|
||||
this->pinned_threads[core_id] = thread;
|
||||
}
|
||||
|
||||
void UnpinThread(s32 core_id, KThread *thread) {
|
||||
MESOSPHERE_ASSERT(0 <= core_id && core_id < static_cast<s32>(cpu::NumCores));
|
||||
MESOSPHERE_ASSERT(thread != nullptr);
|
||||
MESOSPHERE_ASSERT(this->pinned_threads[core_id] == thread);
|
||||
this->pinned_threads[core_id] = nullptr;
|
||||
}
|
||||
|
||||
void CopySvcPermissionsTo(KThread::StackParameters &sp) {
|
||||
this->capabilities.CopySvcPermissionsTo(sp);
|
||||
}
|
||||
|
||||
void CopyPinnedSvcPermissionsTo(KThread::StackParameters &sp) {
|
||||
this->capabilities.CopyPinnedSvcPermissionsTo(sp);
|
||||
}
|
||||
|
||||
void CopyUnpinnedSvcPermissionsTo(KThread::StackParameters &sp) {
|
||||
this->capabilities.CopyUnpinnedSvcPermissionsTo(sp);
|
||||
}
|
||||
|
||||
constexpr KResourceLimit *GetResourceLimit() const { return this->resource_limit; }
|
||||
|
||||
bool ReserveResource(ams::svc::LimitableResource which, s64 value);
|
||||
|
|
|
@ -131,6 +131,9 @@ namespace ams::kern {
|
|||
|
||||
static NOINLINE void ClearPreviousThread(KThread *thread);
|
||||
|
||||
static NOINLINE void PinCurrentThread(KProcess *cur_process);
|
||||
static NOINLINE void UnpinCurrentThread(KProcess *cur_process);
|
||||
|
||||
static NOINLINE void OnThreadStateChanged(KThread *thread, KThread::ThreadState old_state);
|
||||
static NOINLINE void OnThreadPriorityChanged(KThread *thread, s32 old_priority);
|
||||
static NOINLINE void OnThreadAffinityMaskChanged(KThread *thread, const KAffinityMask &old_affinity, s32 old_core);
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace ams::kern {
|
|||
u8 current_svc_id;
|
||||
bool is_calling_svc;
|
||||
bool is_in_exception_handler;
|
||||
bool is_preemption_state_pinned;
|
||||
bool is_pinned;
|
||||
s32 disable_count;
|
||||
KThreadContext *context;
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ namespace ams::kern {
|
|||
using ConditionVariableThreadTree = ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
|
||||
|
||||
WaiterList waiter_list{};
|
||||
WaiterList paused_waiter_list{};
|
||||
WaiterList pinned_waiter_list{};
|
||||
KThread *lock_owner{};
|
||||
ConditionVariableThreadTree *condvar_tree{};
|
||||
uintptr_t debug_params[3]{};
|
||||
|
@ -249,6 +249,9 @@ namespace ams::kern {
|
|||
this->GetStackParameters().disable_count--;
|
||||
}
|
||||
|
||||
void Pin();
|
||||
void Unpin();
|
||||
|
||||
NOINLINE void DisableCoreMigration();
|
||||
NOINLINE void EnableCoreMigration();
|
||||
|
||||
|
@ -281,7 +284,7 @@ namespace ams::kern {
|
|||
|
||||
ALWAYS_INLINE bool HasDpc() const {
|
||||
MESOSPHERE_ASSERT_THIS();
|
||||
return this->GetDpc() != 0;;
|
||||
return this->GetDpc() != 0;
|
||||
}
|
||||
private:
|
||||
void Suspend();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue