CoreTiming: Pull globals into a single struct

This commit is contained in:
MerryMage 2017-04-05 10:13:30 +01:00
parent dc2d11c1a7
commit 38917a151d
4 changed files with 44 additions and 44 deletions

View File

@ -65,8 +65,6 @@ static std::mutex s_ts_write_lock;
static Common::FifoQueue<Event, false> s_ts_queue; static Common::FifoQueue<Event, false> s_ts_queue;
static float s_last_OC_factor; static float s_last_OC_factor;
float g_last_OC_factor_inverted;
int g_slice_length;
static constexpr int MAX_SLICE_LENGTH = 20000; static constexpr int MAX_SLICE_LENGTH = 20000;
static s64 s_idled_cycles; static s64 s_idled_cycles;
@ -76,9 +74,7 @@ static u64 s_fake_dec_start_ticks;
// Are we in a function that has been called from Advance() // Are we in a function that has been called from Advance()
static bool s_is_global_timer_sane; static bool s_is_global_timer_sane;
s64 g_global_timer; Globals g;
u64 g_fake_TB_start_value;
u64 g_fake_TB_start_ticks;
static EventType* s_ev_lost = nullptr; static EventType* s_ev_lost = nullptr;
@ -95,7 +91,7 @@ static void EmptyTimedCallback(u64 userdata, s64 cyclesLate)
// but the effect is largely the same. // but the effect is largely the same.
static int DowncountToCycles(int downcount) static int DowncountToCycles(int downcount)
{ {
return static_cast<int>(downcount * g_last_OC_factor_inverted); return static_cast<int>(downcount * g.last_OC_factor_inverted);
} }
static int CyclesToDowncount(int cycles) static int CyclesToDowncount(int cycles)
@ -127,10 +123,10 @@ void UnregisterAllEvents()
void Init() void Init()
{ {
s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
g_last_OC_factor_inverted = 1.0f / s_last_OC_factor; g.last_OC_factor_inverted = 1.0f / s_last_OC_factor;
PowerPC::ppcState.downcount = CyclesToDowncount(MAX_SLICE_LENGTH); PowerPC::ppcState.downcount = CyclesToDowncount(MAX_SLICE_LENGTH);
g_slice_length = MAX_SLICE_LENGTH; g.slice_length = MAX_SLICE_LENGTH;
g_global_timer = 0; g.global_timer = 0;
s_idled_cycles = 0; s_idled_cycles = 0;
// The time between CoreTiming being intialized and the first call to Advance() is considered // The time between CoreTiming being intialized and the first call to Advance() is considered
@ -154,15 +150,15 @@ void Shutdown()
void DoState(PointerWrap& p) void DoState(PointerWrap& p)
{ {
std::lock_guard<std::mutex> lk(s_ts_write_lock); std::lock_guard<std::mutex> lk(s_ts_write_lock);
p.Do(g_slice_length); p.Do(g.slice_length);
p.Do(g_global_timer); p.Do(g.global_timer);
p.Do(s_idled_cycles); p.Do(s_idled_cycles);
p.Do(s_fake_dec_start_value); p.Do(s_fake_dec_start_value);
p.Do(s_fake_dec_start_ticks); p.Do(s_fake_dec_start_ticks);
p.Do(g_fake_TB_start_value); p.Do(g.fake_TB_start_value);
p.Do(g_fake_TB_start_ticks); p.Do(g.fake_TB_start_ticks);
p.Do(s_last_OC_factor); p.Do(s_last_OC_factor);
g_last_OC_factor_inverted = 1.0f / s_last_OC_factor; g.last_OC_factor_inverted = 1.0f / s_last_OC_factor;
p.Do(s_event_fifo_id); p.Do(s_event_fifo_id);
p.DoMarker("CoreTimingData"); p.DoMarker("CoreTimingData");
@ -212,11 +208,11 @@ void DoState(PointerWrap& p)
// it from any other thread, you are doing something evil // it from any other thread, you are doing something evil
u64 GetTicks() u64 GetTicks()
{ {
u64 ticks = static_cast<u64>(g_global_timer); u64 ticks = static_cast<u64>(g.global_timer);
if (!s_is_global_timer_sane) if (!s_is_global_timer_sane)
{ {
int downcount = DowncountToCycles(PowerPC::ppcState.downcount); int downcount = DowncountToCycles(PowerPC::ppcState.downcount);
ticks += g_slice_length - downcount; ticks += g.slice_length - downcount;
} }
return ticks; return ticks;
} }
@ -268,7 +264,7 @@ void ScheduleEvent(s64 cycles_into_future, EventType* event_type, u64 userdata,
} }
std::lock_guard<std::mutex> lk(s_ts_write_lock); std::lock_guard<std::mutex> lk(s_ts_write_lock);
s_ts_queue.Push(Event{g_global_timer + cycles_into_future, 0, userdata, event_type}); s_ts_queue.Push(Event{g.global_timer + cycles_into_future, 0, userdata, event_type});
} }
} }
@ -297,8 +293,8 @@ void ForceExceptionCheck(s64 cycles)
if (DowncountToCycles(PowerPC::ppcState.downcount) > cycles) if (DowncountToCycles(PowerPC::ppcState.downcount) > cycles)
{ {
// downcount is always (much) smaller than MAX_INT so we can safely cast cycles to an int here. // 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 // Account for cycles already executed by adjusting the g.slice_length
g_slice_length -= DowncountToCycles(PowerPC::ppcState.downcount) - static_cast<int>(cycles); g.slice_length -= DowncountToCycles(PowerPC::ppcState.downcount) - static_cast<int>(cycles);
PowerPC::ppcState.downcount = CyclesToDowncount(static_cast<int>(cycles)); PowerPC::ppcState.downcount = CyclesToDowncount(static_cast<int>(cycles));
} }
} }
@ -317,22 +313,22 @@ void Advance()
{ {
MoveEvents(); MoveEvents();
int cyclesExecuted = g_slice_length - DowncountToCycles(PowerPC::ppcState.downcount); int cyclesExecuted = g.slice_length - DowncountToCycles(PowerPC::ppcState.downcount);
g_global_timer += cyclesExecuted; g.global_timer += cyclesExecuted;
s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f; s_last_OC_factor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
g_last_OC_factor_inverted = 1.0f / s_last_OC_factor; g.last_OC_factor_inverted = 1.0f / s_last_OC_factor;
g_slice_length = MAX_SLICE_LENGTH; g.slice_length = MAX_SLICE_LENGTH;
s_is_global_timer_sane = true; s_is_global_timer_sane = true;
while (!s_event_queue.empty() && s_event_queue.front().time <= g_global_timer) while (!s_event_queue.empty() && s_event_queue.front().time <= g.global_timer)
{ {
Event evt = std::move(s_event_queue.front()); Event evt = std::move(s_event_queue.front());
std::pop_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>()); std::pop_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>());
s_event_queue.pop_back(); s_event_queue.pop_back();
// NOTICE_LOG(POWERPC, "[Scheduler] %-20s (%lld, %lld)", evt.type->name->c_str(), // NOTICE_LOG(POWERPC, "[Scheduler] %-20s (%lld, %lld)", evt.type->name->c_str(),
// g_global_timer, evt.time); // g.global_timer, evt.time);
evt.type->callback(evt.userdata, g_global_timer - evt.time); evt.type->callback(evt.userdata, g.global_timer - evt.time);
} }
s_is_global_timer_sane = false; s_is_global_timer_sane = false;
@ -340,11 +336,11 @@ void Advance()
// Still events left (scheduled in the future) // Still events left (scheduled in the future)
if (!s_event_queue.empty()) if (!s_event_queue.empty())
{ {
g_slice_length = static_cast<int>( g.slice_length = static_cast<int>(
std::min<s64>(s_event_queue.front().time - g_global_timer, MAX_SLICE_LENGTH)); std::min<s64>(s_event_queue.front().time - g.global_timer, MAX_SLICE_LENGTH));
} }
PowerPC::ppcState.downcount = CyclesToDowncount(g_slice_length); PowerPC::ppcState.downcount = CyclesToDowncount(g.slice_length);
// Check for any external exceptions. // Check for any external exceptions.
// It's important to do this after processing events otherwise any exceptions will be delayed // It's important to do this after processing events otherwise any exceptions will be delayed
@ -359,7 +355,7 @@ void LogPendingEvents()
std::sort(clone.begin(), clone.end()); std::sort(clone.begin(), clone.end());
for (const Event& ev : clone) for (const Event& ev : clone)
{ {
INFO_LOG(POWERPC, "PENDING: Now: %" PRId64 " Pending: %" PRId64 " Type: %s", g_global_timer, INFO_LOG(POWERPC, "PENDING: Now: %" PRId64 " Pending: %" PRId64 " Type: %s", g.global_timer,
ev.time, ev.type->name->c_str()); ev.time, ev.type->name->c_str());
} }
} }
@ -369,8 +365,8 @@ void AdjustEventQueueTimes(u32 new_ppc_clock, u32 old_ppc_clock)
{ {
for (Event& ev : s_event_queue) for (Event& ev : s_event_queue)
{ {
const s64 ticks = (ev.time - g_global_timer) * new_ppc_clock / old_ppc_clock; const s64 ticks = (ev.time - g.global_timer) * new_ppc_clock / old_ppc_clock;
ev.time = g_global_timer + ticks; ev.time = g.global_timer + ticks;
} }
} }
@ -425,22 +421,22 @@ void SetFakeDecStartTicks(u64 val)
u64 GetFakeTBStartValue() u64 GetFakeTBStartValue()
{ {
return g_fake_TB_start_value; return g.fake_TB_start_value;
} }
void SetFakeTBStartValue(u64 val) void SetFakeTBStartValue(u64 val)
{ {
g_fake_TB_start_value = val; g.fake_TB_start_value = val;
} }
u64 GetFakeTBStartTicks() u64 GetFakeTBStartTicks()
{ {
return g_fake_TB_start_ticks; return g.fake_TB_start_ticks;
} }
void SetFakeTBStartTicks(u64 val) void SetFakeTBStartTicks(u64 val)
{ {
g_fake_TB_start_ticks = val; g.fake_TB_start_ticks = val;
} }
} // namespace } // namespace

