summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-03-10 13:13:39 -0400
committerGravatar Fernando Sahmkow2020-06-27 11:35:45 -0400
commitd494b074e8afd3aff7b65afc7b977496be06ccc9 (patch)
tree002cc29d32a9b1e44e61fb1aae122715556b36c5 /src
parentCPU_Manager: Unload/Reload threads on preemption on SingleCore (diff)
downloadyuzu-d494b074e8afd3aff7b65afc7b977496be06ccc9.tar.gz
yuzu-d494b074e8afd3aff7b65afc7b977496be06ccc9.tar.xz
yuzu-d494b074e8afd3aff7b65afc7b977496be06ccc9.zip
Kernel: Preempt Single core on redudant yields.
Diffstat (limited to 'src')
-rw-r--r--src/core/cpu_manager.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/kernel.h2
-rw-r--r--src/core/hle/kernel/svc.cpp23
-rw-r--r--src/core/hle/kernel/thread.cpp21
-rw-r--r--src/core/hle/kernel/thread.h9
6 files changed, 42 insertions, 21 deletions
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h
index ff1935d5c..c0e454a7d 100644
--- a/src/core/cpu_manager.h
+++ b/src/core/cpu_manager.h
@@ -45,6 +45,8 @@ public:
45 std::function<void(void*)> GetSuspendThreadStartFunc(); 45 std::function<void(void*)> GetSuspendThreadStartFunc();
46 void* GetStartFuncParamater(); 46 void* GetStartFuncParamater();
47 47
48 void PreemptSingleCore();
49
48 std::size_t CurrentCore() const { 50 std::size_t CurrentCore() const {
49 return current_core.load(); 51 return current_core.load();
50 } 52 }
@@ -71,8 +73,6 @@ private:
71 73
72 void RunThread(std::size_t core); 74 void RunThread(std::size_t core);
73 75
74 void PreemptSingleCore();
75
76 struct CoreData { 76 struct CoreData {
77 std::shared_ptr<Common::Fiber> host_context; 77 std::shared_ptr<Common::Fiber> host_context;
78 std::unique_ptr<Common::Event> enter_barrier; 78 std::unique_ptr<Common::Event> enter_barrier;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 4a091ea38..2a1b91752 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -642,6 +642,10 @@ void KernelCore::Suspend(bool in_suspention) {
642 } 642 }
643} 643}
644 644
645bool KernelCore::IsMulticore() const {
646 return impl->is_multicore;
647}
648
645void KernelCore::ExceptionalExit() { 649void KernelCore::ExceptionalExit() {
646 exception_exited = true; 650 exception_exited = true;
647 Suspend(true); 651 Suspend(true);
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 162bbd2f8..50eeb50ec 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -212,6 +212,8 @@ public:
212 /// Exceptional exit the OS. 212 /// Exceptional exit the OS.
213 void ExceptionalExit(); 213 void ExceptionalExit();
214 214
215 bool IsMulticore() const;
216
215private: 217private:
216 friend class Object; 218 friend class Object;
217 friend class Process; 219 friend class Process;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index aad2ac549..eca92b356 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -19,6 +19,7 @@
19#include "core/core_manager.h" 19#include "core/core_manager.h"
20#include "core/core_timing.h" 20#include "core/core_timing.h"
21#include "core/core_timing_util.h" 21#include "core/core_timing_util.h"
22#include "core/cpu_manager.h"
22#include "core/hle/kernel/address_arbiter.h" 23#include "core/hle/kernel/address_arbiter.h"
23#include "core/hle/kernel/client_port.h" 24#include "core/hle/kernel/client_port.h"
24#include "core/hle/kernel/client_session.h" 25#include "core/hle/kernel/client_session.h"
@@ -1509,21 +1510,31 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
1509 1510
1510 if (nanoseconds <= 0) { 1511 if (nanoseconds <= 0) {
1511 switch (static_cast<SleepType>(nanoseconds)) { 1512 switch (static_cast<SleepType>(nanoseconds)) {
1512 case SleepType::YieldWithoutLoadBalancing: 1513 case SleepType::YieldWithoutLoadBalancing: {
1513 current_thread->YieldSimple(); 1514 auto pair = current_thread->YieldSimple();
1515 is_redundant = pair.second;
1514 break; 1516 break;
1515 case SleepType::YieldWithLoadBalancing: 1517 }
1516 current_thread->YieldAndBalanceLoad(); 1518 case SleepType::YieldWithLoadBalancing: {
1519 auto pair = current_thread->YieldAndBalanceLoad();
1520 is_redundant = pair.second;
1517 break; 1521 break;
1518 case SleepType::YieldAndWaitForLoadBalancing: 1522 }
1519 current_thread->YieldAndWaitForLoadBalancing(); 1523 case SleepType::YieldAndWaitForLoadBalancing: {
1524 auto pair = current_thread->YieldAndWaitForLoadBalancing();
1525 is_redundant = pair.second;
1520 break; 1526 break;
1527 }
1521 default: 1528 default:
1522 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds); 1529 UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
1523 } 1530 }
1524 } else { 1531 } else {
1525 current_thread->Sleep(nanoseconds); 1532 current_thread->Sleep(nanoseconds);
1526 } 1533 }
1534
1535 if (is_redundant && !system.Kernel().IsMulticore()) {
1536 system.GetCpuManager().PreemptSingleCore();
1537 }
1527} 1538}
1528 1539
1529/// Wait process wide key atomic 1540/// Wait process wide key atomic
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index fc6c0bc85..1c32552b1 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -435,28 +435,31 @@ ResultCode Thread::Sleep(s64 nanoseconds) {
435 return RESULT_SUCCESS; 435 return RESULT_SUCCESS;
436} 436}
437 437
438ResultCode Thread::YieldSimple() { 438std::pair<ResultCode, bool> Thread::YieldSimple() {
439 bool is_redundant = false;
439 { 440 {
440 SchedulerLock lock(kernel); 441 SchedulerLock lock(kernel);
441 kernel.GlobalScheduler().YieldThread(this); 442 is_redundant = kernel.GlobalScheduler().YieldThread(this);
442 } 443 }
443 return RESULT_SUCCESS; 444 return {RESULT_SUCCESS, is_redundant};
444} 445}
445 446
446ResultCode Thread::YieldAndBalanceLoad() { 447std::pair<ResultCode, bool> Thread::YieldAndBalanceLoad() {
448 bool is_redundant = false;
447 { 449 {
448 SchedulerLock lock(kernel); 450 SchedulerLock lock(kernel);
449 kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this); 451 is_redundant = kernel.GlobalScheduler().YieldThreadAndBalanceLoad(this);
450 } 452 }
451 return RESULT_SUCCESS; 453 return {RESULT_SUCCESS, is_redundant};
452} 454}
453 455
454ResultCode Thread::YieldAndWaitForLoadBalancing() { 456std::pair<ResultCode, bool> Thread::YieldAndWaitForLoadBalancing() {
457 bool is_redundant = false;
455 { 458 {
456 SchedulerLock lock(kernel); 459 SchedulerLock lock(kernel);
457 kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this); 460 is_redundant = kernel.GlobalScheduler().YieldThreadAndWaitForLoadBalancing(this);
458 } 461 }
459 return RESULT_SUCCESS; 462 return {RESULT_SUCCESS, is_redundant};
460} 463}
461 464
462void Thread::AddSchedulingFlag(ThreadSchedFlags flag) { 465void Thread::AddSchedulingFlag(ThreadSchedFlags flag) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 953b023b5..9a29875ac 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -6,6 +6,7 @@
6 6
7#include <functional> 7#include <functional>
8#include <string> 8#include <string>
9#include <utility>
9#include <vector> 10#include <vector>
10 11
11#include "common/common_types.h" 12#include "common/common_types.h"
@@ -503,13 +504,13 @@ public:
503 ResultCode Sleep(s64 nanoseconds); 504 ResultCode Sleep(s64 nanoseconds);
504 505
505 /// Yields this thread without rebalancing loads. 506 /// Yields this thread without rebalancing loads.
506 ResultCode YieldSimple(); 507 std::pair<ResultCode, bool> YieldSimple();
507 508
508 /// Yields this thread and does a load rebalancing. 509 /// Yields this thread and does a load rebalancing.
509 ResultCode YieldAndBalanceLoad(); 510 std::pair<ResultCode, bool> YieldAndBalanceLoad();
510 511
511 /// Yields this thread and if the core is left idle, loads are rebalanced 512 /// Yields this thread and if the core is left idle, loads are rebalanced
512 ResultCode YieldAndWaitForLoadBalancing(); 513 std::pair<ResultCode, bool> YieldAndWaitForLoadBalancing();
513 514
514 void IncrementYieldCount() { 515 void IncrementYieldCount() {
515 yield_count++; 516 yield_count++;
@@ -587,7 +588,7 @@ private:
587 ThreadContext32 context_32{}; 588 ThreadContext32 context_32{};
588 ThreadContext64 context_64{}; 589 ThreadContext64 context_64{};
589 Common::SpinLock context_guard{}; 590 Common::SpinLock context_guard{};
590 std::shared_ptr<Common::Fiber> host_context{}; 591 std::shared_ptr<Common::Fiber> host_context{};
591 592
592 u64 thread_id = 0; 593 u64 thread_id = 0;
593 594