Skip to content

Commit

Permalink
CoreTiming: Document initial startup behavior
Browse files Browse the repository at this point in the history
Events don't update the downcount until after the first Advance(),
thus Advance() must be called once before scheduling works normally.
  • Loading branch information
EmptyChaos committed Sep 3, 2016
1 parent 5946591 commit fb55372
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Source/Core/Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ void Init()
g_slice_length = MAX_SLICE_LENGTH;
g_global_timer = 0;
s_idled_cycles = 0;

// The time between CoreTiming being intialized and the first call to Advance() is considered
// the slice boundary between slice -1 and slice 0. Dispatcher loops must call Advance() before
// executing the first PPC cycle of each slice to prepare the slice length and downcount for
// that slice.
s_is_global_timer_sane = true;

s_ev_lost = RegisterEvent("_lost_event", &EmptyTimedCallback);
Expand Down
12 changes: 12 additions & 0 deletions Source/Core/Core/CoreTiming.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extern u64 g_fake_TB_start_ticks;
extern int g_slice_length;
extern float g_last_OC_factor_inverted;

// 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.
void Init();
void Shutdown();

Expand Down Expand Up @@ -60,12 +62,22 @@ enum class FromThread
};

// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from savestates.
// After the first Advance, the slice lengths and the downcount will be reduced whenever an event
// is scheduled earlier than the current values (when scheduled from the CPU Thread only).
// Scheduling from a callback will not update the downcount until the Advance() completes.
void ScheduleEvent(s64 cycles_into_future, EventType* event_type, u64 userdata = 0,
FromThread from = FromThread::CPU);

// We only permit one event of each type in the queue at a time.
void RemoveEvent(EventType* event_type);
void RemoveAllEvents(EventType* event_type);

// Advance must be called at the beginning of dispatcher loops, not the end. Advance() ends
// the previous timing slice and begins the next one, you must Advance from the previous
// slice to the current one before executing any cycles. CoreTiming starts in slice -1 so an
// Advance() is required to initialize the slice length before the first cycle of emulated
// instructions is executed.
// NOTE: Advance updates the PowerPC downcount and performs a PPC external exception check.
void Advance();
void MoveEvents();

Expand Down

0 comments on commit fb55372

Please sign in to comment.