@ -31,10 +31,10 @@ void CallbackTemplate(u64 userdata, s64 cycles_late) {
class ScopeInit final {
class ScopeInit final {
public :
public :
ScopeInit ( ) {
ScopeInit ( ) {
Core Timing: : Init ( ) ;
Core : : Timing: : Init ( ) ;
}
}
~ ScopeInit ( ) {
~ ScopeInit ( ) {
Core Timing: : Shutdown ( ) ;
Core : : Timing: : Shutdown ( ) ;
}
}
} ;
} ;
@ -44,37 +44,37 @@ static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0,
expected_callback = CB_IDS [ idx ] ;
expected_callback = CB_IDS [ idx ] ;
lateness = expected_lateness ;
lateness = expected_lateness ;
CoreTiming : : AddTicks ( CoreTiming : : GetDowncount ( ) -
// Pretend we executed X cycles of instructions.
cpu_downcount ) ; // Pretend we executed X cycles of instructions.
Core : : Timing : : AddTicks ( Core : : Timing : : GetDowncount ( ) - cpu_downcount ) ;
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
REQUIRE ( decltype ( callbacks_ran_flags ) ( ) . set ( idx ) = = callbacks_ran_flags ) ;
REQUIRE ( decltype ( callbacks_ran_flags ) ( ) . set ( idx ) = = callbacks_ran_flags ) ;
REQUIRE ( downcount = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( downcount = = Core : : Timing: : GetDowncount ( ) ) ;
}
}
TEST_CASE ( " CoreTiming[BasicOrder] " , " [core] " ) {
TEST_CASE ( " CoreTiming[BasicOrder] " , " [core] " ) {
ScopeInit guard ;
ScopeInit guard ;
Core Timing: : EventType * cb_a = Core Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core : : Timing: : EventType * cb_a = Core : : Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core Timing: : EventType * cb_b = Core Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core : : Timing: : EventType * cb_b = Core : : Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core Timing: : EventType * cb_c = Core Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core : : Timing: : EventType * cb_c = Core : : Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core Timing: : EventType * cb_d = Core Timing: : RegisterEvent ( " callbackD " , CallbackTemplate < 3 > ) ;
Core : : Timing: : EventType * cb_d = Core : : Timing: : RegisterEvent ( " callbackD " , CallbackTemplate < 3 > ) ;
Core Timing: : EventType * cb_e = Core Timing: : RegisterEvent ( " callbackE " , CallbackTemplate < 4 > ) ;
Core : : Timing: : EventType * cb_e = Core : : Timing: : RegisterEvent ( " callbackE " , CallbackTemplate < 4 > ) ;
// Enter slice 0
// Enter slice 0
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
// D -> B -> C -> A -> E
// D -> B -> C -> A -> E
Core Timing: : ScheduleEvent ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
REQUIRE ( 1000 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 1000 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEvent ( 500 , cb_b , CB_IDS [ 1 ] ) ;
Core : : Timing: : ScheduleEvent ( 500 , cb_b , CB_IDS [ 1 ] ) ;
REQUIRE ( 500 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 500 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEvent ( 800 , cb_c , CB_IDS [ 2 ] ) ;
Core : : Timing: : ScheduleEvent ( 800 , cb_c , CB_IDS [ 2 ] ) ;
REQUIRE ( 500 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 500 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEvent ( 100 , cb_d , CB_IDS [ 3 ] ) ;
Core : : Timing: : ScheduleEvent ( 100 , cb_d , CB_IDS [ 3 ] ) ;
REQUIRE ( 100 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 100 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEvent ( 1200 , cb_e , CB_IDS [ 4 ] ) ;
Core : : Timing: : ScheduleEvent ( 1200 , cb_e , CB_IDS [ 4 ] ) ;
REQUIRE ( 100 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 100 = = Core : : Timing: : GetDowncount ( ) ) ;
AdvanceAndCheck ( 3 , 400 ) ;
AdvanceAndCheck ( 3 , 400 ) ;
AdvanceAndCheck ( 1 , 300 ) ;
AdvanceAndCheck ( 1 , 300 ) ;
@ -86,36 +86,36 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
TEST_CASE ( " CoreTiming[Threadsave] " , " [core] " ) {
TEST_CASE ( " CoreTiming[Threadsave] " , " [core] " ) {
ScopeInit guard ;
ScopeInit guard ;
Core Timing: : EventType * cb_a = Core Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core : : Timing: : EventType * cb_a = Core : : Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core Timing: : EventType * cb_b = Core Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core : : Timing: : EventType * cb_b = Core : : Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core Timing: : EventType * cb_c = Core Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core : : Timing: : EventType * cb_c = Core : : Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core Timing: : EventType * cb_d = Core Timing: : RegisterEvent ( " callbackD " , CallbackTemplate < 3 > ) ;
Core : : Timing: : EventType * cb_d = Core : : Timing: : RegisterEvent ( " callbackD " , CallbackTemplate < 3 > ) ;
Core Timing: : EventType * cb_e = Core Timing: : RegisterEvent ( " callbackE " , CallbackTemplate < 4 > ) ;
Core : : Timing: : EventType * cb_e = Core : : Timing: : RegisterEvent ( " callbackE " , CallbackTemplate < 4 > ) ;
// Enter slice 0
// Enter slice 0
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
// D -> B -> C -> A -> E
// D -> B -> C -> A -> E
Core Timing: : ScheduleEventThreadsafe ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
Core : : Timing: : ScheduleEventThreadsafe ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
// Manually force since ScheduleEventThreadsafe doesn't call it
// Manually force since ScheduleEventThreadsafe doesn't call it
Core Timing: : ForceExceptionCheck ( 1000 ) ;
Core : : Timing: : ForceExceptionCheck ( 1000 ) ;
REQUIRE ( 1000 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 1000 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEventThreadsafe ( 500 , cb_b , CB_IDS [ 1 ] ) ;
Core : : Timing: : ScheduleEventThreadsafe ( 500 , cb_b , CB_IDS [ 1 ] ) ;
// Manually force since ScheduleEventThreadsafe doesn't call it
// Manually force since ScheduleEventThreadsafe doesn't call it
Core Timing: : ForceExceptionCheck ( 500 ) ;
Core : : Timing: : ForceExceptionCheck ( 500 ) ;
REQUIRE ( 500 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 500 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEventThreadsafe ( 800 , cb_c , CB_IDS [ 2 ] ) ;
Core : : Timing: : ScheduleEventThreadsafe ( 800 , cb_c , CB_IDS [ 2 ] ) ;
// Manually force since ScheduleEventThreadsafe doesn't call it
// Manually force since ScheduleEventThreadsafe doesn't call it
Core Timing: : ForceExceptionCheck ( 800 ) ;
Core : : Timing: : ForceExceptionCheck ( 800 ) ;
REQUIRE ( 500 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 500 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEventThreadsafe ( 100 , cb_d , CB_IDS [ 3 ] ) ;
Core : : Timing: : ScheduleEventThreadsafe ( 100 , cb_d , CB_IDS [ 3 ] ) ;
// Manually force since ScheduleEventThreadsafe doesn't call it
// Manually force since ScheduleEventThreadsafe doesn't call it
Core Timing: : ForceExceptionCheck ( 100 ) ;
Core : : Timing: : ForceExceptionCheck ( 100 ) ;
REQUIRE ( 100 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 100 = = Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : ScheduleEventThreadsafe ( 1200 , cb_e , CB_IDS [ 4 ] ) ;
Core : : Timing: : ScheduleEventThreadsafe ( 1200 , cb_e , CB_IDS [ 4 ] ) ;
// Manually force since ScheduleEventThreadsafe doesn't call it
// Manually force since ScheduleEventThreadsafe doesn't call it
Core Timing: : ForceExceptionCheck ( 1200 ) ;
Core : : Timing: : ForceExceptionCheck ( 1200 ) ;
REQUIRE ( 100 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 100 = = Core : : Timing: : GetDowncount ( ) ) ;
AdvanceAndCheck ( 3 , 400 ) ;
AdvanceAndCheck ( 3 , 400 ) ;
AdvanceAndCheck ( 1 , 300 ) ;
AdvanceAndCheck ( 1 , 300 ) ;
@ -143,42 +143,42 @@ TEST_CASE("CoreTiming[SharedSlot]", "[core]") {
ScopeInit guard ;
ScopeInit guard ;
Core Timing: : EventType * cb_a = Core Timing: : RegisterEvent ( " callbackA " , FifoCallback < 0 > ) ;
Core : : Timing: : EventType * cb_a = Core : : Timing: : RegisterEvent ( " callbackA " , FifoCallback < 0 > ) ;
Core Timing: : EventType * cb_b = Core Timing: : RegisterEvent ( " callbackB " , FifoCallback < 1 > ) ;
Core : : Timing: : EventType * cb_b = Core : : Timing: : RegisterEvent ( " callbackB " , FifoCallback < 1 > ) ;
Core Timing: : EventType * cb_c = Core Timing: : RegisterEvent ( " callbackC " , FifoCallback < 2 > ) ;
Core : : Timing: : EventType * cb_c = Core : : Timing: : RegisterEvent ( " callbackC " , FifoCallback < 2 > ) ;
Core Timing: : EventType * cb_d = Core Timing: : RegisterEvent ( " callbackD " , FifoCallback < 3 > ) ;
Core : : Timing: : EventType * cb_d = Core : : Timing: : RegisterEvent ( " callbackD " , FifoCallback < 3 > ) ;
Core Timing: : EventType * cb_e = Core Timing: : RegisterEvent ( " callbackE " , FifoCallback < 4 > ) ;
Core : : Timing: : EventType * cb_e = Core : : Timing: : RegisterEvent ( " callbackE " , FifoCallback < 4 > ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_a , CB_IDS [ 0 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_b , CB_IDS [ 1 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_b , CB_IDS [ 1 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_c , CB_IDS [ 2 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_c , CB_IDS [ 2 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_d , CB_IDS [ 3 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_d , CB_IDS [ 3 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_e , CB_IDS [ 4 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_e , CB_IDS [ 4 ] ) ;
// Enter slice 0
// Enter slice 0
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
REQUIRE ( 1000 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 1000 = = Core : : Timing: : GetDowncount ( ) ) ;
callbacks_ran_flags = 0 ;
callbacks_ran_flags = 0 ;
counter = 0 ;
counter = 0 ;
lateness = 0 ;
lateness = 0 ;
Core Timing: : AddTicks ( Core Timing: : GetDowncount ( ) ) ;
Core : : Timing: : AddTicks ( Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
REQUIRE ( MAX_SLICE_LENGTH = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( MAX_SLICE_LENGTH = = Core : : Timing: : GetDowncount ( ) ) ;
REQUIRE ( 0x1FULL = = callbacks_ran_flags . to_ullong ( ) ) ;
REQUIRE ( 0x1FULL = = callbacks_ran_flags . to_ullong ( ) ) ;
}
}
TEST_CASE ( " Core Timing[PredictableLateness]" , " [core] " ) {
TEST_CASE ( " Core :: Timing[PredictableLateness]" , " [core] " ) {
ScopeInit guard ;
ScopeInit guard ;
Core Timing: : EventType * cb_a = Core Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core : : Timing: : EventType * cb_a = Core : : Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core Timing: : EventType * cb_b = Core Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core : : Timing: : EventType * cb_b = Core : : Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
// Enter slice 0
// Enter slice 0
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
Core Timing: : ScheduleEvent ( 100 , cb_a , CB_IDS [ 0 ] ) ;
Core : : Timing: : ScheduleEvent ( 100 , cb_a , CB_IDS [ 0 ] ) ;
Core Timing: : ScheduleEvent ( 200 , cb_b , CB_IDS [ 1 ] ) ;
Core : : Timing: : ScheduleEvent ( 200 , cb_b , CB_IDS [ 1 ] ) ;
AdvanceAndCheck ( 0 , 90 , 10 , - 10 ) ; // (100 - 10)
AdvanceAndCheck ( 0 , 90 , 10 , - 10 ) ; // (100 - 10)
AdvanceAndCheck ( 1 , MAX_SLICE_LENGTH , 50 , - 50 ) ;
AdvanceAndCheck ( 1 , MAX_SLICE_LENGTH , 50 , - 50 ) ;
@ -192,10 +192,11 @@ static void RescheduleCallback(u64 userdata, s64 cycles_late) {
REQUIRE ( reschedules > = 0 ) ;
REQUIRE ( reschedules > = 0 ) ;
REQUIRE ( lateness = = cycles_late ) ;
REQUIRE ( lateness = = cycles_late ) ;
if ( reschedules > 0 )
if ( reschedules > 0 ) {
Core Timing: : ScheduleEvent ( 1000 , reinterpret_cast < Core Timing: : EventType * > ( userdata ) ,
Core : : Timing: : ScheduleEvent ( 1000 , reinterpret_cast < Core : : Timing: : EventType * > ( userdata ) ,
userdata ) ;
userdata ) ;
}
}
}
} // namespace ChainSchedulingTest
} // namespace ChainSchedulingTest
TEST_CASE ( " CoreTiming[ChainScheduling] " , " [core] " ) {
TEST_CASE ( " CoreTiming[ChainScheduling] " , " [core] " ) {
@ -203,35 +204,35 @@ TEST_CASE("CoreTiming[ChainScheduling]", "[core]") {
ScopeInit guard ;
ScopeInit guard ;
Core Timing: : EventType * cb_a = Core Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core : : Timing: : EventType * cb_a = Core : : Timing: : RegisterEvent ( " callbackA " , CallbackTemplate < 0 > ) ;
Core Timing: : EventType * cb_b = Core Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core : : Timing: : EventType * cb_b = Core : : Timing: : RegisterEvent ( " callbackB " , CallbackTemplate < 1 > ) ;
Core Timing: : EventType * cb_c = Core Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core : : Timing: : EventType * cb_c = Core : : Timing: : RegisterEvent ( " callbackC " , CallbackTemplate < 2 > ) ;
Core Timing: : EventType * cb_rs =
Core : : Timing: : EventType * cb_rs =
Core Timing: : RegisterEvent ( " callbackReschedule " , RescheduleCallback ) ;
Core : : Timing: : RegisterEvent ( " callbackReschedule " , RescheduleCallback ) ;
// Enter slice 0
// Enter slice 0
Core Timing: : Advance ( ) ;
Core : : Timing: : Advance ( ) ;
Core Timing: : ScheduleEvent ( 800 , cb_a , CB_IDS [ 0 ] ) ;
Core : : Timing: : ScheduleEvent ( 800 , cb_a , CB_IDS [ 0 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_b , CB_IDS [ 1 ] ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_b , CB_IDS [ 1 ] ) ;
Core Timing: : ScheduleEvent ( 2200 , cb_c , CB_IDS [ 2 ] ) ;
Core : : Timing: : ScheduleEvent ( 2200 , cb_c , CB_IDS [ 2 ] ) ;
Core Timing: : ScheduleEvent ( 1000 , cb_rs , reinterpret_cast < u64 > ( cb_rs ) ) ;
Core : : Timing: : ScheduleEvent ( 1000 , cb_rs , reinterpret_cast < u64 > ( cb_rs ) ) ;
REQUIRE ( 800 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 800 = = Core : : Timing: : GetDowncount ( ) ) ;
reschedules = 3 ;
reschedules = 3 ;
AdvanceAndCheck ( 0 , 200 ) ; // cb_a
AdvanceAndCheck ( 0 , 200 ) ; // cb_a
AdvanceAndCheck ( 1 , 1000 ) ; // cb_b, cb_rs
AdvanceAndCheck ( 1 , 1000 ) ; // cb_b, cb_rs
REQUIRE ( 2 = = reschedules ) ;
REQUIRE ( 2 = = reschedules ) ;
Core Timing: : AddTicks ( Core Timing: : GetDowncount ( ) ) ;
Core : : Timing: : AddTicks ( Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : Advance ( ) ; // cb_rs
Core : : Timing: : Advance ( ) ; // cb_rs
REQUIRE ( 1 = = reschedules ) ;
REQUIRE ( 1 = = reschedules ) ;
REQUIRE ( 200 = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( 200 = = Core : : Timing: : GetDowncount ( ) ) ;
AdvanceAndCheck ( 2 , 800 ) ; // cb_c
AdvanceAndCheck ( 2 , 800 ) ; // cb_c
Core Timing: : AddTicks ( Core Timing: : GetDowncount ( ) ) ;
Core : : Timing: : AddTicks ( Core : : Timing: : GetDowncount ( ) ) ;
Core Timing: : Advance ( ) ; // cb_rs
Core : : Timing: : Advance ( ) ; // cb_rs
REQUIRE ( 0 = = reschedules ) ;
REQUIRE ( 0 = = reschedules ) ;
REQUIRE ( MAX_SLICE_LENGTH = = Core Timing: : GetDowncount ( ) ) ;
REQUIRE ( MAX_SLICE_LENGTH = = Core : : Timing: : GetDowncount ( ) ) ;
}
}