From 24d5cfc64749dd5947db240061c369748a8c4670 Mon Sep 17 00:00:00 2001 From: icex2 Date: Mon, 12 Apr 2021 22:03:24 +0200 Subject: [PATCH] patch/piuio/piubtn: Add option to delay polling on ctrl msgs The PRO games do not have proper CPU load limiting on their IO threads which results in very high CPU load when using the emulation subsystem. --- src/main/hook/patch/piubtn.c | 14 +++++++++++++- src/main/hook/patch/piubtn.h | 7 +++++-- src/main/hook/patch/piuio.c | 13 ++++++++++++- src/main/hook/patch/piuio.h | 6 +++++- 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/main/hook/patch/piubtn.c b/src/main/hook/patch/piubtn.c index 4364c36..b4659f7 100644 --- a/src/main/hook/patch/piubtn.c +++ b/src/main/hook/patch/piubtn.c @@ -37,6 +37,8 @@ static ptapi_io_piubtn_send_t _patch_piubtn_ptapi_io_piubtn_send; static ptapi_io_piubtn_get_input_t _patch_piubtn_ptapi_io_piubtn_get_input; static ptapi_io_piubtn_set_output_t _patch_piubtn_ptapi_io_piubtn_set_output; +static uint32_t _patch_piubtn_poll_delay_ms; + static const struct cnh_usb_emu_virtdev_ep _patch_piubtn_virtdev = { .pid = PIUBTN_DRV_PID, .vid = PIUBTN_DRV_VID, @@ -49,8 +51,14 @@ static const struct cnh_usb_emu_virtdev_ep _patch_piubtn_virtdev = { static void *_patch_piubtn_api_lib_handle; -void patch_piubtn_init(const char *piubtn_lib_path) +void patch_piubtn_init(const char *piubtn_lib_path, uint32_t poll_delay_ms) { + _patch_piubtn_poll_delay_ms = poll_delay_ms; + + if (_patch_piubtn_poll_delay_ms > 0) { + log_debug("Enabled poll delay ms: %d", poll_delay_ms); + } + if (!piubtn_lib_path) { log_die("No piubtn emulation library path specified"); } @@ -140,6 +148,10 @@ static enum cnh_result _patch_piubtn_control_msg( struct cnh_iobuf *buffer, int timeout) { + if (_patch_piubtn_poll_delay_ms > 0) { + usleep(_patch_piubtn_poll_delay_ms * 1000); + } + if (request_type == PIUBTN_DRV_USB_CTRL_TYPE_IN && request == PIUBTN_DRV_USB_CTRL_REQUEST) { if (buffer->nbytes != PIUBTN_DRV_BUFFER_SIZE) { diff --git a/src/main/hook/patch/piubtn.h b/src/main/hook/patch/piubtn.h index 12a046c..d578693 100644 --- a/src/main/hook/patch/piubtn.h +++ b/src/main/hook/patch/piubtn.h @@ -13,9 +13,12 @@ * Initialize the patch module * * @param piubtn_lib_path Path to a library implementing the piubtn API - * @param real_passthrough True to ignore the library and disable any emulation + * @param poll_delay_ms If the polling thread relies on the hardware + * load for timing, CPU load increases massively if the caller is not taking + * care of sleeping properly. Injects an artificial delay to emulate that and + * control the CPU load. */ -void patch_piubtn_init(const char *piubtn_lib_path); +void patch_piubtn_init(const char *piubtn_lib_path, uint32_t poll_delay_ms); /** * Get the input hook handler provided by the piubtn library. diff --git a/src/main/hook/patch/piuio.c b/src/main/hook/patch/piuio.c index b2a29c7..fd28b16 100644 --- a/src/main/hook/patch/piuio.c +++ b/src/main/hook/patch/piuio.c @@ -45,11 +45,18 @@ static const struct cnh_usb_emu_virtdev_ep _patch_piuio_virtdev = { .close = _patch_piuio_close, }; +static uint32_t _patch_piuio_poll_delay_ms; static struct ptapi_io_piuio_api _patch_piuio_api; static enum ptapi_io_piuio_sensor_group _patch_piuio_sensor_group; -void patch_piuio_init(const char *piuio_lib_path) +void patch_piuio_init(const char *piuio_lib_path, uint32_t poll_delay_ms) { + _patch_piuio_poll_delay_ms = poll_delay_ms; + + if (_patch_piuio_poll_delay_ms > 0) { + log_debug("Enabled poll delay ms: %d", poll_delay_ms); + } + if (!piuio_lib_path) { log_die("No piuio emulation library path specified"); } @@ -116,6 +123,10 @@ static enum cnh_result _patch_piuio_control_msg( struct cnh_iobuf *buffer, int timeout) { + if (_patch_piuio_poll_delay_ms > 0) { + usleep(_patch_piuio_poll_delay_ms * 1000); + } + /** * Expected call pattern for a full game state update on a single frame (when * done synchronously) diff --git a/src/main/hook/patch/piuio.h b/src/main/hook/patch/piuio.h index db04f79..0ae3b4b 100644 --- a/src/main/hook/patch/piuio.h +++ b/src/main/hook/patch/piuio.h @@ -11,8 +11,12 @@ * Initialize the patch module * * @param piuio_lib_path Path to a library implementing the piuio API + * @param poll_delay_ms If the polling thread relies on the hardware + * load for timing, CPU load increases massively if the caller is not taking + * care of sleeping properly. Injects an artificial delay to emulate that and + * control the CPU load. */ -void patch_piuio_init(const char *piuio_lib_path); +void patch_piuio_init(const char *piuio_lib_path, uint32_t poll_delay_ms); /** * Shut down the patch module