A longstanding issue has been that the addition or removal of a USB input device (controller, mouse) causes a complete tear-down and rescan of all input devices in the main thread - this can lead to substantial stalls in reading inputs (which is less critical here since presumably the user is fumbling with their new device and doesn't notice) or feeding data to CD based cores since both tasks run as part of the main loop. (This has been vexing the CD-i core for a while, see #1039).
I have a WIP patch that implements a fix in this manner:
input_test has moved from 3 states (0,1,2) to four which are defined as enums for readability. The new states are:
INPUT_INIT, INPUT_FULL_SCAN, INPUT_CHANGED, INPUT_NORMAL
input_test begins in INPUT_INIT state, which initializes all data structures, etc, then moves to INPUT_FULL_SCAN.
INPUT_FULL_SCAN clears fds and events and other minor cleanup then moves to INPUT_CHANGED.
INPUT_CHANGED checks the list of actual devices and compares it to the list in pool[] for a list of changes. It removes devices which have been removed, and then runs the existing code (which has been moved to its own function) to directly scan devices which are new. When it completes, it runs mergedevs, check_joycons, etc. then sets state to INPUT_NORMAL.
Instead of doing a full scan, the check_devs test at
|
if ((pool[NUMDEV].revents & POLLIN) && check_devs()) |
instead sets the state to INPUT_CHANGED which triggers the new differential scan.
Testing has gone well - I believe I chose the logically best place to split up the existing process and I've not been able to create any issues so far plugging in/unplugging controllers in arbitrary and contrived scenarios. Once I'm confident I'm on the right track I'll move to profiling to see how much/if any this reduces the stalls.
A few asks: Does anybody have recommendations as to devices that involve mergedevs I can use for testing to make sure this new approach doesn't break anything? Also, if anybody has any thoughts on edge cases to test it'd be appreciated as well.
A longstanding issue has been that the addition or removal of a USB input device (controller, mouse) causes a complete tear-down and rescan of all input devices in the main thread - this can lead to substantial stalls in reading inputs (which is less critical here since presumably the user is fumbling with their new device and doesn't notice) or feeding data to CD based cores since both tasks run as part of the main loop. (This has been vexing the CD-i core for a while, see #1039).
I have a WIP patch that implements a fix in this manner:
input_test has moved from 3 states (0,1,2) to four which are defined as enums for readability. The new states are:
INPUT_INIT, INPUT_FULL_SCAN, INPUT_CHANGED, INPUT_NORMAL
input_test begins in INPUT_INIT state, which initializes all data structures, etc, then moves to INPUT_FULL_SCAN.
INPUT_FULL_SCAN clears fds and events and other minor cleanup then moves to INPUT_CHANGED.
INPUT_CHANGED checks the list of actual devices and compares it to the list in pool[] for a list of changes. It removes devices which have been removed, and then runs the existing code (which has been moved to its own function) to directly scan devices which are new. When it completes, it runs mergedevs, check_joycons, etc. then sets state to INPUT_NORMAL.
Instead of doing a full scan, the check_devs test at
Main_MiSTer/input.cpp
Line 5282 in b796212
Testing has gone well - I believe I chose the logically best place to split up the existing process and I've not been able to create any issues so far plugging in/unplugging controllers in arbitrary and contrived scenarios. Once I'm confident I'm on the right track I'll move to profiling to see how much/if any this reduces the stalls.
A few asks: Does anybody have recommendations as to devices that involve mergedevs I can use for testing to make sure this new approach doesn't break anything? Also, if anybody has any thoughts on edge cases to test it'd be appreciated as well.