early-access version 3046
This commit is contained in:
@@ -49,4 +49,19 @@ bool GlobalSchedulerContext::IsLocked() const {
|
||||
return scheduler_lock.IsLockedByCurrentThread();
|
||||
}
|
||||
|
||||
void GlobalSchedulerContext::RegisterDummyThreadForWakeup(KThread* thread) {
|
||||
ASSERT(IsLocked());
|
||||
woken_dummy_thread_list.push_back(thread);
|
||||
}
|
||||
|
||||
void GlobalSchedulerContext::WakeupWaitingDummyThreads() {
|
||||
ASSERT(IsLocked());
|
||||
|
||||
for (auto* thread : woken_dummy_thread_list) {
|
||||
thread->IfDummyThreadEndWait();
|
||||
}
|
||||
|
||||
woken_dummy_thread_list.clear();
|
||||
}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
/// Returns true if the global scheduler lock is acquired
|
||||
bool IsLocked() const;
|
||||
|
||||
void RegisterDummyThreadForWakeup(KThread* thread);
|
||||
void WakeupWaitingDummyThreads();
|
||||
|
||||
[[nodiscard]] LockType& SchedulerLock() {
|
||||
return scheduler_lock;
|
||||
}
|
||||
@@ -76,6 +79,9 @@ private:
|
||||
KSchedulerPriorityQueue priority_queue;
|
||||
LockType scheduler_lock;
|
||||
|
||||
/// Lists dummy threads pending wakeup on lock release
|
||||
std::vector<KThread*> woken_dummy_thread_list;
|
||||
|
||||
/// Lists all thread ids that aren't deleted/etc.
|
||||
std::vector<KThread*> thread_list;
|
||||
std::mutex global_list_guard;
|
||||
|
||||
@@ -314,6 +314,9 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
|
||||
idle_cores &= ~(1ULL << core_id);
|
||||
}
|
||||
|
||||
// HACK: any waiting dummy threads can wake up now.
|
||||
kernel.GlobalSchedulerContext().WakeupWaitingDummyThreads();
|
||||
|
||||
return cores_needing_scheduling;
|
||||
}
|
||||
|
||||
@@ -536,6 +539,12 @@ void KScheduler::OnThreadStateChanged(KernelCore& kernel, KThread* thread, Threa
|
||||
GetPriorityQueue(kernel).PushBack(thread);
|
||||
IncrementScheduledCount(thread);
|
||||
SetSchedulerUpdateNeeded(kernel);
|
||||
|
||||
if (thread->IsDummyThread()) {
|
||||
// HACK: if this is a dummy thread, it should wake up when the scheduler
|
||||
// lock is released.
|
||||
kernel.GlobalSchedulerContext().RegisterDummyThreadForWakeup(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
|
||||
physical_affinity_mask.SetAffinity(phys_core, true);
|
||||
|
||||
// Set the thread state.
|
||||
thread_state = (type == ThreadType::Main) ? ThreadState::Runnable : ThreadState::Initialized;
|
||||
thread_state = (type == ThreadType::Main || type == ThreadType::Dummy)
|
||||
? ThreadState::Runnable
|
||||
: ThreadState::Initialized;
|
||||
|
||||
// Set TLS address.
|
||||
tls_address = 0;
|
||||
@@ -1231,9 +1233,6 @@ void KThread::EndWait(Result wait_result_) {
|
||||
}
|
||||
|
||||
wait_queue->EndWait(this, wait_result_);
|
||||
|
||||
// Special case for dummy threads to wakeup if necessary.
|
||||
IfDummyThreadEndWait();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ namespace Kernel {
|
||||
|
||||
struct KernelCore::Impl {
|
||||
explicit Impl(Core::System& system_, KernelCore& kernel_)
|
||||
: time_manager{system_},
|
||||
service_threads_manager{1, "ServiceThreadsManager"}, system{system_} {}
|
||||
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
|
||||
service_thread_barrier{2}, system{system_} {}
|
||||
|
||||
void SetMulticore(bool is_multi) {
|
||||
is_multicore = is_multi;
|
||||
@@ -737,7 +737,12 @@ struct KernelCore::Impl {
|
||||
}
|
||||
|
||||
void ClearServiceThreads() {
|
||||
service_threads_manager.QueueWork([this]() { service_threads.clear(); });
|
||||
service_threads_manager.QueueWork([this] {
|
||||
service_threads.clear();
|
||||
default_service_thread.reset();
|
||||
service_thread_barrier.Sync();
|
||||
});
|
||||
service_thread_barrier.Sync();
|
||||
}
|
||||
|
||||
std::mutex server_objects_lock;
|
||||
@@ -802,6 +807,7 @@ struct KernelCore::Impl {
|
||||
std::unordered_set<std::shared_ptr<ServiceThread>> service_threads;
|
||||
std::weak_ptr<ServiceThread> default_service_thread;
|
||||
Common::ThreadWorker service_threads_manager;
|
||||
Common::Barrier service_thread_barrier;
|
||||
|
||||
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads;
|
||||
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
|
||||
|
||||
@@ -751,8 +751,8 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
|
||||
}
|
||||
|
||||
system.GetReporter().SaveSvcBreakReport(
|
||||
static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger, info1,
|
||||
info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
|
||||
static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger.As<bool>(),
|
||||
info1, info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
|
||||
|
||||
if (!break_reason.signal_debugger) {
|
||||
LOG_CRITICAL(
|
||||
|
||||
Reference in New Issue
Block a user