/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
[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
#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.
{
return -ENOSYS;
}
+
+static inline
+int lttng_pthread_getname_np(char *name, size_t len)
+{
+ return -ENOSYS;
+}
#endif
#endif /* _COMPAT_PTHREAD_H */
#include <common/compat/pthread.h>
#include "thread.h"
-#define LTTNG_PTHREAD_NAMELEN 16
int lttng_thread_setname(const char *name)
{
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 \
# 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 \
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)
--- /dev/null
+/*
+ * 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();
+}