Skip to content

Commit

Permalink
[core] Detect pthread_getname* availability
Browse files Browse the repository at this point in the history
  • Loading branch information
jlsantiago0 authored and maxsharabayko committed Aug 31, 2021
1 parent 4fc0f31 commit 409a40d
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ if (DEFINED HAVE_INET_PTON)
add_definitions(-DHAVE_INET_PTON=1)
endif()

include(FindPThreadGetSetName)
FindPThreadGetSetName() # Defines HAVE_PTHREAD_GETNAME_* and HAVE_PTHREAD_SETNAME_*

if (ENABLE_MONOTONIC_CLOCK)
if (NOT ENABLE_MONOTONIC_CLOCK_DEFAULT)
message(FATAL_ERROR "Your platform does not support CLOCK_MONOTONIC. Build with -DENABLE_MONOTONIC_CLOCK=OFF.")
Expand Down
82 changes: 82 additions & 0 deletions scripts/FindPThreadGetSetName.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

# Check for pthread_getname_np(3) and pthread_setname_np(3)
# used in srtcore/threadname.h.
#
# Some BSD distros need to include <pthread_np.h> for pthread_getname_np().
#
# TODO: Some BSD distros have pthread_get_name_np() and pthread_set_name_np()
# instead of pthread_getname_np() and pthread_setname_np().
#
# Sets:
# HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H
# HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H
# HAVE_PTHREAD_GETNAME_NP
# HAVE_PTHREAD_SETNAME_NP
# Sets as appropriate:
# add_definitions(-DHAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H=1)
# add_definitions(-DHAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H=1)
# add_definitions(-DHAVE_PTHREAD_GETNAME_NP=1)
# add_definitions(-DHAVE_PTHREAD_SETNAME_NP=1)

include(CheckSymbolExists)

function(FindPThreadGetSetName)

