summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h4
-rw-r--r--usr/src/lib/libc/port/mapfile-vers12
-rw-r--r--usr/src/lib/libc/port/threads/pthr_attr.c61
-rw-r--r--usr/src/lib/libc/port/threads/pthread.c4
-rw-r--r--usr/src/lib/libc/port/threads/thr.c91
5 files changed, 160 insertions, 12 deletions
diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h
index 81781fe04c..c9e2670cc4 100644
--- a/usr/src/lib/libc/inc/thr_uberdata.h
+++ b/usr/src/lib/libc/inc/thr_uberdata.h
@@ -57,6 +57,7 @@
#include <sys/priocntl.h>
#include <thread_db.h>
#include <setjmp.h>
+#include <sys/thread.h>
#include "libc_int.h"
#include "tdb_agent.h"
#include "thr_debug.h"
@@ -1233,6 +1234,7 @@ typedef struct _thrattr {
int policy;
int inherit;
size_t guardsize;
+ char name[THREAD_NAME_MAX];
} thrattr_t;
typedef struct _rwlattr {
@@ -1492,7 +1494,7 @@ extern int rw_read_held(rwlock_t *);
extern int rw_write_held(rwlock_t *);
extern int _thrp_create(void *, size_t, void *(*)(void *), void *, long,
- thread_t *, size_t);
+ thread_t *, size_t, const char *);
extern int _thrp_suspend(thread_t, uchar_t);
extern int _thrp_continue(thread_t, uchar_t);
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 953a08f833..ba79795325 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -23,7 +23,7 @@
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2018 Nexenta Systems, Inc.
# Copyright (c) 2012 by Delphix. All rights reserved.
-# Copyright 2016 Joyent, Inc.
+# Copyright 2018 Joyent, Inc.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright (c) 2013 Gary Mills
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
@@ -77,6 +77,16 @@ $if _x86 && _ELF64
$add amd64
$endif
+SYMBOL_VERSION ILLUMOS_0.28 {
+ protected:
+ pthread_attr_getname_np;
+ pthread_attr_setname_np;
+ pthread_getname_np;
+ pthread_setname_np;
+ thr_getname;
+ thr_setname;
+} ILLUMOS_0.27;
+
SYMBOL_VERSION ILLUMOS_0.27 { # memset_s(3C) and set_constraint_handler_s(3C)
protected:
abort_handler_s;
diff --git a/usr/src/lib/libc/port/threads/pthr_attr.c b/usr/src/lib/libc/port/threads/pthr_attr.c
index b04bcdba7c..7cfc970120 100644
--- a/usr/src/lib/libc/port/threads/pthr_attr.c
+++ b/usr/src/lib/libc/port/threads/pthr_attr.c
@@ -25,11 +25,13 @@
*/
/*
- * Copyright 2015, Joyent, Inc.
+ * Copyright 2018, Joyent, Inc.
*/
#include "lint.h"
#include "thr_uberdata.h"
+#include <sys/ctype.h>
+#include <strings.h>
#include <sched.h>
/*
@@ -48,7 +50,8 @@ def_thrattr(void)
0, /* prio */
SCHED_OTHER, /* policy */
PTHREAD_INHERIT_SCHED, /* inherit */
- 0 /* guardsize */
+ 0, /* guardsize */
+ { 0 } /* name */
};
if (thrattr.guardsize == 0)
thrattr.guardsize = _sysconf(_SC_PAGESIZE);
@@ -95,7 +98,7 @@ pthread_attr_clone(pthread_attr_t *attr, const pthread_attr_t *old_attr)
{
thrattr_t *ap;
const thrattr_t *old_ap =
- old_attr? old_attr->__pthread_attrp : def_thrattr();
+ old_attr ? old_attr->__pthread_attrp : def_thrattr();
if (old_ap == NULL)
return (EINVAL);
@@ -114,8 +117,8 @@ pthread_attr_clone(pthread_attr_t *attr, const pthread_attr_t *old_attr)
int
pthread_attr_equal(const pthread_attr_t *attr1, const pthread_attr_t *attr2)
{
- const thrattr_t *ap1 = attr1? attr1->__pthread_attrp : def_thrattr();
- const thrattr_t *ap2 = attr2? attr2->__pthread_attrp : def_thrattr();
+ const thrattr_t *ap1 = attr1 ? attr1->__pthread_attrp : def_thrattr();
+ const thrattr_t *ap2 = attr2 ? attr2->__pthread_attrp : def_thrattr();
if (ap1 == NULL || ap2 == NULL)
return (0);
@@ -476,6 +479,53 @@ pthread_attr_getstack(const pthread_attr_t *attr,
return (EINVAL);
}
+int
+pthread_attr_setname_np(pthread_attr_t *attr, const char *name)
+{
+ thrattr_t *ap;
+
+ if (attr == NULL || (ap = attr->__pthread_attrp) == NULL)
+ return (EINVAL);
+
+ if (name == NULL) {
+ bzero(ap->name, sizeof (ap->name));
+ return (0);
+ }
+
+ if (strlen(name) >= sizeof (ap->name))
+ return (ERANGE);
+
+ /*
+ * We really want the ASCII version of isprint() here...
+ */
+ for (size_t i = 0; name[i] != '\0'; i++) {
+ if (!ISPRINT(name[i]))
+ return (EINVAL);
+ }
+
+ /*
+ * not having garbage after the end of the string simplifies attr
+ * comparison
+ */
+ bzero(ap->name, sizeof (ap->name));
+ (void) strlcpy(ap->name, name, sizeof (ap->name));
+ return (0);
+}
+
+int
+pthread_attr_getname_np(pthread_attr_t *attr, char *buf, size_t len)
+{
+ thrattr_t *ap;
+
+ if (buf == NULL || attr == NULL ||
+ (ap = attr->__pthread_attrp) == NULL)
+ return (EINVAL);
+
+ if (strlcpy(buf, ap->name, len) > len)
+ return (ERANGE);
+ return (0);
+}
+
/*
* This function is a common BSD extension to pthread which is used to obtain
* the attributes of a thread that might have changed after its creation, for
@@ -551,6 +601,7 @@ pthread_attr_get_np(pthread_t tid, pthread_attr_t *attr)
ap->policy = target->ul_policy;
ap->inherit = target->ul_ptinherit;
ap->guardsize = target->ul_guardsize;
+ (void) pthread_getname_np(tid, ap->name, sizeof (ap->name));
ret = 0;
out:
diff --git a/usr/src/lib/libc/port/threads/pthread.c b/usr/src/lib/libc/port/threads/pthread.c
index 6a22995639..34b4b4c73c 100644
--- a/usr/src/lib/libc/port/threads/pthread.c
+++ b/usr/src/lib/libc/port/threads/pthread.c
@@ -24,7 +24,7 @@
* Use is subject to license terms.
*/
/*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
#include "lint.h"
@@ -128,7 +128,7 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
flag = ap->scope | ap->detachstate | ap->daemonstate | THR_SUSPENDED;
error = _thrp_create(ap->stkaddr, ap->stksize, start_routine, arg,
- flag, &tid, ap->guardsize);
+ flag, &tid, ap->guardsize, ap->name);
if (error == 0) {
/*
* Record the original inheritence value for
diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c
index 640c1c9645..e849b19e6d 100644
--- a/usr/src/lib/libc/port/threads/thr.c
+++ b/usr/src/lib/libc/port/threads/thr.c
@@ -25,7 +25,7 @@
* Copyright (c) 2017 by The MathWorks, Inc. All rights reserved.
*/
/*
- * Copyright 2016 Joyent, Inc.
+ * Copyright 2018 Joyent, Inc.
*/
#include "lint.h"
@@ -560,7 +560,7 @@ find_lwp(thread_t tid)
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;
@@ -715,6 +715,9 @@ _thrp_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
exit_critical(self);
+ if (name != NULL)
+ (void) pthread_setname_np(tid, name);
+
if (!(flags & THR_SUSPENDED))
(void) _thrp_continue(tid, TSTP_REGULAR);
@@ -725,7 +728,8 @@ 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));
}
/*
@@ -2398,6 +2402,87 @@ __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