Skip to content

Commit f1857e3

Browse files
committed
Refactor ThreadName() to improve its portability
* Test for the presence of pthread_getname_np() during cmake time and only use it if it is available. At least FreeBSD does not have it. * Similar with pthread_threadid_np() - use it only if it is available. Also detect and possibly use pthread_getthreadid_np(). Fallback to C++11 standard way to retrieve a thread id if none of the others are available. C++11 thread ids are longer and different than the ones printed by gdb. * According to pthread_getname_np(3) the thread name length is restricted to 16 characters, including the terminating null byte. So reduce our thread_name[] from 17 to 16 chars.
1 parent fe76b28 commit f1857e3

File tree

3 files changed

+62
-6
lines changed

3 files changed

+62
-6
lines changed

CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,43 @@
44

55
cmake_minimum_required(VERSION 3.0)
66
project("Libmultiprocess" CXX)
7+
include(CMakePushCheckState)
78
include(CTest)
9+
include(CheckCXXSourceCompiles)
810
find_package(Boost)
911
find_package(CapnProto)
12+
find_package(Threads REQUIRED)
13+
14+
cmake_push_check_state()
15+
set(CMAKE_REQUIRED_LIBRARIES Threads::Threads)
16+
check_cxx_source_compiles("
17+
#include <pthread.h>
18+
int main(int argc, char** argv)
19+
{
20+
char thread_name[16];
21+
return pthread_getname_np(pthread_self(), thread_name, sizeof(thread_name));
22+
}"
23+
HAVE_PTHREAD_GETNAME_NP)
24+
25+
check_cxx_source_compiles("
26+
#include <pthread.h>
27+
int main(int argc, char** argv)
28+
{
29+
uint64_t tid;
30+
pthread_threadid_np(NULL, &tid);
31+
return 0;
32+
}"
33+
HAVE_PTHREAD_THREADID_NP)
34+
35+
check_cxx_source_compiles("
36+
#include <pthread.h>
37+
#include <pthread_np.h>
38+
int main(int argc, char** argv)
39+
{
40+
return pthread_getthreadid_np();
41+
}"
42+
HAVE_PTHREAD_GETTHREADID_NP)
43+
cmake_pop_check_state()
1044

1145
capnp_generate_cpp(MP_PROXY_SRCS MP_PROXY_HDRS include/mp/proxy.capnp)
1246

include/mp/config.h.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@
88
#cmakedefine CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
99
#cmakedefine capnp_PREFIX "@capnp_PREFIX@"
1010

11+
#cmakedefine HAVE_PTHREAD_GETNAME_NP @HAVE_PTHREAD_GETNAME_NP@
12+
#cmakedefine HAVE_PTHREAD_THREADID_NP @HAVE_PTHREAD_THREADID_NP@
13+
#cmakedefine HAVE_PTHREAD_GETTHREADID_NP @HAVE_PTHREAD_GETTHREADID_NP@
14+
1115
#endif // MP_CONFIG_H

src/mp/util.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <mp/config.h>
56
#include <mp/util.h>
67

78
#include <kj/array.h>
@@ -13,12 +14,17 @@
1314
#include <sys/types.h>
1415
#include <sys/un.h>
1516
#include <sys/wait.h>
17+
#include <thread>
1618
#include <unistd.h>
1719

1820
#if __linux__
1921
#include <syscall.h>
2022
#endif
2123

24+
#ifdef HAVE_PTHREAD_GETTHREADID_NP
25+
#include <pthread_np.h>
26+
#endif // HAVE_PTHREAD_GETTHREADID_NP
27+
2228
namespace mp {
2329
namespace {
2430

@@ -37,16 +43,28 @@ size_t MaxFd()
3743

3844
std::string ThreadName(const char* exe_name)
3945
{
40-
char thread_name[17] = {0};
46+
char thread_name[16] = {0};
47+
#ifdef HAVE_PTHREAD_GETNAME_NP
4148
pthread_getname_np(pthread_self(), thread_name, sizeof(thread_name));
42-
uint64_t tid = 0;
49+
#endif // HAVE_PTHREAD_GETNAME_NP
50+
51+
std::ostringstream buffer;
52+
buffer << (exe_name ? exe_name : "") << "-" << getpid() << "/" << thread_name << "-";
53+
54+
// Prefer platform specific thread ids over the standard C++11 ones because
55+
// the former are shorter and are the same as what gdb prints "LWP ...".
4356
#if __linux__
44-
tid = syscall(SYS_gettid);
45-
#else
57+
buffer << syscall(SYS_gettid);
58+
#elif defined(HAVE_PTHREAD_THREADID_NP)
59+
uint64_t tid = 0;
4660
pthread_threadid_np(NULL, &tid);
61+
buffer << tid;
62+
#elif defined(HAVE_PTHREAD_GETTHREADID_NP)
63+
buffer << pthread_getthreadid_np();
64+
#else
65+
buffer << std::this_thread::get_id();
4766
#endif
48-
std::ostringstream buffer;
49-
buffer << (exe_name ? exe_name : "") << "-" << getpid() << "/" << thread_name << "-" << tid;
67+
5068
return std::move(buffer.str());
5169
}
5270

0 commit comments

Comments
 (0)