Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/param.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/signal.h>
  31 #include <sys/stack.h>
  32 #include <sys/pcb.h>
  33 #include <sys/user.h>
  34 #include <sys/systm.h>
  35 #include <sys/sysinfo.h>
  36 #include <sys/errno.h>
  37 #include <sys/cmn_err.h>
  38 #include <sys/cred.h>
  39 #include <sys/resource.h>
  40 #include <sys/task.h>
  41 #include <sys/project.h>
  42 #include <sys/proc.h>
  43 #include <sys/debug.h>
  44 #include <sys/disp.h>


  57 #include <sys/sobject.h>
  58 #include <sys/cpupart.h>
  59 #include <sys/pset.h>
  60 #include <sys/door.h>
  61 #include <sys/spl.h>
  62 #include <sys/copyops.h>
  63 #include <sys/rctl.h>
  64 #include <sys/brand.h>
  65 #include <sys/pool.h>
  66 #include <sys/zone.h>
  67 #include <sys/tsol/label.h>
  68 #include <sys/tsol/tndb.h>
  69 #include <sys/cpc_impl.h>
  70 #include <sys/sdt.h>
  71 #include <sys/reboot.h>
  72 #include <sys/kdi.h>
  73 #include <sys/schedctl.h>
  74 #include <sys/waitq.h>
  75 #include <sys/cpucaps.h>
  76 #include <sys/kiconv.h>

  77 
  78 struct kmem_cache *thread_cache;        /* cache of free threads */
  79 struct kmem_cache *lwp_cache;           /* cache of free lwps */
  80 struct kmem_cache *turnstile_cache;     /* cache of free turnstiles */
  81 
  82 /*
  83  * allthreads is only for use by kmem_readers.  All kernel loops can use
  84  * the current thread as a start/end point.
  85  */
  86 kthread_t *allthreads = &t0;        /* circular list of all threads */
  87 
  88 static kcondvar_t reaper_cv;            /* synchronization var */
  89 kthread_t       *thread_deathrow;       /* circular list of reapable threads */
  90 kthread_t       *lwp_deathrow;          /* circular list of reapable threads */
  91 kmutex_t        reaplock;               /* protects lwp and thread deathrows */
  92 int     thread_reapcnt = 0;             /* number of threads on deathrow */
  93 int     lwp_reapcnt = 0;                /* number of lwps on deathrow */
  94 int     reaplimit = 16;                 /* delay reaping until reaplimit */
  95 
  96 thread_free_lock_t      *thread_free_lock;


 774         kmem_cache_free(turnstile_cache, t->t_ts);
 775 
 776         free_afd(&t->t_activefd);
 777 
 778         /*
 779          * Barrier for the tick accounting code.  The tick accounting code
 780          * holds this lock to keep the thread from going away while it's
 781          * looking at it.
 782          */
 783         thread_free_barrier(t);
 784 
 785         ASSERT(ttoproj(t) == proj0p);
 786         project_rele(ttoproj(t));
 787 
 788         lgrp_affinity_free(&t->t_lgrp_affinity);
 789 
 790         mutex_enter(&pidlock);
 791         nthread--;
 792         mutex_exit(&pidlock);
 793 





 794         /*
 795          * Free thread, lwp and stack.  This needs to be done carefully, since
 796          * if T_TALLOCSTK is set, the thread is part of the stack.
 797          */
 798         t->t_lwp = NULL;
 799         t->t_swap = NULL;
 800 
 801         if (swap) {
 802                 segkp_release(segkp, swap);
 803         }
 804         if (lwp) {
 805                 kmem_cache_free(lwp_cache, lwp);
 806         }
 807         if (!allocstk) {
 808                 kmem_cache_free(thread_cache, t);
 809         }
 810 }
 811 
 812 /*
 813  * Removes threads associated with the given zone from a deathrow queue.


2109                         return (100);
2110                 }
2111                 percent = t_stk - sp + 1;
2112                 s = t_stk - t_stkbase + 1;
2113         } else {
2114                 /* stack grows up */
2115                 if (sp < t_stk) {
2116                         return (0);
2117                 }
2118                 if (sp > t_stkbase) {
2119                         return (100);
2120                 }
2121                 percent = sp - t_stk + 1;
2122                 s = t_stkbase - t_stk + 1;
2123         }
2124         percent = ((100 * percent) / s) + 1;
2125         if (percent > 100) {
2126                 percent = 100;
2127         }
2128         return (percent);








































































