fixup! CoreTiming: Keep Cores synced by having each core it's own downcount and let the main core run an intermediate run if it's slice_length was cropped
This commit is contained in:
@@ -25,7 +25,7 @@ void CpuBarrier::NotifyEnd() {
|
||||
condition.notify_all();
|
||||
}
|
||||
|
||||
bool CpuBarrier::Rendezvous() {
|
||||
bool CpuBarrier::Rendezvous(bool main_core) {
|
||||
if (!Settings::values.use_multi_core) {
|
||||
// Meaningless when running in single-core mode
|
||||
return true;
|
||||
@@ -36,7 +36,7 @@ bool CpuBarrier::Rendezvous() {
|
||||
|
||||
--cores_waiting;
|
||||
if (!cores_waiting) {
|
||||
if (CoreTiming::MainSliceWasCropped() && IsMainCore()) {
|
||||
if (CoreTiming::MainSliceWasCropped() && main_core) {
|
||||
// This is the main thread but we were cropped, so just continue;
|
||||
++cores_waiting;
|
||||
return true;
|
||||
@@ -46,7 +46,7 @@ bool CpuBarrier::Rendezvous() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CoreTiming::MainSliceWasCropped() && IsMainCore()) {
|
||||
if (CoreTiming::MainSliceWasCropped() && main_core) {
|
||||
// This is the main thread but we were cropped, so just continue;
|
||||
++cores_waiting;
|
||||
return true;
|
||||
@@ -90,7 +90,7 @@ std::shared_ptr<ExclusiveMonitor> Cpu::MakeExclusiveMonitor(size_t num_cores) {
|
||||
|
||||
void Cpu::RunLoop(bool tight_loop) {
|
||||
// Wait for all other CPU cores to complete the previous slice, such that they run in lock-step
|
||||
if (!cpu_barrier->Rendezvous()) {
|
||||
if (!cpu_barrier->Rendezvous(IsMainCore())) {
|
||||
// If rendezvous failed, session has been killed
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public:
|
||||
|
||||
void NotifyEnd();
|
||||
|
||||
bool Rendezvous();
|
||||
bool Rendezvous(bool main_core);
|
||||
|
||||
private:
|
||||
unsigned cores_waiting{NUM_CPU_CORES};
|
||||
|
||||
@@ -93,7 +93,7 @@ void UnregisterAllEvents() {
|
||||
|
||||
void Init() {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
std::fill(downcount.begin(), downcount.end(), MAX_SLICE_LENGTH);
|
||||
downcount.fill(MAX_SLICE_LENGTH);
|
||||
slice_length = MAX_SLICE_LENGTH;
|
||||
next_slice_length = MAX_SLICE_LENGTH;
|
||||
global_timer = 0;
|
||||
@@ -183,8 +183,7 @@ void ForceExceptionCheck(s64 cycles) {
|
||||
if (downcount[0] > cycles) {
|
||||
// downcount is always (much) smaller than MAX_INT so we can safely cast cycles to an int
|
||||
// here. Account for cycles already executed by adjusting the g.slice_length
|
||||
s64 crop_time = downcount[0] - static_cast<int>(cycles);
|
||||
slice_length -= crop_time;
|
||||
slice_length -= downcount[0] - static_cast<int>(cycles);
|
||||
downcount[0] = static_cast<int>(cycles);
|
||||
if (next_slice_length <= 0)
|
||||
next_slice_length = MAX_SLICE_LENGTH;
|
||||
@@ -201,7 +200,7 @@ void MoveEvents() {
|
||||
|
||||
void Advance() {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
size_t current_core = Core::System::GetInstance().CurrentCoreIndex();
|
||||
const size_t current_core = Core::System::GetInstance().CurrentCoreIndex();
|
||||
if (current_core != 0) {
|
||||
downcount[current_core] = MAX_SLICE_LENGTH;
|
||||
return;
|
||||
|
||||
@@ -81,6 +81,7 @@ void MoveEvents();
|
||||
/// Pretend that the main CPU has executed enough cycles to reach the next event.
|
||||
void Idle();
|
||||
|
||||
/// Checks if the Main Core executed less then MAX_SLICE_LENGTH
|
||||
bool MainSliceWasCropped();
|
||||
|
||||
/// Clear all pending events. This should ONLY be done on exit.
|
||||
|
||||
Reference in New Issue
Block a user