mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
kern: cleanup KThread, optimize/normalize KThreadQueue/KWaitObject
This commit is contained in:
parent
a4c4cf22c9
commit
72671d39ab
10 changed files with 58 additions and 168 deletions
|
@ -24,7 +24,6 @@ namespace ams::kern {
|
||||||
struct InfoCreateThread {
|
struct InfoCreateThread {
|
||||||
u32 thread_id;
|
u32 thread_id;
|
||||||
uintptr_t tls_address;
|
uintptr_t tls_address;
|
||||||
uintptr_t entrypoint;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InfoExitProcess {
|
struct InfoExitProcess {
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
using KThreadFunction = void (*)(uintptr_t);
|
using KThreadFunction = void (*)(uintptr_t);
|
||||||
|
|
||||||
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, public KTimerTask, public KWorkerTask {
|
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, public util::IntrusiveListBaseNode<KThread>, public KTimerTask, public KWorkerTask {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
|
||||||
private:
|
private:
|
||||||
friend class KProcess;
|
friend class KProcess;
|
||||||
|
@ -111,6 +111,8 @@ namespace ams::kern {
|
||||||
constexpr void SetPrev(KThread *t) { this->prev = t; }
|
constexpr void SetPrev(KThread *t) { this->prev = t; }
|
||||||
constexpr void SetNext(KThread *t) { this->next = t; }
|
constexpr void SetNext(KThread *t) { this->next = t; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using WaiterList = util::IntrusiveListBaseTraits<KThread>::ListType;
|
||||||
private:
|
private:
|
||||||
static constexpr size_t PriorityInheritanceCountMax = 10;
|
static constexpr size_t PriorityInheritanceCountMax = 10;
|
||||||
union SyncObjectBuffer {
|
union SyncObjectBuffer {
|
||||||
|
@ -141,13 +143,19 @@ namespace ams::kern {
|
||||||
static inline std::atomic<u64> s_next_thread_id = 0;
|
static inline std::atomic<u64> s_next_thread_id = 0;
|
||||||
private:
|
private:
|
||||||
alignas(16) KThreadContext thread_context{};
|
alignas(16) KThreadContext thread_context{};
|
||||||
|
util::IntrusiveListNode process_list_node{};
|
||||||
|
util::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{};
|
||||||
|
s32 priority{};
|
||||||
|
|
||||||
|
using ConditionVariableThreadTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&KThread::condvar_arbiter_tree_node>;
|
||||||
|
using ConditionVariableThreadTree = ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
|
||||||
|
|
||||||
|
ConditionVariableThreadTree *condvar_tree{};
|
||||||
|
uintptr_t condvar_key{};
|
||||||
KAffinityMask affinity_mask{};
|
KAffinityMask affinity_mask{};
|
||||||
u64 thread_id{};
|
u64 thread_id{};
|
||||||
std::atomic<s64> cpu_time{};
|
std::atomic<s64> cpu_time{};
|
||||||
KSynchronizationObject *synced_object{};
|
KSynchronizationObject *synced_object{};
|
||||||
KLightLock *waiting_lock{};
|
|
||||||
uintptr_t condvar_key{};
|
|
||||||
uintptr_t entrypoint{};
|
|
||||||
KProcessAddress address_key{};
|
KProcessAddress address_key{};
|
||||||
KProcess *parent{};
|
KProcess *parent{};
|
||||||
void *kernel_stack_top{};
|
void *kernel_stack_top{};
|
||||||
|
@ -159,43 +167,31 @@ namespace ams::kern {
|
||||||
s64 schedule_count{};
|
s64 schedule_count{};
|
||||||
s64 last_scheduled_tick{};
|
s64 last_scheduled_tick{};
|
||||||
QueueEntry per_core_priority_queue_entry[cpu::NumCores]{};
|
QueueEntry per_core_priority_queue_entry[cpu::NumCores]{};
|
||||||
QueueEntry sleeping_queue_entry{};
|
KLightLock *waiting_lock{};
|
||||||
|
|
||||||
KThreadQueue *sleeping_queue{};
|
KThreadQueue *sleeping_queue{};
|
||||||
util::IntrusiveListNode waiter_list_node{};
|
|
||||||
util::IntrusiveRedBlackTreeNode condvar_arbiter_tree_node{};
|
|
||||||
util::IntrusiveListNode process_list_node{};
|
|
||||||
|
|
||||||
using WaiterListTraits = util::IntrusiveListMemberTraitsDeferredAssert<&KThread::waiter_list_node>;
|
|
||||||
using WaiterList = WaiterListTraits::ListType;
|
|
||||||
|
|
||||||
using ConditionVariableThreadTreeTraits = util::IntrusiveRedBlackTreeMemberTraitsDeferredAssert<&KThread::condvar_arbiter_tree_node>;
|
|
||||||
using ConditionVariableThreadTree = ConditionVariableThreadTreeTraits::TreeType<ConditionVariableComparator>;
|
|
||||||
|
|
||||||
WaiterList waiter_list{};
|
WaiterList waiter_list{};
|
||||||
WaiterList pinned_waiter_list{};
|
WaiterList pinned_waiter_list{};
|
||||||
KThread *lock_owner{};
|
KThread *lock_owner{};
|
||||||
ConditionVariableThreadTree *condvar_tree{};
|
|
||||||
uintptr_t debug_params[3]{};
|
uintptr_t debug_params[3]{};
|
||||||
u32 address_key_value{};
|
u32 address_key_value{};
|
||||||
u32 suspend_request_flags{};
|
u32 suspend_request_flags{};
|
||||||
u32 suspend_allowed_flags{};
|
u32 suspend_allowed_flags{};
|
||||||
Result wait_result;
|
Result wait_result;
|
||||||
Result debug_exception_result;
|
Result debug_exception_result;
|
||||||
s32 priority{};
|
|
||||||
s32 current_core_id{};
|
|
||||||
s32 core_id{};
|
|
||||||
s32 base_priority{};
|
s32 base_priority{};
|
||||||
s32 ideal_core_id{};
|
s32 ideal_core_id{};
|
||||||
s32 num_kernel_waiters{};
|
s32 num_kernel_waiters{};
|
||||||
|
s32 current_core_id{};
|
||||||
|
s32 core_id{};
|
||||||
KAffinityMask original_affinity_mask{};
|
KAffinityMask original_affinity_mask{};
|
||||||
s32 original_ideal_core_id{};
|
s32 original_ideal_core_id{};
|
||||||
s32 num_core_migration_disables{};
|
s32 num_core_migration_disables{};
|
||||||
ThreadState thread_state{};
|
ThreadState thread_state{};
|
||||||
std::atomic<bool> termination_requested{};
|
std::atomic<bool> termination_requested{};
|
||||||
bool ipc_cancelled{};
|
|
||||||
bool wait_cancelled{};
|
bool wait_cancelled{};
|
||||||
bool cancellable{};
|
bool cancellable{};
|
||||||
bool registered{};
|
|
||||||
bool signaled{};
|
bool signaled{};
|
||||||
bool initialized{};
|
bool initialized{};
|
||||||
bool debug_attached{};
|
bool debug_attached{};
|
||||||
|
@ -393,8 +389,6 @@ namespace ams::kern {
|
||||||
constexpr QueueEntry &GetPriorityQueueEntry(s32 core) { return this->per_core_priority_queue_entry[core]; }
|
constexpr QueueEntry &GetPriorityQueueEntry(s32 core) { return this->per_core_priority_queue_entry[core]; }
|
||||||
constexpr const QueueEntry &GetPriorityQueueEntry(s32 core) const { return this->per_core_priority_queue_entry[core]; }
|
constexpr const QueueEntry &GetPriorityQueueEntry(s32 core) const { return this->per_core_priority_queue_entry[core]; }
|
||||||
|
|
||||||
constexpr QueueEntry &GetSleepingQueueEntry() { return this->sleeping_queue_entry; }
|
|
||||||
constexpr const QueueEntry &GetSleepingQueueEntry() const { return this->sleeping_queue_entry; }
|
|
||||||
constexpr void SetSleepingQueue(KThreadQueue *q) { this->sleeping_queue = q; }
|
constexpr void SetSleepingQueue(KThreadQueue *q) { this->sleeping_queue = q; }
|
||||||
|
|
||||||
constexpr ConditionVariableThreadTree *GetConditionVariableTree() const { return this->condvar_tree; }
|
constexpr ConditionVariableThreadTree *GetConditionVariableTree() const { return this->condvar_tree; }
|
||||||
|
@ -459,8 +453,6 @@ namespace ams::kern {
|
||||||
constexpr KProcess *GetOwnerProcess() const { return this->parent; }
|
constexpr KProcess *GetOwnerProcess() const { return this->parent; }
|
||||||
constexpr bool IsUserThread() const { return this->parent != nullptr; }
|
constexpr bool IsUserThread() const { return this->parent != nullptr; }
|
||||||
|
|
||||||
constexpr uintptr_t GetEntrypoint() const { return this->entrypoint; }
|
|
||||||
|
|
||||||
constexpr KProcessAddress GetThreadLocalRegionAddress() const { return this->tls_address; }
|
constexpr KProcessAddress GetThreadLocalRegionAddress() const { return this->tls_address; }
|
||||||
constexpr void *GetThreadLocalRegionHeapAddress() const { return this->tls_heap_address; }
|
constexpr void *GetThreadLocalRegionHeapAddress() const { return this->tls_heap_address; }
|
||||||
|
|
||||||
|
@ -541,10 +533,6 @@ namespace ams::kern {
|
||||||
virtual void OnTimer() override;
|
virtual void OnTimer() override;
|
||||||
virtual void DoWorkerTask() override;
|
virtual void DoWorkerTask() override;
|
||||||
public:
|
public:
|
||||||
static constexpr bool IsWaiterListValid() {
|
|
||||||
return WaiterListTraits::IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr bool IsConditionVariableThreadTreeValid() {
|
static constexpr bool IsConditionVariableThreadTreeValid() {
|
||||||
return ConditionVariableThreadTreeTraits::IsValid();
|
return ConditionVariableThreadTreeTraits::IsValid();
|
||||||
}
|
}
|
||||||
|
@ -555,7 +543,6 @@ namespace ams::kern {
|
||||||
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
|
using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
|
||||||
};
|
};
|
||||||
static_assert(alignof(KThread) == 0x10);
|
static_assert(alignof(KThread) == 0x10);
|
||||||
static_assert(KThread::IsWaiterListValid());
|
|
||||||
static_assert(KThread::IsConditionVariableThreadTreeValid());
|
static_assert(KThread::IsConditionVariableThreadTreeValid());
|
||||||
|
|
||||||
class KScopedDisableDispatch {
|
class KScopedDisableDispatch {
|
||||||
|
|
|
@ -21,92 +21,38 @@ namespace ams::kern {
|
||||||
|
|
||||||
class KThreadQueue {
|
class KThreadQueue {
|
||||||
private:
|
private:
|
||||||
using Entry = KThread::QueueEntry;
|
KThread::WaiterList wait_list;
|
||||||
private:
|
|
||||||
Entry root;
|
|
||||||
public:
|
public:
|
||||||
constexpr ALWAYS_INLINE KThreadQueue() : root() { /* ... */ }
|
constexpr ALWAYS_INLINE KThreadQueue() : wait_list() { /* ... */ }
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE bool IsEmpty() const { return this->root.GetNext() == nullptr; }
|
bool IsEmpty() const { return this->wait_list.empty(); }
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE KThread *GetFront() const { return this->root.GetNext(); }
|
KThread::WaiterList::iterator begin() { return this->wait_list.begin(); }
|
||||||
constexpr ALWAYS_INLINE KThread *GetNext(KThread *t) const { return t->GetSleepingQueueEntry().GetNext(); }
|
KThread::WaiterList::iterator end() { return this->wait_list.end(); }
|
||||||
private:
|
|
||||||
constexpr ALWAYS_INLINE KThread *GetBack() const { return this->root.GetPrev(); }
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE void Enqueue(KThread *add) {
|
|
||||||
/* Get the entry associated with the added thread. */
|
|
||||||
Entry &add_entry = add->GetSleepingQueueEntry();
|
|
||||||
|
|
||||||
/* Get the entry associated with the end of the queue. */
|
|
||||||
KThread *tail = this->GetBack();
|
|
||||||
Entry &tail_entry = (tail != nullptr) ? tail->GetSleepingQueueEntry() : this->root;
|
|
||||||
|
|
||||||
/* Link the entries. */
|
|
||||||
add_entry.SetPrev(tail);
|
|
||||||
add_entry.SetNext(nullptr);
|
|
||||||
tail_entry.SetNext(add);
|
|
||||||
this->root.SetPrev(add);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE void Remove(KThread *remove) {
|
|
||||||
/* Get the entry associated with the thread. */
|
|
||||||
Entry &remove_entry = remove->GetSleepingQueueEntry();
|
|
||||||
|
|
||||||
/* Get the entries associated with next and prev. */
|
|
||||||
KThread *prev = remove_entry.GetPrev();
|
|
||||||
KThread *next = remove_entry.GetNext();
|
|
||||||
Entry &prev_entry = (prev != nullptr) ? prev->GetSleepingQueueEntry() : this->root;
|
|
||||||
Entry &next_entry = (next != nullptr) ? next->GetSleepingQueueEntry() : this->root;
|
|
||||||
|
|
||||||
/* Unlink. */
|
|
||||||
prev_entry.SetNext(next);
|
|
||||||
next_entry.SetPrev(prev);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
constexpr ALWAYS_INLINE void Dequeue() {
|
|
||||||
/* Get the front of the queue. */
|
|
||||||
KThread *head = this->GetFront();
|
|
||||||
if (head == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MESOSPHERE_ASSERT(head->GetState() == KThread::ThreadState_Waiting);
|
|
||||||
|
|
||||||
/* Get the entry for the next head. */
|
|
||||||
KThread *next = GetNext(head);
|
|
||||||
Entry &next_entry = (next != nullptr) ? next->GetSleepingQueueEntry() : this->root;
|
|
||||||
|
|
||||||
/* Link the entries. */
|
|
||||||
this->root.SetNext(next);
|
|
||||||
next_entry.SetPrev(nullptr);
|
|
||||||
|
|
||||||
/* Clear the head's queue. */
|
|
||||||
head->SetSleepingQueue(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SleepThread(KThread *t) {
|
bool SleepThread(KThread *t) {
|
||||||
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
|
/* If the thread needs terminating, don't enqueue it. */
|
||||||
|
if (t->IsTerminationRequested()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the thread's queue and mark it as waiting. */
|
/* Set the thread's queue and mark it as waiting. */
|
||||||
t->SetSleepingQueue(this);
|
t->SetSleepingQueue(this);
|
||||||
t->SetState(KThread::ThreadState_Waiting);
|
t->SetState(KThread::ThreadState_Waiting);
|
||||||
|
|
||||||
/* Add the thread to the queue. */
|
/* Add the thread to the queue. */
|
||||||
this->Enqueue(t);
|
this->wait_list.push_back(*t);
|
||||||
|
|
||||||
/* If the thread needs terminating, undo our work. */
|
|
||||||
if (t->IsTerminationRequested()) {
|
|
||||||
this->WakeupThread(t);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WakeupThread(KThread *t) {
|
void WakeupThread(KThread *t) {
|
||||||
MESOSPHERE_ASSERT(t->GetState() == KThread::ThreadState_Waiting);
|
KScopedSchedulerLock sl;
|
||||||
|
|
||||||
/* Remove the thread from the queue. */
|
/* Remove the thread from the queue. */
|
||||||
this->Remove(t);
|
this->wait_list.erase(this->wait_list.iterator_to(*t));
|
||||||
|
|
||||||
/* Mark the thread as no longer sleeping. */
|
/* Mark the thread as no longer sleeping. */
|
||||||
t->SetState(KThread::ThreadState_Runnable);
|
t->SetState(KThread::ThreadState_Runnable);
|
||||||
|
@ -114,18 +60,24 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
KThread *WakeupFrontThread() {
|
KThread *WakeupFrontThread() {
|
||||||
KThread *front = this->GetFront();
|
KScopedSchedulerLock sl;
|
||||||
if (front != nullptr) {
|
|
||||||
MESOSPHERE_ASSERT(front->GetState() == KThread::ThreadState_Waiting);
|
|
||||||
|
|
||||||
|
if (this->wait_list.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
} else {
|
||||||
/* Remove the thread from the queue. */
|
/* Remove the thread from the queue. */
|
||||||
this->Dequeue();
|
auto it = this->wait_list.begin();
|
||||||
|
KThread *thread = std::addressof(*it);
|
||||||
|
this->wait_list.erase(it);
|
||||||
|
|
||||||
|
MESOSPHERE_ASSERT(thread->GetState() == KThread::ThreadState_Waiting);
|
||||||
|
|
||||||
/* Mark the thread as no longer sleeping. */
|
/* Mark the thread as no longer sleeping. */
|
||||||
front->SetState(KThread::ThreadState_Runnable);
|
thread->SetState(KThread::ThreadState_Runnable);
|
||||||
front->SetSleepingQueue(nullptr);
|
thread->SetSleepingQueue(nullptr);
|
||||||
|
|
||||||
|
return thread;
|
||||||
}
|
}
|
||||||
return front;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,45 +22,13 @@ namespace ams::kern {
|
||||||
|
|
||||||
class KWaitObject : public KTimerTask {
|
class KWaitObject : public KTimerTask {
|
||||||
private:
|
private:
|
||||||
using Entry = KThread::QueueEntry;
|
KThread::WaiterList wait_list;
|
||||||
private:
|
|
||||||
Entry root;
|
|
||||||
bool timer_used;
|
bool timer_used;
|
||||||
public:
|
public:
|
||||||
constexpr KWaitObject() : root(), timer_used() { /* ... */ }
|
constexpr KWaitObject() : wait_list(), timer_used() { /* ... */ }
|
||||||
|
|
||||||
virtual void OnTimer() override;
|
virtual void OnTimer() override;
|
||||||
Result Synchronize(s64 timeout);
|
Result Synchronize(s64 timeout);
|
||||||
private:
|
|
||||||
constexpr ALWAYS_INLINE void Enqueue(KThread *add) {
|
|
||||||
/* Get the entry associated with the added thread. */
|
|
||||||
Entry &add_entry = add->GetSleepingQueueEntry();
|
|
||||||
|
|
||||||
/* Get the entry associated with the end of the queue. */
|
|
||||||
KThread *tail = this->root.GetPrev();
|
|
||||||
Entry &tail_entry = (tail != nullptr) ? tail->GetSleepingQueueEntry() : this->root;
|
|
||||||
|
|
||||||
/* Link the entries. */
|
|
||||||
add_entry.SetPrev(tail);
|
|
||||||
add_entry.SetNext(nullptr);
|
|
||||||
tail_entry.SetNext(add);
|
|
||||||
this->root.SetPrev(add);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE void Remove(KThread *remove) {
|
|
||||||
/* Get the entry associated with the thread. */
|
|
||||||
Entry &remove_entry = remove->GetSleepingQueueEntry();
|
|
||||||
|
|
||||||
/* Get the entries associated with next and prev. */
|
|
||||||
KThread *prev = remove_entry.GetPrev();
|
|
||||||
KThread *next = remove_entry.GetNext();
|
|
||||||
Entry &prev_entry = (prev != nullptr) ? prev->GetSleepingQueueEntry() : this->root;
|
|
||||||
Entry &next_entry = (next != nullptr) ? next->GetSleepingQueueEntry() : this->root;
|
|
||||||
|
|
||||||
/* Unlink. */
|
|
||||||
prev_entry.SetNext(next);
|
|
||||||
next_entry.SetPrev(prev);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace ams::kern::arch::arm64 {
|
||||||
/* Send KDebug event for this thread's creation. */
|
/* Send KDebug event for this thread's creation. */
|
||||||
{
|
{
|
||||||
KScopedInterruptEnable ei;
|
KScopedInterruptEnable ei;
|
||||||
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()), GetCurrentThread().GetEntrypoint());
|
KDebug::OnDebugEvent(ams::svc::DebugEvent_CreateThread, GetCurrentThread().GetId(), GetInteger(GetCurrentThread().GetThreadLocalRegionAddress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle any pending dpc. */
|
/* Handle any pending dpc. */
|
||||||
|
|
|
@ -327,7 +327,7 @@ namespace ams::kern {
|
||||||
it->SetDebugAttached();
|
it->SetDebugAttached();
|
||||||
|
|
||||||
/* Send the event. */
|
/* Send the event. */
|
||||||
this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()), it->GetEntrypoint());
|
this->PushDebugEvent(ams::svc::DebugEvent_CreateThread, it->GetId(), GetInteger(it->GetThreadLocalRegionAddress()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,7 +682,6 @@ namespace ams::kern {
|
||||||
/* Set the thread creation info. */
|
/* Set the thread creation info. */
|
||||||
info->info.create_thread.thread_id = param0;
|
info->info.create_thread.thread_id = param0;
|
||||||
info->info.create_thread.tls_address = param1;
|
info->info.create_thread.tls_address = param1;
|
||||||
info->info.create_thread.entrypoint = param2;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_ExitProcess:
|
case ams::svc::DebugEvent_ExitProcess:
|
||||||
|
@ -842,7 +841,6 @@ namespace ams::kern {
|
||||||
{
|
{
|
||||||
out->info.create_thread.thread_id = info->info.create_thread.thread_id;
|
out->info.create_thread.thread_id = info->info.create_thread.thread_id;
|
||||||
out->info.create_thread.tls_address = info->info.create_thread.tls_address;
|
out->info.create_thread.tls_address = info->info.create_thread.tls_address;
|
||||||
out->info.create_thread.entrypoint = info->info.create_thread.entrypoint;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ams::svc::DebugEvent_ExitProcess:
|
case ams::svc::DebugEvent_ExitProcess:
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace ams::kern {
|
||||||
/* If we can reply, do so. */
|
/* If we can reply, do so. */
|
||||||
if (!this->current_request->IsTerminationRequested()) {
|
if (!this->current_request->IsTerminationRequested()) {
|
||||||
MESOSPHERE_ASSERT(this->current_request->GetState() == KThread::ThreadState_Waiting);
|
MESOSPHERE_ASSERT(this->current_request->GetState() == KThread::ThreadState_Waiting);
|
||||||
MESOSPHERE_ASSERT(this->current_request == this->request_queue.GetFront());
|
MESOSPHERE_ASSERT(this->request_queue.begin() != this->request_queue.end() && this->current_request == std::addressof(*this->request_queue.begin()));
|
||||||
std::memcpy(this->current_request->GetLightSessionData(), server_thread->GetLightSessionData(), KLightSession::DataSize);
|
std::memcpy(this->current_request->GetLightSessionData(), server_thread->GetLightSessionData(), KLightSession::DataSize);
|
||||||
this->request_queue.WakeupThread(this->current_request);
|
this->request_queue.WakeupThread(this->current_request);
|
||||||
}
|
}
|
||||||
|
@ -110,8 +110,8 @@ namespace ams::kern {
|
||||||
R_UNLESS(!this->parent->IsServerClosed(), svc::ResultSessionClosed());
|
R_UNLESS(!this->parent->IsServerClosed(), svc::ResultSessionClosed());
|
||||||
|
|
||||||
/* If we have a request available, use it. */
|
/* If we have a request available, use it. */
|
||||||
if (this->current_request == nullptr && this->request_queue.IsEmpty()) {
|
if (this->current_request == nullptr && !this->request_queue.IsEmpty()) {
|
||||||
this->current_request = this->request_queue.GetFront();
|
this->current_request = std::addressof(*this->request_queue.begin());
|
||||||
this->current_request->Open();
|
this->current_request->Open();
|
||||||
this->server_thread = server_thread;
|
this->server_thread = server_thread;
|
||||||
break;
|
break;
|
||||||
|
@ -148,7 +148,7 @@ namespace ams::kern {
|
||||||
/* Reply to the current request. */
|
/* Reply to the current request. */
|
||||||
if (!this->current_request->IsTerminationRequested()) {
|
if (!this->current_request->IsTerminationRequested()) {
|
||||||
MESOSPHERE_ASSERT(this->current_request->GetState() == KThread::ThreadState_Waiting);
|
MESOSPHERE_ASSERT(this->current_request->GetState() == KThread::ThreadState_Waiting);
|
||||||
MESOSPHERE_ASSERT(this->current_request == this->request_queue.GetFront());
|
MESOSPHERE_ASSERT(this->request_queue.begin() != this->request_queue.end() && this->current_request == std::addressof(*this->request_queue.begin()));
|
||||||
this->request_queue.WakeupThread(this->current_request);
|
this->request_queue.WakeupThread(this->current_request);
|
||||||
this->current_request->SetSyncedObject(nullptr, svc::ResultSessionClosed());
|
this->current_request->SetSyncedObject(nullptr, svc::ResultSessionClosed());
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Set sync booleans. */
|
/* Set sync booleans. */
|
||||||
this->signaled = false;
|
this->signaled = false;
|
||||||
this->ipc_cancelled = false;
|
|
||||||
this->termination_requested = false;
|
this->termination_requested = false;
|
||||||
this->wait_cancelled = false;
|
this->wait_cancelled = false;
|
||||||
this->cancellable = false;
|
this->cancellable = false;
|
||||||
|
@ -119,7 +118,6 @@ namespace ams::kern {
|
||||||
this->waiting_lock = nullptr;
|
this->waiting_lock = nullptr;
|
||||||
|
|
||||||
/* Initialize sleeping queue. */
|
/* Initialize sleeping queue. */
|
||||||
this->sleeping_queue_entry.Initialize();
|
|
||||||
this->sleeping_queue = nullptr;
|
this->sleeping_queue = nullptr;
|
||||||
|
|
||||||
/* Set suspend flags. */
|
/* Set suspend flags. */
|
||||||
|
@ -141,7 +139,6 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* We have no waiters, but we do have an entrypoint. */
|
/* We have no waiters, but we do have an entrypoint. */
|
||||||
this->num_kernel_waiters = 0;
|
this->num_kernel_waiters = 0;
|
||||||
this->entrypoint = reinterpret_cast<uintptr_t>(func);
|
|
||||||
|
|
||||||
/* Set our current core id. */
|
/* Set our current core id. */
|
||||||
this->current_core_id = core;
|
this->current_core_id = core;
|
||||||
|
@ -172,7 +169,7 @@ namespace ams::kern {
|
||||||
const bool is_64_bit = this->parent ? this->parent->Is64Bit() : IsDefault64Bit;
|
const bool is_64_bit = this->parent ? this->parent->Is64Bit() : IsDefault64Bit;
|
||||||
const bool is_user = (type == ThreadType_User);
|
const bool is_user = (type == ThreadType_User);
|
||||||
const bool is_main = (type == ThreadType_Main);
|
const bool is_main = (type == ThreadType_Main);
|
||||||
this->thread_context.Initialize(this->entrypoint, reinterpret_cast<uintptr_t>(this->GetStackTop()), GetInteger(user_stack_top), arg, is_user, is_64_bit, is_main);
|
this->thread_context.Initialize(reinterpret_cast<uintptr_t>(func), reinterpret_cast<uintptr_t>(this->GetStackTop()), GetInteger(user_stack_top), arg, is_user, is_64_bit, is_main);
|
||||||
|
|
||||||
/* Setup the stack parameters. */
|
/* Setup the stack parameters. */
|
||||||
StackParameters &sp = this->GetStackParameters();
|
StackParameters &sp = this->GetStackParameters();
|
||||||
|
|
|
@ -21,19 +21,8 @@ namespace ams::kern {
|
||||||
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
MESOSPHERE_ASSERT(KScheduler::IsSchedulerLockedByCurrentThread());
|
||||||
|
|
||||||
/* Wake up all the waiting threads. */
|
/* Wake up all the waiting threads. */
|
||||||
Entry *entry = std::addressof(this->root);
|
for (KThread &thread : this->wait_list) {
|
||||||
while (true) {
|
thread.Wakeup();
|
||||||
/* Get the next thread. */
|
|
||||||
KThread *thread = entry->GetNext();
|
|
||||||
if (thread == nullptr) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wake it up. */
|
|
||||||
thread->Wakeup();
|
|
||||||
|
|
||||||
/* Advance. */
|
|
||||||
entry = std::addressof(thread->GetSleepingQueueEntry());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +62,7 @@ namespace ams::kern {
|
||||||
this->OnTimer();
|
this->OnTimer();
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, sleep until the timeout occurs. */
|
/* Otherwise, sleep until the timeout occurs. */
|
||||||
this->Enqueue(cur_thread);
|
this->wait_list.push_back(GetCurrentThread());
|
||||||
cur_thread->SetState(KThread::ThreadState_Waiting);
|
cur_thread->SetState(KThread::ThreadState_Waiting);
|
||||||
cur_thread->SetSyncedObject(nullptr, svc::ResultTimedOut());
|
cur_thread->SetSyncedObject(nullptr, svc::ResultTimedOut());
|
||||||
}
|
}
|
||||||
|
@ -93,7 +82,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Remove the thread from our queue. */
|
/* Remove the thread from our queue. */
|
||||||
if (timeout != 0) {
|
if (timeout != 0) {
|
||||||
this->Remove(cur_thread);
|
this->wait_list.erase(this->wait_list.iterator_to(GetCurrentThread()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace ams::svc {
|
||||||
struct DebugInfoCreateThread {
|
struct DebugInfoCreateThread {
|
||||||
u64 thread_id;
|
u64 thread_id;
|
||||||
u64 tls_address;
|
u64 tls_address;
|
||||||
u64 entrypoint;
|
/* Removed in 11.0.0 u64 entrypoint; */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DebugInfoExitProcess {
|
struct DebugInfoExitProcess {
|
||||||
|
|
Loading…
Reference in a new issue