From ec41d849bbc460d4002ae19e3891b3bda513307e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 23 Jan 2014 10:07:14 +0100 Subject: [PATCH] thread/Name: set thread names For debugging. --- Makefile.am | 1 + configure.ac | 7 ++++++ src/DecoderThread.cxx | 11 ++++++++++ src/IOThread.cxx | 3 +++ src/OutputThread.cxx | 3 +++ src/PlayerThread.cxx | 3 +++ src/thread/Name.hxx | 51 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+) create mode 100644 src/thread/Name.hxx diff --git a/Makefile.am b/Makefile.am index cdeca8dc6..80ae9bdd8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -290,6 +290,7 @@ libutil_a_SOURCES = \ libthread_a_SOURCES = \ src/thread/Util.hxx \ + src/thread/Name.hxx \ src/thread/Mutex.hxx \ src/thread/PosixMutex.hxx \ src/thread/CriticalSection.hxx \ diff --git a/configure.ac b/configure.ac index 52db236ba..13ff64ba7 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,13 @@ AC_SEARCH_LIBS([exp], [m],, AC_CHECK_HEADERS(locale.h) AC_CHECK_HEADERS(valgrind/memcheck.h) +AC_CHECK_LIB([pthread], [pthread_setname_np], + [have_pthread_setname_np=yes], + [have_pthread_setname_np=no]) +if test x$have_pthread_setname_np = xyes; then + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Is pthread_setname_np() available?]) +fi + dnl --------------------------------------------------------------------------- dnl Event loop selection dnl --------------------------------------------------------------------------- diff --git a/src/DecoderThread.cxx b/src/DecoderThread.cxx index 8658c8883..5c0e31034 100644 --- a/src/DecoderThread.cxx +++ b/src/DecoderThread.cxx @@ -34,6 +34,7 @@ #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" +#include "thread/Name.hxx" #include "tag/ApeReplayGain.hxx" #include "Log.hxx" @@ -127,8 +128,12 @@ decoder_stream_decode(const DecoderPlugin &plugin, decoder.dc.Unlock(); + FormatThreadName("decoder:%s", plugin.name); + plugin.StreamDecode(decoder, input_stream); + SetThreadName("decoder"); + decoder.dc.Lock(); assert(decoder.dc.state == DecoderState::START || @@ -155,8 +160,12 @@ decoder_file_decode(const DecoderPlugin &plugin, decoder.dc.Unlock(); + FormatThreadName("decoder:%s", plugin.name); + plugin.FileDecode(decoder, path); + SetThreadName("decoder"); + decoder.dc.Lock(); assert(decoder.dc.state == DecoderState::START || @@ -421,6 +430,8 @@ decoder_task(void *arg) { DecoderControl &dc = *(DecoderControl *)arg; + SetThreadName("decoder"); + dc.Lock(); do { diff --git a/src/IOThread.cxx b/src/IOThread.cxx index 8877d3c2d..e21ede4f3 100644 --- a/src/IOThread.cxx +++ b/src/IOThread.cxx @@ -22,6 +22,7 @@ #include "thread/Mutex.hxx" #include "thread/Cond.hxx" #include "thread/Thread.hxx" +#include "thread/Name.hxx" #include "event/Loop.hxx" #include "system/FatalError.hxx" #include "util/Error.hxx" @@ -48,6 +49,8 @@ io_thread_run(void) static void io_thread_func(gcc_unused void *arg) { + SetThreadName("io"); + /* lock+unlock to synchronize with io_thread_start(), to be sure that io.thread is set */ io.mutex.lock(); diff --git a/src/OutputThread.cxx b/src/OutputThread.cxx index b56e7f1ca..f7e28b5f4 100644 --- a/src/OutputThread.cxx +++ b/src/OutputThread.cxx @@ -31,6 +31,7 @@ #include "MusicPipe.hxx" #include "MusicChunk.hxx" #include "thread/Util.hxx" +#include "thread/Name.hxx" #include "system/FatalError.hxx" #include "util/Error.hxx" #include "Log.hxx" @@ -579,6 +580,8 @@ audio_output_task(void *arg) { struct audio_output *ao = (struct audio_output *)arg; + FormatThreadName("output:%s", ao->name); + SetThreadRealtime(); ao->mutex.lock(); diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx index 8512c6051..750a1732a 100644 --- a/src/PlayerThread.cxx +++ b/src/PlayerThread.cxx @@ -33,6 +33,7 @@ #include "Idle.hxx" #include "GlobalEvents.hxx" #include "util/Domain.hxx" +#include "thread/Name.hxx" #include "Log.hxx" #include @@ -1106,6 +1107,8 @@ player_task(void *arg) { PlayerControl &pc = *(PlayerControl *)arg; + SetThreadName("player"); + DecoderControl dc(pc.mutex, pc.cond); decoder_thread_start(dc); diff --git a/src/thread/Name.hxx b/src/thread/Name.hxx new file mode 100644 index 000000000..a6faa0508 --- /dev/null +++ b/src/thread/Name.hxx @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_THREAD_NAME_HXX +#define MPD_THREAD_NAME_HXX + +#ifdef HAVE_PTHREAD_SETNAME_NP +#include +#include +#endif + +static inline void +SetThreadName(const char *name) +{ +#ifdef HAVE_PTHREAD_SETNAME_NP + pthread_setname_np(pthread_self(), name); +#else + (void)name; +#endif +} + +template +static inline void +FormatThreadName(const char *fmt, gcc_unused Args&&... args) +{ +#ifdef HAVE_PTHREAD_SETNAME_NP + char buffer[16]; + snprintf(buffer, sizeof(buffer), fmt, args...); + SetThreadName(buffer); +#else + (void)fmt; +#endif +} + +#endif