New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core: CoreTiming Cleanup (Add UnitTests) #4168
Conversation
@phire Is CoreTiming supposed to work like this? There's no comments explaining the behavior. void Test()
{
CoreTiming::Init()
auto key = CoreTiming::RegisterEvent("test", TestCallback);
CoreTiming::ScheduleEvent(1000, key, 0);
PowerPC::ppcState.downcount = 0;
CoreTiming::Advance();
}
void TestCallback(u64 userdata, s64 late)
{
_assert_(late == 19000); // <-- This is always true
} This seems wrong but I don't know if there's a reason for it or not. |
Not anymore. However you don't get the correct result until I think Init is making the assumption that Advance will be called before On Sep 1, 2016 5:21 PM, "EmptyChaos" notifications@github.com wrote:
|
Source/Core/Core/CoreTiming.cpp, line 57 [r1] (raw file):
Please don't inherit from the standard library types (I shouldn't even need to explain why this is generally a bad idea, there's numerous explanations already written on the net). If necessary, compose a type that builds off a priority_queue through composition or utilize some other means of doing the same thing. Comments from Reviewable |
Review status: 0 of 26 files reviewed at latest revision, 1 unresolved discussion. Source/Core/Core/CoreTiming.cpp, line 57 [r1] (raw file):
|
Source/Core/Core/CoreTiming.cpp, line 57 [r1] (raw file):
|
Source/Core/Core/CoreTiming.cpp, line 70 [r1] (raw file):
Note that you can utilize the returned iterator from Comments from Reviewable |
a41276c
to
0ece7d0
Compare
I've set Review status: 0 of 26 files reviewed at latest revision, 2 unresolved discussions. Source/Core/Core/CoreTiming.cpp, line 57 [r1] (raw file):
|
I'm not sure that's the proper way to fix the bug. With the original code, this works:
This works too:
Only this sequence fails
I would be in favor of simply not doing the latter and adding documentation that it shouldn't be done. |
@phire Okay, but what documentation should I put in? There doesn't seem to be an obvious reason that
|
f8983b2
to
8ca5ad6
Compare
Reviewed 23 of 26 files at r1, 1 of 1 files at r2, 1 of 2 files at r3. Source/Core/Core/CoreTiming.cpp, line 32 [r3] (raw file):
How often do we use this reference to name here? I don't see much usage in storing it, and it would simplify the map string->callback. Source/Core/Core/CoreTiming.cpp, line 56 [r3] (raw file):
I think we need at least a good comment here why you don't use a std::priority_queue. Also, I'm doubtful that your performance check is valid, as there are games which triggers a lot of events. eg Silent Hill should be checked: https://forums.dolphin-emu.org/Thread-is-silent-hill-fixed-yet?pid=418166#pid418166 Source/Core/Core/CoreTiming.cpp, line 363 [r3] (raw file):
Isn't the event queue already sorted? Source/Core/Core/CoreTiming.cpp, line 408 [r3] (raw file):
With dropping this line, you'll increase the max delay of asynchronous events. Was this done on purpose? Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp, line 88 [r3] (raw file):
Maybe a small comment which behavior is expected here with queued events: assert, called now, or dropped. Source/Core/Core/PowerPC/PowerPC.cpp, line 39 [r3] (raw file):
By the way, "= nullptr" is redundant here. Global static pointers are initialized with nullptr. Comments from Reviewable |
@@ -31,6 +31,7 @@ extern u64 g_fake_TB_start_ticks; | |||
extern int g_slice_length; | |||
extern float g_last_OC_factor_inverted; | |||
|
|||
// NOTE: ScheduleEvent will not start updating the PowerPC downcount until after the first Advance. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Sorry, something went wrong.
Though after looking thought the code, I'm not actually seeing a good reason to keep the behavior I originally gave it. Perhaps |
486ae63
to
4184984
Compare
Or just make it explicit. Init() for the internal structurs, then a few RegisterEvents, then maybe a Start() call on the initial PPC run. |
Reviewed 18 of 19 files at r4. Comments from Reviewable |
4184984
to
6d62369
Compare
Review status: 24 of 26 files reviewed at latest revision, 7 unresolved discussions. Source/Core/Core/CoreTiming.cpp, line 32 [r3] (raw file):
|
6d62369
to
ddba0c6
Compare
@phire The part I didn't understand from just looking at the code was the implicit slice boundary concept. It makes sense when you explained it as the boundary between slice -1 and slice 0 so I'm fine the current behavior now. One point though, the interpreter seems to be divergent from the JIT. It calls |
Yeah, it needs some comments to make this concept explictly clear. Shortly before 5.0, all the cores had wildly different behaviour about when advance was called. I thought I standardized in in #3800, but I might have left an inconstancy. Fixing it up (and adding comments as to why |
Reviewed 1 of 19 files at r4, 3 of 3 files at r5. Source/Core/Core/CoreTiming.cpp, line 32 [r3] (raw file):
|
Reviewed 7 of 26 files at r1, 15 of 19 files at r4, 3 of 3 files at r5. Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp, line 91 [r5] (raw file):
I'm not really happy about the existing code here. It looks like we could end up with a save-state loading containing one of these events before this event has been registered. Generally events should all be registers during Init. Source/UnitTests/Core/CoreTimingTest.cpp, line 120 [r5] (raw file):
Might as well assert that downcount equals 1000 here. Source/UnitTests/Core/CoreTimingTest.cpp, line 147 [r5] (raw file):
|
ddba0c6
to
d7bfd83
Compare
Review status: 23 of 26 files reviewed at latest revision, 7 unresolved discussions. Source/Core/Core/CoreTiming.cpp, line 32 [r3] (raw file):
|
Reviewed 3 of 3 files at r7. Comments from Reviewable |
Review status: all files reviewed at latest revision, 5 unresolved discussions. Source/UnitTests/Core/CoreTimingTest.cpp, line 147 [r5] (raw file):
|
Replace adhoc linked list with a priority heap. Performance characteristics are mostly the same, but is more cache friendly. [Priority Queues have O(log n) push/pop compared to the linked list's O(n) push/O(1) pop but the queue is not big enough for that to matter, so linear is faster over linked. Very slight gains when framelimit is unlimited (Wind Waker), 1900% -> 1950%]
d7bfd83
to
4112797
Compare
Review status: 22 of 26 files reviewed at latest revision, 6 unresolved discussions. Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp, line 91 [r5] (raw file):
|
Reviewed 1 of 3 files at r7, 4 of 4 files at r8. Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp, line 91 [r5] (raw file):
|
Once you have deleted that enum, Review status: all files reviewed at latest revision, 3 unresolved discussions. Source/Core/Core/CoreTiming.h, line 48 [r8] (raw file):
Now that the one place that used this enum was used has been proven buggy and been eliminated, the enum (and the optional argument on I don't think there is any use cases for these alternative modes which won't break savestates. Comments from Reviewable |
Separate state reset from Init().
Replace 'int' keys with something that carries type information. Performance is neutral.
ForceExceptionCheck messes up the downcount and slice length if the callback is scheduled into the past (g_slice_length becomes negative)
Events don't update the downcount until after the first Advance(), thus Advance() must be called once before scheduling works normally.
CoreTiming gets restored before ExpansionInterface so CoreTiming events need to already be registered before the save state loading begins. This means that the callbacks must be registered unconditionally instead of on-demand.
4112797
to
3a85aa9
Compare
PixelEngine is initialized by InitializeShared()
Review status: 24 of 27 files reviewed at latest revision, 5 unresolved discussions. Source/Core/VideoBackends/Software/SWmain.cpp, line 145 [r10] (raw file):
Perhaps put this change in another PR. Comments from Reviewable |
Review status: 24 of 27 files reviewed at latest revision, 5 unresolved discussions. Source/Core/Core/CoreTiming.h, line 48 [r8] (raw file):
|
Reviewed 1 of 2 files at r9, 1 of 1 files at r10. Source/Core/VideoBackends/Software/SWmain.cpp, line 145 [r10] (raw file):
|
Reviewed 2 of 4 files at r8, 2 of 2 files at r9, 1 of 1 files at r10. Source/Core/VideoBackends/Software/SWmain.cpp, line 145 [r10] (raw file):
|
Review status: all files reviewed at latest revision, 2 unresolved discussions. Source/UnitTests/Core/CoreTimingTest.cpp, line 147 [r5] (raw file):
|
@EmptyChaos I'm getting reports that the system menu can't load channels since this was merged. |
I heard something on the forums about Metroid Prime Trilogy not being able to launch its games (though there was no bisect). Could ES_Launch be broken? |
I've been poking around in the core and noticed that CoreTiming could use some tidying.
Changes:
s_
prefix to staticsLinkedListItem
with a slightly modifiedstd::priority_queue
int
toEventType*
(type safety)I haven't measured any significant performance differences.
This change is