Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
@@ -23,11 +23,11 @@
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
* Copyright (c) 2017 by The MathWorks, Inc. All rights reserved.
*/
/*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
#include "lint.h"
#include "thr_uberdata.h"
#include <pthread.h>
@@ -558,11 +558,11 @@
return (ulwp);
}
int
_thrp_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
- long flags, thread_t *new_thread, size_t guardsize)
+ long flags, thread_t *new_thread, size_t guardsize, const char *name)
{
ulwp_t *self = curthread;
uberdata_t *udp = self->ul_uberdata;
ucontext_t uc;
uint_t lwp_flags;
@@ -713,10 +713,13 @@
tdb_event(TD_CREATE, udp);
}
exit_critical(self);
+ if (name != NULL)
+ (void) pthread_setname_np(tid, name);
+
if (!(flags & THR_SUSPENDED))
(void) _thrp_continue(tid, TSTP_REGULAR);
return (0);
}
@@ -723,11 +726,12 @@
int
thr_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
long flags, thread_t *new_thread)
{
- return (_thrp_create(stk, stksize, func, arg, flags, new_thread, 0));
+ return (_thrp_create(stk, stksize, func, arg, flags, new_thread, 0,
+ NULL));
}
/*
* A special cancellation cleanup hook for DCE.
* cleanuphndlr, when it is not NULL, will contain a callback
@@ -2396,10 +2400,91 @@
__nthreads(void)
{
return (curthread->ul_uberdata->nthreads);
}
+/* "/proc/self/lwp/%u/lwpname" w/o stdio */
+static void
+lwpname_path(pthread_t tid, char *buf, size_t bufsize)
+{
+ (void) strlcpy(buf, "/proc/self/lwp/", bufsize);
+ ultos((uint64_t)tid, 10, buf + strlen(buf));
+ (void) strlcat(buf, "/lwpname", bufsize);
+}
+
+#pragma weak pthread_setname_np = thr_setname
+int
+thr_setname(pthread_t tid, const char *name)
+{
+ extern ssize_t __write(int, const void *, size_t);
+ char path[PATH_MAX];
+ int saved_errno;
+ size_t len;
+ ssize_t n;
+ int fd;
+
+ if (name == NULL)
+ name = "";
+
+ len = strlen(name) + 1;
+ if (len > THREAD_NAME_MAX)
+ return (ERANGE);
+
+ lwpname_path(tid, path, sizeof (path));
+
+ if ((fd = __open(path, O_WRONLY, 0)) < 0) {
+ if (errno == ENOENT)
+ errno = ESRCH;
+ return (errno);
+ }
+
+ n = __write(fd, name, len);
+ saved_errno = errno;
+ (void) __close(fd);
+
+ if (n < 0)
+ return (saved_errno);
+ if (n != len)
+ return (EFAULT);
+ return (0);
+}
+
+#pragma weak pthread_getname_np = thr_getname
+int
+thr_getname(pthread_t tid, char *buf, size_t bufsize)
+{
+ extern ssize_t __read(int, void *, size_t);
+ char name[THREAD_NAME_MAX];
+ char path[PATH_MAX];
+ int saved_errno;
+ ssize_t n;
+ int fd;
+
+ if (buf == NULL)
+ return (EINVAL);
+
+ lwpname_path(tid, path, sizeof (path));
+
+ if ((fd = __open(path, O_RDONLY, 0)) < 0) {
+ if (errno == ENOENT)
+ errno = ESRCH;
+ return (errno);
+ }
+
+ n = __read(fd, name, sizeof (name));
+ saved_errno = errno;
+ (void) __close(fd);
+
+ if (n < 0)
+ return (saved_errno);
+ if (n != sizeof (name))
+ return (EFAULT);
+ if (strlcpy(buf, name, bufsize) >= bufsize)
+ return (ERANGE);
+ return (0);
+}
+
/*
* XXX
* The remainder of this file implements the private interfaces to java for
* garbage collection. It is no longer used, at least by java 1.2.
* It can all go away once all old JVMs have disappeared.