Add pthread_getname_np and pthread_setname_np

This patch adds pthread_getname_np and pthread_setname_np.

These were added to glibc in 2.12[1] and are also present in some form on
NetBSD and several UNIXes.

The code is based on NetBSD's implementation with changes to better match
Linux behaviour.

Implementation quirks:

* pthread_setname_np with a NULL pointer segfaults (as linux)

* pthread_setname_np returns ERANGE for names longer than 16 characters (as
linux)

* pthread_getname_np with a NULL pointer returns EFAULT (as linux)

* pthread_getname_np with a buffer length of less than 16 returns ERANGE (as
linux)

* pthread_getname_np truncates the thread name to fit the buffer length.
This guarantees success even when the default thread name is longer than 16
characters, but means there is no way to discover the actual length of the
thread name. (Linux always truncates the thread name to 16 characters)

* Changing program_invocation_short_name changes the default thread name (on
linux, it has no effect on the default thread name)

I'll leave it up to you to decide if any of these matter.

This is implemented via class pthread_attr to make it easier to add
pthread_attr_[gs]etname_np (present in NetBSD and some UNIXes) should it
ever be added to Linux (or we decide we want it anyway).

[1] https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS
This commit is contained in:
Jon Turney 2016-08-22 18:43:05 +01:00
parent fb8e88815e
commit fdb7df230d
8 changed files with 78 additions and 2 deletions

View File

@ -1046,6 +1046,7 @@ pthread_exit SIGFE
pthread_getattr_np SIGFE
pthread_getconcurrency SIGFE
pthread_getcpuclockid SIGFE
pthread_getname_np SIGFE
pthread_getschedparam SIGFE
pthread_getsequence_np SIGFE
pthread_getspecific SIGFE
@ -1086,6 +1087,7 @@ pthread_self SIGFE
pthread_setcancelstate SIGFE
pthread_setcanceltype SIGFE
pthread_setconcurrency SIGFE
pthread_setname_np SIGFE
pthread_setschedparam SIGFE
pthread_setschedprio SIGFE
pthread_setspecific SIGFE

View File

@ -467,12 +467,13 @@ details. */
strtoull_l, wcstod_l, wcstof_l, wcstol_l, wcstold_l, wcstoll_l,
wcstoul_l, wcstoull_l.
302: Export nl_langinfo_l.
303: Export pthread_getname_np, pthread_setname_np.
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
sigaltstack, sethostname. */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 302
#define CYGWIN_VERSION_API_MINOR 303
/* There is also a compatibity version number associated with the shared memory
regions. It is incremented when incompatible changes are made to the shared

View File

@ -222,6 +222,8 @@ void pthread_testcancel (void);
#if __GNU_VISIBLE
int pthread_getattr_np (pthread_t, pthread_attr_t *);
int pthread_getname_np (pthread_t, char *, size_t) __attribute__((nonnull(2)));
int pthread_setname_np (pthread_t, const char *) __attribute__((nonnull(2)));
int pthread_sigqueue (pthread_t *, int, const union sigval);
int pthread_yield (void);
#endif

View File

@ -20,6 +20,7 @@ What's new:
- locale(1) now supports a -i/--input option to fetch the current input
locale (this is basically equivalent to the current keyboard layout setting).
- New API: pthread_getname_np, pthread_setname_np.
What changed:
-------------

View File

@ -1106,7 +1106,7 @@ pthread::resume ()
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
inheritsched (PTHREAD_INHERIT_SCHED), stackaddr (NULL), stacksize (0),
guardsize (wincap.def_guard_page_size ())
guardsize (wincap.def_guard_page_size ()), name (NULL)
{
schedparam.sched_priority = 0;
}
@ -2576,6 +2576,69 @@ pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
return 0;
}
/* For Linux compatibility, the length of a thread name is 16 characters. */
#define THRNAMELEN 16
extern "C" int
pthread_getname_np (pthread_t thread, char *buf, size_t buflen)
{
char *name;
if (!pthread::is_good_object (&thread))
return ESRCH;
if (!thread->attr.name)
name = program_invocation_short_name;
else
name = thread->attr.name;
/* Return ERANGE if the provided buffer is less than THRNAMELEN. Truncate
and zero-terminate the name to fit in buf. This means we always return
something if the buffer is THRNAMELEN or larger, but there is no way to
tell if we have the whole name. */
if (buflen < THRNAMELEN)
return ERANGE;
int ret = 0;
__try
{
strlcpy (buf, name, buflen);
}
__except (NO_ERROR)
{
ret = EFAULT;
}
__endtry
return ret;
}
extern "C" int
pthread_setname_np (pthread_t thread, const char *name)
{
char *oldname, *cp;
if (!pthread::is_good_object (&thread))
return ESRCH;
if (strlen (name) > THRNAMELEN)
return ERANGE;
cp = strdup (name);
if (!cp)
return ENOMEM;
oldname = thread->attr.name;
thread->attr.name = cp;
if (oldname)
free (oldname);
return 0;
}
#undef THRNAMELEN
/* provided for source level compatability.
See http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_getconcurrency.html
*/

View File

@ -240,6 +240,7 @@ public:
void *stackaddr;
size_t stacksize;
size_t guardsize;
char *name;
pthread_attr ();
~pthread_attr ();

View File

@ -64,6 +64,10 @@ Support AzureAD accounts.
"nobody" account support for WinFSP.
</para></listitem>
<listitem><para>
New API: pthread_getname_np, pthread_setname_np.
</para></listitem>
</itemizedlist>
</sect2>

View File

@ -1337,6 +1337,8 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
pow10l
ppoll
pthread_getattr_np
pthread_getname_np
pthread_setname_np
pthread_sigqueue
ptsname_r
putwc_unlocked