port: Add pthread_setname_np FreeBSD compat
authorMichael Jeanson <mjeanson@efficios.com>
Thu, 29 Oct 2020 10:09:41 +0000 (06:09 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 9 Nov 2020 20:49:38 +0000 (15:49 -0500)
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I7ca8334c4ce28bc240c898aeb5a6857ff951143b

.gitignore
m4/lttng_pthread_setname_np.m4
src/common/compat/pthread.h
src/common/thread.c
tests/unit/Makefile.am
tests/unit/test_utils_compat_pthread.c [new file with mode: 0644]

index 9b2b60d041f643092e3117287bc8ed9ebc0c27f3..2032177eabfb1c0e25110a641ba22ac9a416ba9d 100644 (file)
@@ -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
index a8526e8d23eac3985a3d0bcb068fafe5343ab261..6eff705baa3b7a6d00f4c480d19f3c02f7d2b5b1 100644 (file)
@@ -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 <pthread.h>
+        #include <pthread_np.h>],
+        [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
 
index 87aa746ba13e68e624b57d1c433d0da0c44d2c61..511ab089b3ed975c00cbb84e229b9c17c2bb2e22 100644 (file)
 
 #include <pthread.h>
 #include <common/compat/errno.h>
+#include <string.h>
+
+#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 <pthread_np.h>
+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 <sys/prctl.h>
+
+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 */
index bbcc1521cc5de8f4e2bc670e205e7b968d5bd4e4..34a620679d258a1e72035416f67ed85310473ba4 100644 (file)
@@ -10,7 +10,6 @@
 #include <common/compat/pthread.h>
 #include "thread.h"
 
-#define LTTNG_PTHREAD_NAMELEN 16
 
 int lttng_thread_setname(const char *name)
 {
index a91b4dbd92682f01ccb5a891d21222a5de080001..8e2703726e9d8e64bf88e9c8377abb25314585dd 100644 (file)
@@ -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 (file)
index 0000000..d9e59bc
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "common/compat/pthread.h"
+
+#include <tap/tap.h>
+
+#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();
+}
This page took 0.040346 seconds and 4 git commands to generate.