perf(threads): implement adjust_thread_priority for macOS and add set_thread_name (#4605)
This commit is contained in:
parent
f879294449
commit
3a12f96a86
17 changed files with 71 additions and 1 deletions
|
|
@ -91,6 +91,7 @@ namespace audio {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encoding takes place on this thread
|
// Encoding takes place on this thread
|
||||||
|
platf::set_thread_name("audio::encode");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||||
|
|
||||||
opus_t opus {opus_multistream_encoder_create(
|
opus_t opus {opus_multistream_encoder_create(
|
||||||
|
|
|
||||||
|
|
@ -1172,6 +1172,7 @@ namespace confighttp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
platf::set_thread_name("confighttp");
|
||||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||||
|
|
||||||
auto port_https = net::map_port(PORT_HTTPS);
|
auto port_https = net::map_port(PORT_HTTPS);
|
||||||
|
|
@ -1224,6 +1225,7 @@ namespace confighttp {
|
||||||
|
|
||||||
auto accept_and_run = [&](auto *server) {
|
auto accept_and_run = [&](auto *server) {
|
||||||
try {
|
try {
|
||||||
|
platf::set_thread_name("confighttp::tcp");
|
||||||
server->start([](unsigned short port) {
|
server->start([](unsigned short port) {
|
||||||
BOOST_LOG(info) << "Configuration UI available at [https://localhost:"sv << port << "]";
|
BOOST_LOG(info) << "Configuration UI available at [https://localhost:"sv << port << "]";
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,7 @@ int main(int argc, char *argv[]) {
|
||||||
auto session_monitor_join_thread_future = session_monitor_join_thread_promise.get_future();
|
auto session_monitor_join_thread_future = session_monitor_join_thread_promise.get_future();
|
||||||
|
|
||||||
std::thread session_monitor_thread([&]() {
|
std::thread session_monitor_thread([&]() {
|
||||||
|
platf::set_thread_name("session_monitor");
|
||||||
session_monitor_join_thread_promise.set_value_at_thread_exit();
|
session_monitor_join_thread_promise.set_value_at_thread_exit();
|
||||||
|
|
||||||
WNDCLASSA wnd_class {};
|
WNDCLASSA wnd_class {};
|
||||||
|
|
|
||||||
|
|
@ -1056,6 +1056,7 @@ namespace nvhttp {
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
platf::set_thread_name("nvhttp");
|
||||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||||
|
|
||||||
auto port_http = net::map_port(PORT_HTTP);
|
auto port_http = net::map_port(PORT_HTTP);
|
||||||
|
|
@ -1173,6 +1174,8 @@ namespace nvhttp {
|
||||||
|
|
||||||
auto accept_and_run = [&](auto *http_server) {
|
auto accept_and_run = [&](auto *http_server) {
|
||||||
try {
|
try {
|
||||||
|
std::string name = "nvhttp::" + std::to_string(http_server->config.port);
|
||||||
|
platf::set_thread_name(name);
|
||||||
http_server->start();
|
http_server->start();
|
||||||
} catch (boost::system::system_error &err) {
|
} catch (boost::system::system_error &err) {
|
||||||
// It's possible the exception gets thrown after calling http_server->stop() from a different thread
|
// It's possible the exception gets thrown after calling http_server->stop() from a different thread
|
||||||
|
|
|
||||||
|
|
@ -613,6 +613,12 @@ namespace platf {
|
||||||
};
|
};
|
||||||
void adjust_thread_priority(thread_priority_e priority);
|
void adjust_thread_priority(thread_priority_e priority);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Name the current thread for use with development tools.
|
||||||
|
* @note On Linux this will be truncated after 15 characters.
|
||||||
|
*/
|
||||||
|
void set_thread_name(const std::string &name);
|
||||||
|
|
||||||
void enable_mouse_keys();
|
void enable_mouse_keys();
|
||||||
|
|
||||||
// Allow OS-specific actions to be taken to prepare for streaming
|
// Allow OS-specific actions to be taken to prepare for streaming
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ namespace platf {
|
||||||
worker = std::thread {
|
worker = std::thread {
|
||||||
[](loop_t::pointer loop) {
|
[](loop_t::pointer loop) {
|
||||||
int retval;
|
int retval;
|
||||||
|
platf::set_thread_name("audio::pulseaudio");
|
||||||
auto status = pa_mainloop_run(loop, &retval);
|
auto status = pa_mainloop_run(loop, &retval);
|
||||||
|
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,10 @@ namespace platf {
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_thread_name(const std::string &name) {
|
||||||
|
pthread_setname_np(pthread_self(), name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void enable_mouse_keys() {
|
void enable_mouse_keys() {
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -423,6 +423,8 @@ namespace platf::publish {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
platf::set_thread_name("publish::avahi");
|
||||||
|
|
||||||
int avhi_error;
|
int avhi_error;
|
||||||
|
|
||||||
poll.reset(avahi::simple_poll_new());
|
poll.reset(avahi::simple_poll_new());
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <sys/qos.h>
|
||||||
|
|
||||||
// lib includes
|
// lib includes
|
||||||
#include <boost/asio/ip/address.hpp>
|
#include <boost/asio/ip/address.hpp>
|
||||||
|
|
@ -211,7 +212,32 @@ namespace platf {
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjust_thread_priority(thread_priority_e priority) {
|
void adjust_thread_priority(thread_priority_e priority) {
|
||||||
// Unimplemented
|
qos_class_t mac_priority;
|
||||||
|
|
||||||
|
switch (priority) {
|
||||||
|
case thread_priority_e::low:
|
||||||
|
mac_priority = QOS_CLASS_UTILITY;
|
||||||
|
break;
|
||||||
|
case thread_priority_e::normal:
|
||||||
|
mac_priority = QOS_CLASS_DEFAULT;
|
||||||
|
break;
|
||||||
|
case thread_priority_e::high:
|
||||||
|
mac_priority = QOS_CLASS_USER_INITIATED;
|
||||||
|
break;
|
||||||
|
case thread_priority_e::critical:
|
||||||
|
mac_priority = QOS_CLASS_USER_INTERACTIVE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BOOST_LOG(error) << "Unknown thread priority: "sv << (int) priority;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/apple/darwin-libpthread/blob/main/include/sys/qos.h
|
||||||
|
pthread_set_qos_class_self_np(mac_priority, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_thread_name(const std::string &name) {
|
||||||
|
pthread_setname_np(name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_mouse_keys() {
|
void enable_mouse_keys() {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ namespace platf::publish {
|
||||||
deinit_t(DNSServiceRef serviceRef):
|
deinit_t(DNSServiceRef serviceRef):
|
||||||
unique_ptr(serviceRef) {
|
unique_ptr(serviceRef) {
|
||||||
_thread = std::thread {[serviceRef, &_stopRequested = std::as_const(_stopRequested)]() {
|
_thread = std::thread {[serviceRef, &_stopRequested = std::as_const(_stopRequested)]() {
|
||||||
|
platf::set_thread_name("publish::mdns");
|
||||||
const auto socket = DNSServiceRefSockFD(serviceRef);
|
const auto socket = DNSServiceRefSockFD(serviceRef);
|
||||||
while (!_stopRequested) {
|
while (!_stopRequested) {
|
||||||
auto fdset = fd_set {};
|
auto fdset = fd_set {};
|
||||||
|
|
|
||||||
|
|
@ -1052,6 +1052,14 @@ namespace platf {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_thread_name(const std::string &name) {
|
||||||
|
std::wstring wname = utf_utils::from_utf8(name);
|
||||||
|
HRESULT hr = SetThreadDescription(GetCurrentThread(), wname.c_str());
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
BOOST_LOG(error) << "SetThreadDescription failed: " << hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void streaming_will_start() {
|
void streaming_will_start() {
|
||||||
static std::once_flag load_wlanapi_once_flag;
|
static std::once_flag load_wlanapi_once_flag;
|
||||||
std::call_once(load_wlanapi_once_flag, []() {
|
std::call_once(load_wlanapi_once_flag, []() {
|
||||||
|
|
|
||||||
|
|
@ -1121,6 +1121,7 @@ namespace rtsp_stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
platf::set_thread_name("rtsp");
|
||||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||||
|
|
||||||
server.map("OPTIONS"sv, &cmd_option);
|
server.map("OPTIONS"sv, &cmd_option);
|
||||||
|
|
@ -1138,6 +1139,7 @@ namespace rtsp_stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::thread rtsp_thread {[&shutdown_event] {
|
std::thread rtsp_thread {[&shutdown_event] {
|
||||||
|
platf::set_thread_name("rtsp::handler");
|
||||||
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
|
auto broadcast_shutdown_event = mail::man->event<bool>(mail::broadcast_shutdown);
|
||||||
|
|
||||||
while (!shutdown_event->peek()) {
|
while (!shutdown_event->peek()) {
|
||||||
|
|
|
||||||
|
|
@ -1060,6 +1060,7 @@ namespace stream {
|
||||||
});
|
});
|
||||||
|
|
||||||
// This thread handles latency-sensitive control messages
|
// This thread handles latency-sensitive control messages
|
||||||
|
platf::set_thread_name("stream::controlBroadcast");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
||||||
|
|
||||||
// Check for both the full shutdown event and the shutdown event for this
|
// Check for both the full shutdown event and the shutdown event for this
|
||||||
|
|
@ -1189,6 +1190,8 @@ namespace stream {
|
||||||
std::array<char, 2048> buf[2];
|
std::array<char, 2048> buf[2];
|
||||||
std::function<void(const boost::system::error_code, size_t)> recv_func[2];
|
std::function<void(const boost::system::error_code, size_t)> recv_func[2];
|
||||||
|
|
||||||
|
platf::set_thread_name("stream::recv");
|
||||||
|
|
||||||
auto populate_peer_to_session = [&]() {
|
auto populate_peer_to_session = [&]() {
|
||||||
while (message_queue_queue->peek()) {
|
while (message_queue_queue->peek()) {
|
||||||
auto message_queue_opt = message_queue_queue->pop();
|
auto message_queue_opt = message_queue_queue->pop();
|
||||||
|
|
@ -1271,6 +1274,7 @@ namespace stream {
|
||||||
auto video_epoch = std::chrono::steady_clock::now();
|
auto video_epoch = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
// Video traffic is sent on this thread
|
// Video traffic is sent on this thread
|
||||||
|
platf::set_thread_name("stream::videoBroadcast");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||||
|
|
||||||
logging::min_max_avg_periodic_logger<double> frame_processing_latency_logger(debug, "Frame processing latency", "ms");
|
logging::min_max_avg_periodic_logger<double> frame_processing_latency_logger(debug, "Frame processing latency", "ms");
|
||||||
|
|
@ -1610,6 +1614,7 @@ namespace stream {
|
||||||
audio_packet.rtp.ssrc = 0;
|
audio_packet.rtp.ssrc = 0;
|
||||||
|
|
||||||
// Audio traffic is sent on this thread
|
// Audio traffic is sent on this thread
|
||||||
|
platf::set_thread_name("stream::audioBroadcast");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||||
|
|
||||||
while (auto packet = packets->pop()) {
|
while (auto packet = packets->pop()) {
|
||||||
|
|
@ -1848,6 +1853,7 @@ namespace stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
void videoThread(session_t *session) {
|
void videoThread(session_t *session) {
|
||||||
|
platf::set_thread_name("session::video");
|
||||||
auto fg = util::fail_guard([&]() {
|
auto fg = util::fail_guard([&]() {
|
||||||
session::stop(*session);
|
session::stop(*session);
|
||||||
});
|
});
|
||||||
|
|
@ -1869,6 +1875,7 @@ namespace stream {
|
||||||
}
|
}
|
||||||
|
|
||||||
void audioThread(session_t *session) {
|
void audioThread(session_t *session) {
|
||||||
|
platf::set_thread_name("session::audio");
|
||||||
auto fg = util::fail_guard([&]() {
|
auto fg = util::fail_guard([&]() {
|
||||||
session::stop(*session);
|
session::stop(*session);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -305,6 +305,7 @@ namespace system_tray {
|
||||||
|
|
||||||
// Threading functions available on all platforms
|
// Threading functions available on all platforms
|
||||||
static void tray_thread_worker() {
|
static void tray_thread_worker() {
|
||||||
|
platf::set_thread_name("system_tray");
|
||||||
BOOST_LOG(info) << "System tray thread started"sv;
|
BOOST_LOG(info) << "System tray thread started"sv;
|
||||||
|
|
||||||
// Initialize the tray in this thread
|
// Initialize the tray in this thread
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
|
#include "platform/common.h"
|
||||||
#include "task_pool.h"
|
#include "task_pool.h"
|
||||||
|
|
||||||
namespace thread_pool_util {
|
namespace thread_pool_util {
|
||||||
|
|
@ -98,6 +99,7 @@ namespace thread_pool_util {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void _main() {
|
void _main() {
|
||||||
|
platf::set_thread_name("TaskPool::worker");
|
||||||
while (_continue) {
|
while (_continue) {
|
||||||
if (auto task = this->pop()) {
|
if (auto task = this->pop()) {
|
||||||
(*task)->run();
|
(*task)->run();
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,7 @@ namespace upnp {
|
||||||
* @brief Maintains UPnP port forwarding rules
|
* @brief Maintains UPnP port forwarding rules
|
||||||
*/
|
*/
|
||||||
void upnp_thread_proc() {
|
void upnp_thread_proc() {
|
||||||
|
platf::set_thread_name("upnp");
|
||||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||||
bool mapped = false;
|
bool mapped = false;
|
||||||
IGDdatas data;
|
IGDdatas data;
|
||||||
|
|
|
||||||
|
|
@ -1253,6 +1253,7 @@ namespace video {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Capture takes place on this thread
|
// Capture takes place on this thread
|
||||||
|
platf::set_thread_name("video::capture");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
platf::adjust_thread_priority(platf::thread_priority_e::critical);
|
||||||
|
|
||||||
while (capture_ctx_queue->running()) {
|
while (capture_ctx_queue->running()) {
|
||||||
|
|
@ -2292,6 +2293,7 @@ namespace video {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Encoding and capture takes place on this thread
|
// Encoding and capture takes place on this thread
|
||||||
|
platf::set_thread_name("video::capture_sync");
|
||||||
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
platf::adjust_thread_priority(platf::thread_priority_e::high);
|
||||||
|
|
||||||
std::vector<std::string> display_names;
|
std::vector<std::string> display_names;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue