tests: Add tests/testcore.c, a multi-threaded stress test that hammers#1809
tests: Add tests/testcore.c, a multi-threaded stress test that hammers#1809sonatique wants to merge 1 commit intolibusb:masterfrom
Conversation
3a6cca4 to
1d05add
Compare
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in libusb#1793 and the related set_composite_interface race surfaced during PR libusb#1795 review. The stressed code paths include: - usbi_get_device_by_session_id() - usbi_alloc_device() - usbi_connect_device() - libusb_unref_device() / ctx->usb_devs_lock - winusb_device_priv setup races in set_composite_interface and set_hid_interface (Windows, non-hotplug builds) The original C++20 reproducer was posted by smarvonohr and the C version with Win32 threads by mcuee in libusb#1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build: - Use the same PLATFORM_POSIX / PLATFORM_WINDOWS thread abstraction that stress_mt.c uses (pthread_create on POSIX, _beginthreadex on Windows, CreateThread on Cygwin), instead of bare pthread. The original would not build with MSVC. - Print the device list once before starting the worker threads, so the operator can confirm at a glance which devices are present. This is useful because the bug only manifests when enumeration touches certain device shapes (e.g. composite devices with HID children that exercise set_composite_interface). Add msvc/testcore.vcxproj following the same template as msvc/stress_mt.vcxproj so the test builds out of the box in Visual Studio against libusb_static. Notes for runners: - The test only triggers the enumeration races in non-HOTPLUG builds. With Windows hotplug enabled, libusb_get_device_list is served from a cache and winusb_get_device_list never runs concurrently, so the bug does not manifest. - The default LOOPS = 100000 is intentionally large for the original bug-hunting use case but takes hours of real work even when the library is correct (each non-hotplug get_device_list does a full Windows USB enumeration, ~10-100 ms). Reduce LOOPS for a quick smoke test. - At least one composite USB device with HID-class child interfaces (USB game controller, headset with controls, Logitech Unifying receiver, etc.) must be present to exercise set_composite_interface. Pure UVC/UAC composite devices like webcams will NOT trigger that path because their child interfaces are not HID class and are not bound to any libusb-supported driver. Closes libusb#1808 Closes libusb#1809
|
Two quick comments.
|
|
For example, under macOS, without adding the new test to auto-tools build, it will not build testcore by default. Manual build: |
| } | ||
|
|
||
| //libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG); | ||
|
|
There was a problem hiding this comment.
Maybe can add the following option to test Linux non-hotplug situation. Just as a comment, no need to be too complicated.
// This forces libusb to skip the automatic background discovery
// and only scan when you explicitly call get_device_list.
// libusb_set_option(ctx, LIBUSB_OPTION_NO_DEVICE_DISCOVERY);
|
|
||
| #define THREADS 12 | ||
| #define LOOPS 100000 | ||
|
|
There was a problem hiding this comment.
Since this will be a generic test program, it is good to add these two as argument. It is also good to print the help for the usage.
The default value can be 4 and 100000. Or shall we use 4 and 10000?
It would be good to make number of threads and number of loops to be arguments to the test program. If we choose the default loops to be 100,000, we may want to inform the user the above info. |
| #define THREADS 12 | ||
| #define LOOPS 100000 |
There was a problem hiding this comment.
I know this is just test code, but it would be nice to minimise use of #define for numerical constants as we write new code. Instead:
static const int THREADS = 12;
This allows better type checking.
libusb_get_device_list / libusb_free_device_list from N threads in parallel. It exists primarily to reproduce the concurrent-enumeration crashes reported in #1793 and the related set_composite_interface race surfaced during PR #1795 review.
The stressed code paths include:
Address issue: race in libusb get device list and libusb free device list with win usb backend + claim_interface race #1795 (comment) This version is adapted from mcuee's C version, with two changes that make it portable and easier to build:
Notes for runners:
Closes #1808