util: introduce a common interface for setting thread names
authorGarrett Wollman <wollman@csail.mit.edu>
Mon, 11 Jul 2011 10:31:41 +0000 (06:31 -0400)
committerDerrick Brashear <shadow@dementia.org>
Wed, 13 Jul 2011 16:55:22 +0000 (09:55 -0700)
A previous change added support for setting thread names/titles to
viced; this change moves the #ifdef spaghetti to src/util in
preparation for calling it from other places where it would be
useful.  Two functions are defined, one for setting an arbitrary
thread's name (as might be done by the spawning thread) and one
for setting the current thread's name; the latter is also defined as
a macro for non-pthreads compilations so that it can be called
unconditionally (the interface does not reference any
pthread-specific data types).  Note that some platforms, Mac OS X
in particular, do not allow setting the name of a different thread.

The two functions are defined as no-ops for Windows as our pthreads
emulation layer for Windows does not provide the needed mechanism.

Make viced use the new interface.

Change-Id: I58c65a28772d8d188c03d6ff3a6f052889362fb7
Reviewed-on: http://gerrit.openafs.org/4966
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

acinclude.m4
src/util/Makefile.in
src/util/afsutil_prototypes.h
src/util/pthread_threadname.c [new file with mode: 0644]
src/viced/viced.c

index 41a0019..4764f5e 100644 (file)
@@ -1561,6 +1561,39 @@ AC_CHECK_FUNCS([ \
        pthread_set_name_np \
        pthread_setname_np \
 ])
+
+dnl Sadly, there are three different versions of pthread_setname_np.
+dnl Try to cater for all of them.
+if test "$ac_cv_func_pthread_setname_np" = "yes" ; then
+    AC_MSG_CHECKING([for signature of pthread_setname_np])
+    AC_TRY_COMPILE([
+#include <pthread.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+], [pthread_setname_np(pthread_self(), "test", (void *)0)], [
+       AC_MSG_RESULT([three arguments])
+       pthread_setname_np_args=3], [
+       AC_TRY_COMPILE([
+#include <pthread.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+], [pthread_setname_np(pthread_self(), "test")], [
+           AC_MSG_RESULT([two arguments])
+           pthread_setname_np_args=2], [
+           AC_TRY_COMPILE([
+#include <pthread.h>
+#ifdef HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+], [pthread_setname_np("test")], [
+               AC_MSG_RESULT([one argument])
+               pthread_setname_np_args=1], [pthread_setname_np_args=0])
+])
+])
+AC_DEFINE_UNQUOTED([PTHREAD_SETNAME_NP_ARGS], $pthread_setname_np_args, [Number of arguments required by pthread_setname_np() function])
+fi
 LIBS="$save_LIBS"
 
 AC_TYPE_SIGNAL
index a35c241..520ca29 100644 (file)
@@ -17,7 +17,7 @@ objects = assert.o base64.o casestrcpy.o config_file.o ktime.o volparse.o \
         hputil.o kreltime.o get_krbrlm.o uuid.o serverLog.o \
         dirpath.o fileutil.o netutils.o flipbase64.o fstab.o \
         afs_atomlist.o afs_lhash.o pthread_glock.o tabular_output.o \
-        ${REGEX_OBJ}
+        pthread_threadname.o ${REGEX_OBJ}
 
 objects_pic = \
        assert_pic.o \
@@ -42,6 +42,7 @@ objects_pic = \
        afs_lhash_pic.o \
        pthread_glock_pic.o \
        tabular_output_pic.o \
+       pthread_threadname_pic.o \
        ${REGEX_OBJ_PIC}
 
 includes = \
@@ -182,6 +183,9 @@ util_pic.a: ${objects_pic} AFS_component_version_number_pic.o
 pthread_glock.o: ${srcdir}/pthread_glock.c ${includes}
        ${MT_CC} $(COMMON_CFLAGS) ${MT_CFLAGS} -c ${srcdir}/pthread_glock.c
 
+pthread_threadname.o: ${srcdir}/pthread_threadname.c ${includes}
+       ${MT_CC} $(COMMON_CFLAGS) ${MT_CFLAGS} -c ${srcdir}/pthread_threadname.c
+
 ${objects}: ${includes}
 
 AFS_component_version_number_pic.o: AFS_component_version_number.c
