Files
RetroArch/input/include
LibretroAdmin 4d702934db wiiu/hid: hand adapters between threads lock-free
The polling thread and the frontend shared one adapter list under an
OSFastMutex, which the frontend took on every poll, and the HID attach
callbacks queued events by swapping the list head out and back in. That
swap pair is not atomic as a whole: two callbacks at once (the HID
stack calls them from more than one thread) can each take the list and
put theirs back over the other's, losing an attach or a detach. A lost
detach leaves the pad registered for good.

Each thread now keeps its own list and hands adapters across through
the lock-free stacks of mpsc_stack.h:

  attach callbacks -> hid_events  -> polling thread
  polling thread   -> hid_new     -> frontend: adapters to set up
  frontend         -> hid_retired -> polling thread: to free

An adapter's state is a retro_atomic_int_t, and each value is moved on
by one thread only, so no two ever write it from the same state. The
read completion runs the packet handler before it says READY, since
READY is when the polling thread may start winding the adapter down;
it used to say READY first. The frontend deregisters and deinitialises
a pad as it retires the adapter, the polling thread frees the adapter,
and at shutdown the polling thread tears down what is left, as before.
No lock remains, and the frontend's poll no longer takes one.

samples/input/wiiu_hid_threads runs the driver against stand-ins for
Cafe OS on pthreads: two threads attach and detach devices while the
frontend polls and an "IOS" thread completes the reads, and every pad
must be registered, fed, deregistered and deinitialised in order, on
the right threads, with nothing left at shutdown. Its negative build
loses the reads in flight at shutdown and must fail. Against the old
driver (32-bit PowerPC under qemu) it fails: a few hundred pads of
detached devices are never torn down.
2026-10-29 21:01:28 +01:00
..
2021-10-16 14:52:56 -07:00
2021-10-05 09:10:41 -07:00