From 7db96528cfc000a2f8aeb068a4f3ef2bc3d12bf8 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Fri, 3 May 2019 09:12:11 +0200 Subject: [PATCH] Name threads --- Makefile.in | 1 + configure.ac | 1 + src/control_socket.cpp | 3 + src/main.cpp | 4 ++ src/rtp/net_udp.cpp | 2 + src/rtp/video_decoders.cpp | 3 + src/utils/thread.c | 97 ++++++++++++++++++++++++++++++++ src/utils/thread.h | 52 +++++++++++++++++ src/utils/worker.cpp | 2 + src/video_compress.cpp | 3 + src/video_rxtx.cpp | 2 + src/video_rxtx/ultragrid_rtp.cpp | 2 + src/vo_postprocess.c | 2 - 13 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 src/utils/thread.c create mode 100644 src/utils/thread.h diff --git a/Makefile.in b/Makefile.in index 9464de255..94d4df0ca 100644 --- a/Makefile.in +++ b/Makefile.in @@ -136,6 +136,7 @@ OBJS = @OBJS@ \ src/utils/ring_buffer.o \ src/utils/sdp.o \ src/utils/synchronized_queue.o \ + src/utils/thread.o \ src/utils/vf_split.o \ src/utils/wait_obj.o \ src/utils/worker.o \ diff --git a/configure.ac b/configure.ac index 7ff1075e0..cde0fd268 100644 --- a/configure.ac +++ b/configure.ac @@ -136,6 +136,7 @@ else if expr "$host_os" : ".*mingw32.*" > /dev/null || expr "$host_os" : ".*msys AC_DEFINE([WIN32], [1], [This is an Windows OS]) NET_LIBS="-lsetupapi -lws2_32 -liphlpapi -loleaut32" LIBS="$LIBS $NET_LIBS" + AC_CHECK_FUNCS(SetThreadDescription) else system=Linux LDFLAGS="$LDFLAGS -Wl,--dynamic-list-data" diff --git a/src/control_socket.cpp b/src/control_socket.cpp index 03247a602..651ee62e6 100644 --- a/src/control_socket.cpp +++ b/src/control_socket.cpp @@ -58,6 +58,7 @@ #include "rtp/net_udp.h" // socket_error #include "tv.h" #include "utils/net.h" +#include "utils/thread.h" #define DEFAULT_CONTROL_PORT 5054 #define MAX_CLIENTS 16 @@ -685,6 +686,7 @@ ADD_TO_PARAM(control_accept_global, "control-accept-global", "* control-accept-g " Open control socket to public network.\n"); static void * control_thread(void *args) { + set_thread_name(__func__); struct control_state *s = (struct control_state *) args; struct client *clients = NULL; @@ -840,6 +842,7 @@ static void * control_thread(void *args) static void *stat_event_thread(void *args) { + set_thread_name(__func__); struct control_state *s = (struct control_state *) args; while (1) { diff --git a/src/main.cpp b/src/main.cpp index 1397cc8fa..4dfd213dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,6 +80,7 @@ #include "ug_runtime_error.h" #include "utils/misc.h" #include "utils/net.h" +#include "utils/thread.h" #include "utils/wait_obj.h" #include "video.h" #include "video_capture.h" @@ -1279,6 +1280,7 @@ int main(int argc, char *argv[]) if (strcmp("none", requested_display) != 0) { if (!mainloop) { + set_thread_name("display"); display_run(uv.display_device); } else { throw string("Cannot run display when " @@ -1287,8 +1289,10 @@ int main(int argc, char *argv[]) } if (mainloop) { + set_thread_name("mainloop"); mainloop(mainloop_udata); } + set_thread_name("main"); } catch (ug_runtime_error const &e) { cerr << e.what() << endl; exit_uv(e.get_code()); diff --git a/src/rtp/net_udp.cpp b/src/rtp/net_udp.cpp index 3eeec4a6f..48a4d8fda 100644 --- a/src/rtp/net_udp.cpp +++ b/src/rtp/net_udp.cpp @@ -55,6 +55,7 @@ #include "net_udp.h" #include "rtp.h" #include "utils/net.h" +#include "utils/thread.h" #ifdef NEED_ADDRINFO_H #include "addrinfo.h" @@ -991,6 +992,7 @@ int udp_sendv(socket_udp * s, struct iovec *vector, int count, void *d) */ static void *udp_reader(void *arg) { + set_thread_name(__func__); socket_udp *s = (socket_udp *) arg; while (1) { diff --git a/src/rtp/video_decoders.cpp b/src/rtp/video_decoders.cpp index 8d6df9e53..b9a96dda5 100644 --- a/src/rtp/video_decoders.cpp +++ b/src/rtp/video_decoders.cpp @@ -90,6 +90,7 @@ #include "rtp/pbuf.h" #include "rtp/video_decoders.h" #include "utils/synchronized_queue.h" +#include "utils/thread.h" #include "utils/timed_message.h" #include "utils/worker.h" #include "video.h" @@ -365,6 +366,7 @@ static void wait_for_framebuffer_swap(struct state_video_decoder *decoder) { "while expecting encrypted.\n" static void *fec_thread(void *args) { + set_thread_name(__func__); struct state_video_decoder *decoder = (struct state_video_decoder *) args; @@ -567,6 +569,7 @@ static void *decompress_worker(void *data) } static void *decompress_thread(void *args) { + set_thread_name(__func__); struct state_video_decoder *decoder = (struct state_video_decoder *) args; diff --git a/src/utils/thread.c b/src/utils/thread.c new file mode 100644 index 000000000..d000eafbe --- /dev/null +++ b/src/utils/thread.c @@ -0,0 +1,97 @@ +/** + * @file utils/thread.h + * @author Martin Pulec + */ +/* + * Copyright (c) 2019 CESNET z.s.p.o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#include "config_unix.h" +#include "config_win32.h" +#endif + +#ifdef HAVE_SETTHREADDESCRIPTION +#include +#endif + +#include "host.h" +#include "utils/thread.h" + +static inline char *get_argv_program_name(void) { + if (uv_argv != NULL && uv_argv[0] != NULL) { + char *prog_name = (char *) malloc(strlen(uv_argv[0]) + 2); + strcpy(prog_name, uv_argv[0]); + char *name = basename(prog_name); + memmove(prog_name, name, strlen(name) + 1); + strcat(prog_name, "-"); + return prog_name; + } + return strdup("uv-"); +} + +void set_thread_name(const char *name) { +#ifdef HAVE_LINUX +// thread name can have at most 16 chars (including terminating null char) + char *prog_name = get_argv_program_name(); + char tmp[16]; + tmp[sizeof tmp - 1] = '\0'; + strncpy(tmp, prog_name, sizeof tmp - 1); + free(prog_name); + strncat(tmp, name, sizeof tmp - strlen(tmp) - 1); + pthread_setname_np(pthread_self(), tmp); +#elif defined HAVE_MACOSX + char *prog_name = get_argv_program_name(); + char *tmp = (char *) alloca(strlen(prog_name) + strlen(name) + 1); + strcpy(tmp, prog_name); + free(prog_name); + strcat(tmp, name); + pthread_setname_np(tmp); +#elif defined WIN32 +// supported from Windows 10, not yet working +#if 0 +//#ifdef HAVE_SETTHREADDESCRIPTION + const char *prefix = "uv-";\ + size_t dst_len = (mbstowcs(NULL, prefix, 0) + mbstowcs(NULL, name, 0) + 1) * sizeof(wchar_t);\ + wchar_t *tmp = (wchar_t *) alloca(dst_len);\ + mbstowcs(tmp, prefix, dst_len / sizeof(wchar_t));\ + mbstowcs(tmp + wcslen(tmp), name, dst_len / sizeof(wchar_t) - wcslen(tmp));\ + SetThreadDescription(GetCurrentThread(), tmp);\ +#else + (void) name; +#endif +#else + (void) name; +#endif +} + diff --git a/src/utils/thread.h b/src/utils/thread.h new file mode 100644 index 000000000..2ca5f8fdd --- /dev/null +++ b/src/utils/thread.h @@ -0,0 +1,52 @@ +/** + * @file utils/thread.h + * @author Martin Pulec + */ +/* + * Copyright (c) 2019 CESNET, z. s. p. o. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, is permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of CESNET nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UTILS_THREAD_H_ +#define UTILS_THREAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void set_thread_name(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif // UTILS_THREAD_H_ + diff --git a/src/utils/worker.cpp b/src/utils/worker.cpp index d1f6a90f6..6056424f3 100644 --- a/src/utils/worker.cpp +++ b/src/utils/worker.cpp @@ -51,6 +51,7 @@ #include "config_win32.h" #endif // HAVE_CONFIG_H +#include "utils/thread.h" #include "utils/worker.h" #include @@ -123,6 +124,7 @@ struct wp_worker { }; void *wp_worker::enter_loop(void *args) { + set_thread_name("worker"); wp_worker *instance = (wp_worker *) args; instance->run(); diff --git a/src/video_compress.cpp b/src/video_compress.cpp index 10b519fd5..95c3862bf 100644 --- a/src/video_compress.cpp +++ b/src/video_compress.cpp @@ -54,6 +54,7 @@ #include "messaging.h" #include "module.h" #include "utils/synchronized_queue.h" +#include "utils/thread.h" #include "utils/vf_split.h" #include "utils/worker.h" #include "video.h" @@ -511,6 +512,7 @@ compress_state_real::~compress_state_real() namespace { void compress_state_real::async_tile_consumer(struct compress_state *s) { + set_thread_name(__func__); vector> compressed_tiles; unsigned expected_seq = 0; while (true) { @@ -561,6 +563,7 @@ void compress_state_real::async_tile_consumer(struct compress_state *s) void compress_state_real::async_consumer(struct compress_state *s) { + set_thread_name(__func__); while (true) { auto frame = funcs->compress_frame_async_pop_func(state[0]); if (!discard_frames) { diff --git a/src/video_rxtx.cpp b/src/video_rxtx.cpp index d089966cf..114c7072e 100644 --- a/src/video_rxtx.cpp +++ b/src/video_rxtx.cpp @@ -60,6 +60,7 @@ #include "tfrc.h" #include "transmit.h" #include "tv.h" +#include "utils/thread.h" #include "utils/vf_split.h" #include "video.h" #include "video_compress.h" @@ -179,6 +180,7 @@ int video_rxtx::check_sender_messages() { } void *video_rxtx::sender_loop() { + set_thread_name(__func__); struct video_desc saved_vid_desc; memset(&saved_vid_desc, 0, sizeof(saved_vid_desc)); diff --git a/src/video_rxtx/ultragrid_rtp.cpp b/src/video_rxtx/ultragrid_rtp.cpp index 8cd13af42..4001d9256 100644 --- a/src/video_rxtx/ultragrid_rtp.cpp +++ b/src/video_rxtx/ultragrid_rtp.cpp @@ -64,6 +64,7 @@ #include "tfrc.h" #include "transmit.h" #include "tv.h" +#include "utils/thread.h" #include "utils/vf_split.h" #include "video.h" #include "video_compress.h" @@ -327,6 +328,7 @@ struct vcodec_state *ultragrid_rtp_video_rxtx::new_video_decoder(struct display void *ultragrid_rtp_video_rxtx::receiver_loop() { + set_thread_name(__func__); uint32_t ts; struct pdb_e *cp; struct timeval curr_time; diff --git a/src/vo_postprocess.c b/src/vo_postprocess.c index c2ba16ab7..22cdb5df8 100644 --- a/src/vo_postprocess.c +++ b/src/vo_postprocess.c @@ -56,8 +56,6 @@ #include "lib_common.h" #include "vo_postprocess.h" -extern char **uv_argv; - struct vo_postprocess_state { const struct vo_postprocess_info *funcs; void *state;