unset(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
unset(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H PARENT_SCOPE)
unset(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H CACHE)
unset(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
unset(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H PARENT_SCOPE)
unset(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H CACHE)

unset(HAVE_PTHREAD_GETNAME_NP)
unset(HAVE_PTHREAD_GETNAME_NP PARENT_SCOPE)
unset(HAVE_PTHREAD_GETNAME_NP CACHE)
unset(HAVE_PTHREAD_SETNAME_NP)
unset(HAVE_PTHREAD_SETNAME_NP PARENT_SCOPE)
unset(HAVE_PTHREAD_SETNAME_NP CACHE)

set(CMAKE_REQUIRED_DEFINITIONS
-D_GNU_SOURCE -D_DARWIN_C_SOURCE -D_POSIX_SOURCE=1)
set(CMAKE_REQUIRED_FLAGS "-pthread")

message(STATUS "Checking for pthread_(g/s)etname_np in 'pthread_np.h':")
check_symbol_exists(
pthread_getname_np "pthread_np.h" HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
if (HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
add_definitions(-DHAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H=1)
endif()
check_symbol_exists(
pthread_setname_np "pthread_np.h" HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
if (HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
add_definitions(-DHAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H=1)
endif()

message(STATUS "Checking for pthread_(g/s)etname_np in 'pthread.h':")
check_symbol_exists(pthread_getname_np "pthread.h" HAVE_PTHREAD_GETNAME_NP)
if (HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
set(HAVE_PTHREAD_GETNAME_NP TRUE PARENT_SCOPE)
endif()
check_symbol_exists(pthread_setname_np "pthread.h" HAVE_PTHREAD_SETNAME_NP)
if (HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
set(HAVE_PTHREAD_SETNAME_NP TRUE PARENT_SCOPE)
endif()
if (HAVE_PTHREAD_GETNAME_NP)
add_definitions(-DHAVE_PTHREAD_GETNAME_NP=1)
endif()
if (HAVE_PTHREAD_SETNAME_NP)
add_definitions(-DHAVE_PTHREAD_SETNAME_NP=1)
endif()

unset(CMAKE_REQUIRED_DEFINITIONS)
unset(CMAKE_REQUIRED_FLAGS)

endfunction(FindPThreadGetSetName)
2 changes: 1 addition & 1 deletion srtcore/srt_attr_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ used by SRT library internally.
#define SRT_ATTR_NO_THREAD_SAFETY_ANALYSIS
#else

#if defined(__clang__)
#if defined(__clang__) && defined(__clang_major__) && (__clang_major__ > 5)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
Expand Down
57 changes: 48 additions & 9 deletions srtcore/threadname.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,60 @@ written by
#ifndef INC_SRT_THREADNAME_H
#define INC_SRT_THREADNAME_H

#if defined(__APPLE__) || defined(__linux__)
#if defined(__linux__)
#include <sys/prctl.h>
// NOTE:
// HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H
// HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H
// HAVE_PTHREAD_GETNAME_NP
// HAVE_PTHREAD_GETNAME_NP
// Are detected and set in ../CMakeLists.txt.
// OS Availability of pthread_getname_np(..) and pthread_setname_np(..)::
// MacOS(10.6)
// iOS(3.2)
// AIX(7.1)
// FreeBSD(version?), OpenBSD(Version?)
// Linux-GLIBC(GLIBC-2.12).
// Linux-MUSL(MUSL-1.1.20 Partial Implementation. See below).
// MINGW-W64(4.0.6)

#if defined(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H) \
|| defined(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
#include <pthread_np.h>
#if defined(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H) \
&& !defined(HAVE_PTHREAD_GETNAME_NP)
#define HAVE_PTHREAD_GETNAME_NP 1
#endif
#if defined(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H) \
&& !defined(HAVE_PTHREAD_SETNAME_NP)
#define HAVE_PTHREAD_SETNAME_NP 1
#endif
#endif

#include <pthread.h>
#if (defined(HAVE_PTHREAD_GETNAME_NP) && defined(HAVE_PTHREAD_GETNAME_NP)) \
|| defined(__linux__)
// NOTE:
// Linux pthread_getname_np() and pthread_setname_np() became available
// in GLIBC-2.12 and later.
// Some Linux runtimes do not have pthread_getname_np(), but have
// pthread_setname_np(), for instance MUSL at least as of v1.1.20.
// So using the prctl() for Linux is more portable.
#if defined(__linux__)
#include <sys/prctl.h>
#endif
#include <pthread.h>
#endif

#include <cstdio>
#include <cstring>
#include <string>

#include "common.h"
#include "sync.h"

class ThreadName
{

#if defined(__APPLE__) || defined(__linux__)
#if (defined(HAVE_PTHREAD_GETNAME_NP) && defined(HAVE_PTHREAD_GETNAME_NP)) \
|| defined(__linux__)

class ThreadNameImpl
{
Expand All @@ -47,8 +83,7 @@ class ThreadName
// since Linux 2.6.11. The buffer should allow space for up to 16
// bytes; the returned string will be null-terminated.
return prctl(PR_GET_NAME, (unsigned long)namebuf, 0, 0) != -1;
#elif defined(__APPLE__)
// since macos(10.6), ios(3.2)
#elif defined(HAVE_PTHREAD_GETNAME_NP)
return pthread_getname_np(pthread_self(), namebuf, BUFSIZE) == 0;
#else
#error "unsupported platform"
Expand All @@ -57,14 +92,18 @@ class ThreadName

static bool set(const char* name)
{
SRT_ASSERT(name != NULL);
#if defined(__linux__)
// The name can be up to 16 bytes long, including the terminating
// null byte. (If the length of the string, including the terminating
// null byte, exceeds 16 bytes, the string is silently truncated.)
return prctl(PR_SET_NAME, (unsigned long)name, 0, 0) != -1;
#elif defined(__APPLE__)
// since macos(10.6), ios(3.2)
#elif defined(HAVE_PTHREAD_SETNAME_NP)
#if defined(__APPLE__)
return pthread_setname_np(name) == 0;
#else
return pthread_setname_np(pthread_self(), name) == 0;
#endif
#else
#error "unsupported platform"
#endif
Expand Down

0 comments on commit 409a40d

Please sign in to comment.