View File

@ -25,11 +25,15 @@ class PointerWrap;
namespace CoreTiming namespace CoreTiming
{ {
// These really shouldn't be global, but jit64 accesses them directly // These really shouldn't be global, but jit64 accesses them directly
extern s64 g_global_timer; struct Globals
extern u64 g_fake_TB_start_value; {
extern u64 g_fake_TB_start_ticks; s64 global_timer;
extern int g_slice_length; u64 fake_TB_start_value;
extern float g_last_OC_factor_inverted; u64 fake_TB_start_ticks;
int slice_length;
float last_OC_factor_inverted;
};
extern Globals g;
// CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is // CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is
// required to end slice -1 and start slice 0 before the first cycle of code is executed. // required to end slice -1 and start slice 0 before the first cycle of code is executed.

View File

@ -203,7 +203,7 @@ void Interpreter::SingleStep()
SingleStepInner(); SingleStepInner();
// The interpreter ignores instruction timing information outside the 'fast runloop'. // The interpreter ignores instruction timing information outside the 'fast runloop'.
CoreTiming::g_slice_length = 1; CoreTiming::g.slice_length = 1;
PowerPC::ppcState.downcount = 0; PowerPC::ppcState.downcount = 0;
if (PowerPC::ppcState.Exceptions) if (PowerPC::ppcState.Exceptions)

View File

@ -253,9 +253,9 @@ TEST(CoreTiming, ScheduleIntoPast)
// the stale value, i.e. effectively half-way through the previous slice. // the stale value, i.e. effectively half-way through the previous slice.
// NOTE: We're only testing that the scheduler doesn't break, not whether this makes sense. // NOTE: We're only testing that the scheduler doesn't break, not whether this makes sense.
Core::UndeclareAsCPUThread(); Core::UndeclareAsCPUThread();
CoreTiming::g_global_timer -= 1000; CoreTiming::g.global_timer -= 1000;
CoreTiming::ScheduleEvent(0, cb_b, CB_IDS[1], CoreTiming::FromThread::NON_CPU); CoreTiming::ScheduleEvent(0, cb_b, CB_IDS[1], CoreTiming::FromThread::NON_CPU);
CoreTiming::g_global_timer += 1000; CoreTiming::g.global_timer += 1000;
Core::DeclareAsCPUThread(); Core::DeclareAsCPUThread();
AdvanceAndCheck(1, MAX_SLICE_LENGTH, MAX_SLICE_LENGTH + 1000); AdvanceAndCheck(1, MAX_SLICE_LENGTH, MAX_SLICE_LENGTH + 1000);