@@ -259,6 +263,9 @@ afs_lhash_pic.o: ${srcdir}/afs_lhash.c ${includes}
 pthread_glock_pic.o: ${srcdir}/pthread_glock.c ${includes}
        $(SHD_CCRULE) ${srcdir}/pthread_glock.c
 
+pthread_threadname_pic.o: ${srcdir}/pthread_threadname.c ${includes}
+       $(SHD_CCRULE) ${srcdir}/pthread_threadname.c
+
 tabular_output_pic.o: ${srcdir}/tabular_output.c ${includes}
        $(SHD_CCRULE) ${srcdir}/tabular_output.c
 
index b7b6add..1505386 100644 (file)
@@ -144,6 +144,20 @@ extern int parseNetFiles(afs_uint32 addrbuf[], afs_uint32 maskbuf[],
 /* pthread_glock.c */
 
 
+/* pthread_threadname.c */
+#if AFS_PTHREAD_ENV && !defined(AFS_NT40_ENV)
+extern void afs_pthread_setname(pthread_t thread, const char *threadname);
+extern void afs_pthread_setname_self(const char *threadname);
+#elif defined(AFS_NT40_ENV)
+# define afs_pthread_setname(thread, threadname) (void)0
+# define afs_pthread_setname_self(threadname) (void)0
+#else
+/* Allow unconditional references to afs_pthread_setname_self to
+ * reduce #ifdef spaghetti.
+ */
+#define afs_pthread_setname_self(threadname) (void)0
+#endif
+
 /* readdir_nt.c */
 
 
diff --git a/src/util/pthread_threadname.c b/src/util/pthread_threadname.c
new file mode 100644 (file)
index 0000000..952e5a2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * This file, written by Garrett Wollman <wollman@bimajority.org>, is
+ * in the public domain.
+ */
+#include <afsconfig.h>
+#include <afs/param.h>
+
+#include "afsutil.h"
+
+#if AFS_PTHREAD_ENV && !defined(AFS_NT40_ENV)
+# include <pthread.h>
+# ifdef HAVE_PTHREAD_NP_H
+#  include <pthread_np.h>
+# endif
+
+void
+afs_pthread_setname(pthread_t thread, const char *threadname)
+{
+# if defined(HAVE_PTHREAD_SET_NAME_NP)
+       /* FreeBSD style */
+       pthread_set_name_np(thread, threadname);
+# elif defined(HAVE_PTHREAD_SETNAME_NP)
+#  if PTHREAD_SETNAME_NP_ARGS == 3
+       /* DECthreads style */
+       pthread_setname_np(thread, threadname, (void *)0);
+#  elif PTHREAD_SETNAME_NP_ARGS == 2
+       /* GNU libc on Linux style */
+       pthread_setname_np(thread, threadname);
+#  elif PTHREAD_SETNAME_NP_ARGS == 1
+       /* Mac OS style */
+       if (thread == pthread_self())
+               pthread_setname_np(threadname);
+#  else
+#    error "Could not identify your pthread_setname_np() implementation"
+#  endif
+# endif
+}
+
+void
+afs_pthread_setname_self(const char *threadname)
+{
+       afs_pthread_setname(pthread_self(), threadname);
+}
+#endif
index d107244..bfcb629 100644 (file)
@@ -75,9 +75,6 @@
 #include "host.h"
 #ifdef AFS_PTHREAD_ENV
 # include <afs/softsig.h>
-# ifdef HAVE_PTHREAD_NP_H
-#  include <pthread_np.h>
-# endif /* HAVE_PTHREAD_NP_H */
 #endif
 #if defined(AFS_SGI_ENV)
 # include "sys/schedctl.h"
@@ -419,14 +416,7 @@ setThreadId(char *s)
     /* set our 'thread-id' so that the host hold table works */
     pthread_setspecific(rx_thread_id_key,
                        (void *)(intptr_t)rx_NewThreadId());
-# if defined(HAVE_PTHREAD_SET_NAME_NP)
-    /* The "NP" stands for "non-portable" so it's only just that
-     * implementations disagree about the name of the function.
-     */
-    pthread_set_name_np(pthread_self(), s);
-# elif defined(HAVE_PTHREAD_SETNAME_NP)
-    pthread_setname_np(pthread_self(), s);
-# endif
+    afs_pthread_setname_self(s);
     ViceLog(0,
            ("Set thread id %p for '%s'\n",
             pthread_getspecific(rx_thread_id_key), s));