From: Michael Jeanson Date: Thu, 29 Oct 2020 10:09:41 +0000 (-0400) Subject: port: Add pthread_setname_np FreeBSD compat X-Git-Tag: v2.13.0-rc1~432 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=014d7d3b5e9d69989bf776cffb6c21ff7e1d36ff port: Add pthread_setname_np FreeBSD compat Signed-off-by: Michael Jeanson Signed-off-by: Jérémie Galarneau Change-Id: I7ca8334c4ce28bc240c898aeb5a6857ff951143b --- diff --git a/.gitignore b/.gitignore index 9b2b60d04..2032177ea 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,7 @@ compile_commands.json /tests/unit/test_uri /tests/unit/test_ust_data /tests/unit/test_utils_compat_poll +/tests/unit/test_utils_compat_pthread /tests/unit/test_utils_parse_size_suffix /tests/unit/test_utils_parse_time_suffix /tests/unit/test_utils_expand_path diff --git a/m4/lttng_pthread_setname_np.m4 b/m4/lttng_pthread_setname_np.m4 index a8526e8d2..6eff705ba 100644 --- a/m4/lttng_pthread_setname_np.m4 +++ b/m4/lttng_pthread_setname_np.m4 @@ -63,6 +63,18 @@ AC_LINK_IFELSE( [Have function pthread_setname_np(const char*)])], [AC_MSG_RESULT(no)]) +# FreeBSD +AC_MSG_CHECKING(for pthread_set_name_np(pthread_t, const char*)) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include + #include ], + [pthread_set_name_np(pthread_self(), "example")])], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP_WITH_TID,1, + [Have function pthread_set_name_np(pthread_t, const char*)])], + [AC_MSG_RESULT(no)]) + LDFLAGS=$lttng_pthread_setname_np_save_LDFLAGS LIBS=$lttng_pthread_setname_np_save_LIBS diff --git a/src/common/compat/pthread.h b/src/common/compat/pthread.h index 87aa746ba..511ab089b 100644 --- a/src/common/compat/pthread.h +++ b/src/common/compat/pthread.h @@ -10,19 +10,83 @@ #include #include +#include + +#define LTTNG_PTHREAD_NAMELEN 16 #if defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) static inline int lttng_pthread_setname_np(const char *name) { + /* + * Some implementations don't error out, replicate this behavior for + * consistency. + */ + if (strnlen(name, LTTNG_PTHREAD_NAMELEN) >= LTTNG_PTHREAD_NAMELEN) { + return ERANGE; + } + return pthread_setname_np(pthread_self(), name); } + +static inline +int lttng_pthread_getname_np(char *name, size_t len) +{ + return pthread_getname_np(pthread_self(), name, len); +} #elif defined(HAVE_PTHREAD_SETNAME_NP_WITHOUT_TID) static inline int lttng_pthread_setname_np(const char *name) { return pthread_setname_np(name); } + +static inline +int lttng_pthread_getname_np(char *name, size_t len) +{ + return pthread_getname_np(name, len); +} +#elif defined(HAVE_PTHREAD_SET_NAME_NP_WITH_TID) + +#include +static inline +int lttng_pthread_setname_np(const char *name) +{ + /* Replicate pthread_setname_np's behavior. */ + if (strnlen(name, LTTNG_PTHREAD_NAMELEN) >= LTTNG_PTHREAD_NAMELEN) { + return ERANGE; + } + + pthread_set_name_np(pthread_self(), name); + return 0; +} + +static inline +int lttng_pthread_getname_np(char *name, size_t len) +{ + pthread_get_name_np(pthread_self(), name, len); + return 0; +} +#elif defined(__linux__) + +/* Fallback on prtctl on Linux */ +#include + +static inline +int lttng_pthread_setname_np(const char *name) +{ + /* Replicate pthread_setname_np's behavior. */ + if (strnlen(name, LTTNG_UST_ABI_PROCNAME_LEN) >= LTTNG_UST_ABI_PROCNAME_LEN) { + return ERANGE; + } + return prctl(PR_SET_NAME, name, 0, 0, 0); +} + +static inline +int lttng_pthread_getname_np(char *name, size_t len) +{ + return prctl(PR_GET_NAME, name, 0, 0, 0); +} #else /* * For platforms without thread name support, do nothing. @@ -32,6 +96,12 @@ int lttng_pthread_setname_np(const char *name) { return -ENOSYS; } + +static inline +int lttng_pthread_getname_np(char *name, size_t len) +{ + return -ENOSYS; +} #endif #endif /* _COMPAT_PTHREAD_H */ diff --git a/src/common/thread.c b/src/common/thread.c index bbcc1521c..34a620679 100644 --- a/src/common/thread.c +++ b/src/common/thread.c @@ -10,7 +10,6 @@ #include #include "thread.h" -#define LTTNG_PTHREAD_NAMELEN 16 int lttng_thread_setname(const char *name) { diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index a91b4dbd9..8e2703726 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -15,6 +15,7 @@ TESTS = test_kernel_data \ test_utils_parse_time_suffix \ test_utils_expand_path \ test_utils_compat_poll \ + test_utils_compat_pthread \ test_string_utils \ test_notification \ test_event_rule \ @@ -41,7 +42,7 @@ LIBLTTNG_CTL=$(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la # Define test programs noinst_PROGRAMS = test_uri test_session test_kernel_data \ test_utils_parse_size_suffix test_utils_parse_time_suffix \ - test_utils_expand_path test_utils_compat_poll \ + test_utils_expand_path test_utils_compat_poll test_utils_compat_pthread \ test_string_utils test_notification test_directory_handle \ test_relayd_backward_compat_group_by_session \ test_fd_tracker test_uuid \ @@ -178,6 +179,11 @@ test_utils_compat_poll_SOURCES = test_utils_compat_poll.c test_utils_compat_poll_LDADD = $(LIBTAP) $(LIBHASHTABLE) $(DL_LIBS) \ $(top_builddir)/src/common/compat/libcompat.la $(LIBCOMMON) +# compat_pthread unit test +test_utils_compat_pthread_SOURCES = test_utils_compat_pthread.c +test_utils_compat_pthread_LDADD = $(LIBTAP) \ + $(top_builddir)/src/common/compat/libcompat.la $(LIBCOMMON) + # expand_path unit test test_utils_expand_path_SOURCES = test_utils_expand_path.c test_utils_expand_path_LDADD = $(LIBTAP) $(LIBHASHTABLE) $(LIBCOMMON) $(DL_LIBS) diff --git a/tests/unit/test_utils_compat_pthread.c b/tests/unit/test_utils_compat_pthread.c new file mode 100644 index 000000000..d9e59bccd --- /dev/null +++ b/tests/unit/test_utils_compat_pthread.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020 Michael Jeanson + * + * SPDX-License-Identifier: GPL-2.0-only + * + */ + +#include +#include +#include "common/compat/pthread.h" + +#include + +#define TEST_NAME_PROPER_LEN 16 + +int main() +{ + int ret; + char name1[TEST_NAME_PROPER_LEN]; + char name2[TEST_NAME_PROPER_LEN]; + char too_long_name[] = "thisnameistoolong"; + char short_name[] = "labatt50"; + char long_name[] = "procrastinating"; + + plan_tests(10); + + /* Get the initial thread name */ + ret = lttng_pthread_getname_np(name1, TEST_NAME_PROPER_LEN); + ok(ret == 0, "Get the thread name: '%s'", name1); + + /* Set a thread name of more than 16 bytes, should fail */ + ret = lttng_pthread_setname_np(too_long_name); + ok(ret == ERANGE, "Set a too long thread name: '%s'", too_long_name); + + /* Get the thread name again, shouldn't have changed */ + ret = lttng_pthread_getname_np(name2, TEST_NAME_PROPER_LEN); + ok(ret == 0, "Get the thread name: '%s'", name2); + ok(strcmp(name1, name2) == 0, "Compare the initial thread name: '%s' == '%s'", name1, name2); + + /* Set a thread name of less than 16 bytes */ + ret = lttng_pthread_setname_np(short_name); + ok(ret == 0, "Set a short thread name: '%s'", short_name); + + /* Get the thread name again, should be the one we set */ + ret = lttng_pthread_getname_np(name1, TEST_NAME_PROPER_LEN); + ok(ret == 0, "Get a short thread name: '%s'", name1); + ok(strcmp(short_name, name1) == 0, "Compare the short thread name: '%s' == '%s'", short_name, name1); + + + /* Set a thread name of 16 bytes */ + ret = lttng_pthread_setname_np(long_name); + ok(ret == 0, "Set a long thread name: '%s'", long_name); + + /* Get the thread name again, should be the one we set */ + ret = lttng_pthread_getname_np(name1, TEST_NAME_PROPER_LEN); + ok(ret == 0, "Get a long thread name: '%s'", name1); + ok(strncmp(long_name, name1, TEST_NAME_PROPER_LEN - 1) == 0, "Compare the long thread name: '%s' == '%s'", long_name, name1); + + return exit_status(); +}