diff options
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 12 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/pthr_attr.c | 61 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/pthread.c | 4 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/thr.c | 91 |
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 |