From a7496fae77d85c6043d7833b11e17ca12230505d Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 6 Jun 2021 23:45:47 +0200 Subject: [PATCH] Add thread names --- CHANGELOG.md | 5 +++++ src/common/communication/common.h | 6 +++++- src/plugin/bridges/common.h | 3 +++ src/plugin/bridges/vst2.cpp | 1 + src/plugin/bridges/vst3.cpp | 1 + src/plugin/host-process.cpp | 1 + src/wine-host/bridges/group.cpp | 10 +++++++++- src/wine-host/bridges/vst2.cpp | 2 ++ src/wine-host/bridges/vst3.cpp | 7 +++++++ src/wine-host/individual-host.cpp | 2 ++ src/wine-host/utils.cpp | 6 +++++- 11 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e02b430..3eb5cad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- Added all thread names to all worker threads created by yabridge. This can + make it easier to debug and profile yabridge. + ### Fixed - Fixed mouse clicks in VST2 editors in **Tracktion Waveform** being offset diff --git a/src/common/communication/common.h b/src/common/communication/common.h index 9f42d715..bf4be761 100644 --- a/src/common/communication/common.h +++ b/src/common/communication/common.h @@ -775,7 +775,11 @@ class AdHocSocketHandler { std::move(secondary_socket)); }); - Thread secondary_requests_handler([&]() { secondary_context.run(); }); + Thread secondary_requests_handler([&]() { + pthread_setname_np(pthread_self(), "adhoc-acceptor"); + + secondary_context.run(); + }); // Now we'll handle reads on the primary socket in a loop until the // socket shuts down diff --git a/src/plugin/bridges/common.h b/src/plugin/bridges/common.h index 6dd55b3b..ef310c92 100644 --- a/src/plugin/bridges/common.h +++ b/src/plugin/bridges/common.h @@ -111,6 +111,7 @@ class PluginBridge { has_realtime_priority_promise.set_value( set_realtime_priority(true)); set_realtime_priority(false); + pthread_setname_np(pthread_self(), "wine-stdio"); io_context.run(); }) {} @@ -302,6 +303,8 @@ class PluginBridge { host_watchdog_handler = std::jthread([&](std::stop_token st) { using namespace std::literals::chrono_literals; + pthread_setname_np(pthread_self(), "watchdog"); + while (!st.stop_requested()) { if (!plugin_host->running()) { generic_logger.log( diff --git a/src/plugin/bridges/vst2.cpp b/src/plugin/bridges/vst2.cpp index 1293c11b..3f9ceaec 100644 --- a/src/plugin/bridges/vst2.cpp +++ b/src/plugin/bridges/vst2.cpp @@ -73,6 +73,7 @@ Vst2PluginBridge::Vst2PluginBridge(audioMasterCallback host_callback) // lockstep anyway host_callback_handler = std::jthread([&]() { set_realtime_priority(true); + pthread_setname_np(pthread_self(), "host-callbacks"); sockets.vst_host_callback.receive_events( std::pair(logger, false), diff --git a/src/plugin/bridges/vst3.cpp b/src/plugin/bridges/vst3.cpp index 5b9f8370..5285dbde 100644 --- a/src/plugin/bridges/vst3.cpp +++ b/src/plugin/bridges/vst3.cpp @@ -49,6 +49,7 @@ Vst3PluginBridge::Vst3PluginBridge() // configuration. host_callback_handler = std::jthread([&]() { set_realtime_priority(true); + pthread_setname_np(pthread_self(), "host-callbacks"); sockets.vst_host_callback.receive_messages( std::pair(logger, false), diff --git a/src/plugin/host-process.cpp b/src/plugin/host-process.cpp index 3ea1b14f..b5932523 100644 --- a/src/plugin/host-process.cpp +++ b/src/plugin/host-process.cpp @@ -171,6 +171,7 @@ GroupHost::GroupHost(boost::asio::io_context& io_context, group_host_connect_handler = std::jthread([this, connect, group_host_pid]() { set_realtime_priority(true); + pthread_setname_np(pthread_self(), "group-connect"); using namespace std::literals::chrono_literals; diff --git a/src/wine-host/bridges/group.cpp b/src/wine-host/bridges/group.cpp index 7c317bc1..9abd0e32 100644 --- a/src/wine-host/bridges/group.cpp +++ b/src/wine-host/bridges/group.cpp @@ -103,7 +103,11 @@ GroupBridge::GroupBridge(boost::filesystem::path group_socket_path) logger.async_log_pipe_lines(stderr_redirect.pipe, stderr_buffer, "[STDERR] "); - stdio_handler = Win32Thread([&]() { stdio_context.run(); }); + stdio_handler = Win32Thread([&]() { + pthread_setname_np(pthread_self(), "group-stdio"); + + stdio_context.run(); + }); } GroupBridge::~GroupBridge() noexcept { @@ -238,6 +242,10 @@ void GroupBridge::accept_requests() { const size_t plugin_id = next_plugin_id.fetch_add(1); active_plugins[plugin_id] = std::pair( Win32Thread([this, plugin_id, plugin_ptr = bridge.get()]() { + const std::string thread_name = + "worker-" + std::to_string(plugin_id); + pthread_setname_np(pthread_self(), thread_name.c_str()); + handle_plugin_run(plugin_id, plugin_ptr); }), std::move(bridge)); diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index c6cb708a..6adf3125 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -221,6 +221,7 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context, parameters_handler = Win32Thread([&]() { set_realtime_priority(true); + pthread_setname_np(pthread_self(), "parameters"); sockets.host_vst_parameters.receive_multi( [&](Parameter& request, SerializationBufferBase& buffer) { @@ -246,6 +247,7 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context, process_replacing_handler = Win32Thread([&]() { set_realtime_priority(true); + pthread_setname_np(pthread_self(), "audio"); // Most plugins will already enable FTZ, but there are a handful of // plugins that don't that suffer from extreme DSP load increases when diff --git a/src/wine-host/bridges/vst3.cpp b/src/wine-host/bridges/vst3.cpp index d5ace1c6..004848b4 100644 --- a/src/wine-host/bridges/vst3.cpp +++ b/src/wine-host/bridges/vst3.cpp @@ -1183,6 +1183,13 @@ size_t Vst3Bridge::register_object_instance( .audio_processor_handler = Win32Thread([&, instance_id]() { set_realtime_priority(true); + // XXX: Like with VST2 worker threads, when using plugin groups the + // thread names from different plugins will clash. Not a huge + // deal probably, since duplicate thread names are still more + // useful than no thread names. + const std::string thread_name = "audio-" + std::to_string(instance_id); + pthread_setname_np(pthread_self(), thread_name.c_str()); + sockets.add_audio_processor_and_listen( instance_id, socket_listening_latch, overload{ diff --git a/src/wine-host/individual-host.cpp b/src/wine-host/individual-host.cpp index 84dc1d22..04c7e44d 100644 --- a/src/wine-host/individual-host.cpp +++ b/src/wine-host/individual-host.cpp @@ -117,6 +117,8 @@ __cdecl // potentially unsafe events that should always be run from the UI thread // will be posted to `main_context`. Win32Thread worker_thread([&]() { + pthread_setname_np(pthread_self(), "worker"); + bridge->run(); // // When the sockets get closed, this application should diff --git a/src/wine-host/utils.cpp b/src/wine-host/utils.cpp index e3528d89..78cb4d0c 100644 --- a/src/wine-host/utils.cpp +++ b/src/wine-host/utils.cpp @@ -86,7 +86,11 @@ MainContext::MainContext() // we'll run the timer on a 30 second interval. async_handle_watchdog_timer(5s); - watchdog_handler = Win32Thread([&]() { watchdog_context.run(); }); + watchdog_handler = Win32Thread([&]() { + pthread_setname_np(pthread_self(), "watchdog"); + + watchdog_context.run(); + }); } void MainContext::run() {