2129 }


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2018 Joyent, Inc.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/param.h>
  29 #include <sys/sysmacros.h>
  30 #include <sys/signal.h>
  31 #include <sys/stack.h>
  32 #include <sys/pcb.h>
  33 #include <sys/user.h>
  34 #include <sys/systm.h>
  35 #include <sys/sysinfo.h>
  36 #include <sys/errno.h>
  37 #include <sys/cmn_err.h>
  38 #include <sys/cred.h>
  39 #include <sys/resource.h>
  40 #include <sys/task.h>
  41 #include <sys/project.h>
  42 #include <sys/proc.h>
  43 #include <sys/debug.h>
  44 #include <sys/disp.h>


  57 #include <sys/sobject.h>
  58 #include <sys/cpupart.h>
  59 #include <sys/pset.h>
  60 #include <sys/door.h>
  61 #include <sys/spl.h>
  62 #include <sys/copyops.h>
  63 #include <sys/rctl.h>
  64 #include <sys/brand.h>
  65 #include <sys/pool.h>
  66 #include <sys/zone.h>
  67 #include <sys/tsol/label.h>
  68 #include <sys/tsol/tndb.h>
  69 #include <sys/cpc_impl.h>
  70 #include <sys/sdt.h>
  71 #include <sys/reboot.h>
  72 #include <sys/kdi.h>
  73 #include <sys/schedctl.h>
  74 #include <sys/waitq.h>
  75 #include <sys/cpucaps.h>
  76 #include <sys/kiconv.h>
  77 #include <sys/ctype.h>
  78 
  79 struct kmem_cache *thread_cache;        /* cache of free threads */
  80 struct kmem_cache *lwp_cache;           /* cache of free lwps */
  81 struct kmem_cache *turnstile_cache;     /* cache of free turnstiles */
  82 
  83 /*
  84  * allthreads is only for use by kmem_readers.  All kernel loops can use
  85  * the current thread as a start/end point.
  86  */
  87 kthread_t *allthreads = &t0;        /* circular list of all threads */
  88 
  89 static kcondvar_t reaper_cv;            /* synchronization var */
  90 kthread_t       *thread_deathrow;       /* circular list of reapable threads */
  91 kthread_t       *lwp_deathrow;          /* circular list of reapable threads */
  92 kmutex_t        reaplock;               /* protects lwp and thread deathrows */
  93 int     thread_reapcnt = 0;             /* number of threads on deathrow */
  94 int     lwp_reapcnt = 0;                /* number of lwps on deathrow */
  95 int     reaplimit = 16;                 /* delay reaping until reaplimit */
  96 
  97 thread_free_lock_t      *thread_free_lock;


 775         kmem_cache_free(turnstile_cache, t->t_ts);
 776 
 777         free_afd(&t->t_activefd);
 778 
 779         /*
 780          * Barrier for the tick accounting code.  The tick accounting code
 781          * holds this lock to keep the thread from going away while it's
 782          * looking at it.
 783          */
 784         thread_free_barrier(t);
 785 
 786         ASSERT(ttoproj(t) == proj0p);
 787         project_rele(ttoproj(t));
 788 
 789         lgrp_affinity_free(&t->t_lgrp_affinity);
 790 
 791         mutex_enter(&pidlock);
 792         nthread--;
 793         mutex_exit(&pidlock);
 794 
 795         if (t->t_name != NULL) {
 796                 kmem_free(t->t_name, THREAD_NAME_MAX);
 797                 t->t_name = NULL;
 798         }
 799 
 800         /*
 801          * Free thread, lwp and stack.  This needs to be done carefully, since
 802          * if T_TALLOCSTK is set, the thread is part of the stack.
 803          */
 804         t->t_lwp = NULL;
 805         t->t_swap = NULL;
 806 
 807         if (swap) {
 808                 segkp_release(segkp, swap);
 809         }
 810         if (lwp) {
 811                 kmem_cache_free(lwp_cache, lwp);
 812         }
 813         if (!allocstk) {
 814                 kmem_cache_free(thread_cache, t);
 815         }
 816 }
 817 
 818 /*
 819  * Removes threads associated with the given zone from a deathrow queue.


2115                         return (100);
2116                 }
2117                 percent = t_stk - sp + 1;
2118                 s = t_stk - t_stkbase + 1;
2119         } else {
2120                 /* stack grows up */
2121                 if (sp < t_stk) {
2122                         return (0);
2123                 }
2124                 if (sp > t_stkbase) {
2125                         return (100);
2126                 }
2127                 percent = sp - t_stk + 1;
2128                 s = t_stkbase - t_stk + 1;
2129         }
2130         percent = ((100 * percent) / s) + 1;
2131         if (percent > 100) {
2132                 percent = 100;
2133         }
2134         return (percent);
2135 }
2136 
2137 /*
2138  * NOTE: This will silently truncate a name > THREAD_NAME_MAX - 1 characters
2139  * long.  It is expected that callers (acting on behalf of userland clients)
2140  * will perform any required checks to return the correct error semantics.
2141  * It is also expected callers on behalf of userland clients have done
2142  * any necessary permission checks.
2143  */
2144 int
2145 thread_setname(kthread_t *t, const char *name)
2146 {
2147         char *buf = NULL;
2148 
2149         /*
2150          * We optimistically assume that a thread's name will only be set
2151          * once and so allocate memory in preparation of setting t_name.
2152          * If it turns out a name has already been set, we just discard (free)
2153          * the buffer we just allocated and reuse the current buffer
2154          * (as all should be THREAD_NAME_MAX large).
2155          *
2156          * Such an arrangement means over the lifetime of a kthread_t, t_name
2157          * is either NULL or has one value (the address of the buffer holding
2158          * the current thread name).   The assumption is that most kthread_t
2159          * instances will not have a name assigned, so dynamically allocating
2160          * the memory should minimize the footprint of this feature, but by
2161          * having the buffer persist for the life of the thread, it simplifies
2162          * usage in highly constrained situations (e.g. dtrace).
2163          */
2164         if (name != NULL && name[0] != '\0') {
2165                 for (size_t i = 0; name[i] != '\0'; i++) {
2166                         if (!isprint(name[i]))
2167                                 return (EINVAL);
2168                 }
2169 
2170                 buf = kmem_zalloc(THREAD_NAME_MAX, KM_SLEEP);
2171                 (void) strlcpy(buf, name, THREAD_NAME_MAX);
2172         }
2173 
2174         mutex_enter(&ttoproc(t)->p_lock);
2175         if (t->t_name == NULL) {
2176                 t->t_name = buf;
2177         } else {
2178                 if (buf != NULL) {
2179                         (void) strlcpy(t->t_name, name, THREAD_NAME_MAX);
2180                         kmem_free(buf, THREAD_NAME_MAX);
2181                 } else {
2182                         bzero(t->t_name, THREAD_NAME_MAX);
2183                 }
2184         }
2185         mutex_exit(&ttoproc(t)->p_lock);
2186         return (0);
2187 }
2188 
2189 int
2190 thread_vsetname(kthread_t *t, const char *fmt, ...)
2191 {
2192         char name[THREAD_NAME_MAX];
2193         va_list va;
2194         int rc;
2195 
2196         va_start(va, fmt);
2197         rc = vsnprintf(name, sizeof (name), fmt, va);
2198         va_end(va);
2199 
2200         if (rc < 0)
2201                 return (EINVAL);
2202 
2203         if (rc >= sizeof (name))
2204                 return (ENAMETOOLONG);
2205 
2206         return (thread_setname(t, name));
2207 }