Skip to content

usb input device changes stalling main thread / missed inputs and cd stalls #1140

Description

@tonytoon

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions