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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/threads/pthr_attr.c
          +++ new/usr/src/lib/libc/port/threads/pthr_attr.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28      - * Copyright 2015, Joyent, Inc.
       28 + * Copyright 2018, Joyent, Inc.
  29   29   */
  30   30  
  31   31  #include "lint.h"
  32   32  #include "thr_uberdata.h"
       33 +#include <sys/ctype.h>
       34 +#include <strings.h>
  33   35  #include <sched.h>
  34   36  
  35   37  /*
  36   38   * Default attribute object for pthread_create() with NULL attr pointer.
  37   39   * Note that the 'guardsize' field is initialized on the first call.
  38   40   */
  39   41  const thrattr_t *
  40   42  def_thrattr(void)
  41   43  {
  42   44          static thrattr_t thrattr = {
  43   45                  0,                              /* stksize */
  44   46                  NULL,                           /* stkaddr */
  45   47                  PTHREAD_CREATE_JOINABLE,        /* detachstate */
  46   48                  PTHREAD_CREATE_NONDAEMON_NP,    /* daemonstate */
  47   49                  PTHREAD_SCOPE_PROCESS,          /* scope */
  48   50                  0,                              /* prio */
  49   51                  SCHED_OTHER,                    /* policy */
  50   52                  PTHREAD_INHERIT_SCHED,          /* inherit */
  51      -                0                               /* guardsize */
       53 +                0,                              /* guardsize */
       54 +                { 0 }                           /* name */
  52   55          };
  53   56          if (thrattr.guardsize == 0)
  54   57                  thrattr.guardsize = _sysconf(_SC_PAGESIZE);
  55   58          return (&thrattr);
  56   59  }
  57   60  
  58   61  /*
  59   62   * pthread_attr_init: allocates the attribute object and initializes it
  60   63   * with the default values.
  61   64   */
↓ open down ↓ 26 lines elided ↑ open up ↑
  88   91  }
  89   92  
  90   93  /*
  91   94   * pthread_attr_clone: make a copy of a pthread_attr_t.
  92   95   */
  93   96  int
  94   97  pthread_attr_clone(pthread_attr_t *attr, const pthread_attr_t *old_attr)
  95   98  {
  96   99          thrattr_t *ap;
  97  100          const thrattr_t *old_ap =
  98      -            old_attr? old_attr->__pthread_attrp : def_thrattr();
      101 +            old_attr ? old_attr->__pthread_attrp : def_thrattr();
  99  102  
 100  103          if (old_ap == NULL)
 101  104                  return (EINVAL);
 102  105          if ((ap = lmalloc(sizeof (thrattr_t))) == NULL)
 103  106                  return (ENOMEM);
 104  107          *ap = *old_ap;
 105  108          attr->__pthread_attrp = ap;
 106  109          return (0);
 107  110  }
 108  111  
 109  112  /*
 110  113   * pthread_attr_equal: compare two pthread_attr_t's, return 1 if equal.
 111  114   * A NULL pthread_attr_t pointer implies default attributes.
 112  115   * This is a consolidation-private interface, for librt.
 113  116   */
 114  117  int
 115  118  pthread_attr_equal(const pthread_attr_t *attr1, const pthread_attr_t *attr2)
 116  119  {
 117      -        const thrattr_t *ap1 = attr1? attr1->__pthread_attrp : def_thrattr();
 118      -        const thrattr_t *ap2 = attr2? attr2->__pthread_attrp : def_thrattr();
      120 +        const thrattr_t *ap1 = attr1 ? attr1->__pthread_attrp : def_thrattr();
      121 +        const thrattr_t *ap2 = attr2 ? attr2->__pthread_attrp : def_thrattr();
 119  122  
 120  123          if (ap1 == NULL || ap2 == NULL)
 121  124                  return (0);
 122  125          return (ap1 == ap2 || memcmp(ap1, ap2, sizeof (thrattr_t)) == 0);
 123  126  }
 124  127  
 125  128  /*
 126  129   * pthread_attr_setstacksize: sets the user stack size, minimum should
 127  130   * be PTHREAD_STACK_MIN (MINSTACK).
 128  131   * This is equivalent to stksize argument in thr_create().
↓ open down ↓ 340 lines elided ↑ open up ↑
 469  472  
 470  473          if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
 471  474              stackaddr != NULL && stacksize != NULL) {
 472  475                  *stackaddr = ap->stkaddr;
 473  476                  *stacksize = ap->stksize;
 474  477                  return (0);
 475  478          }
 476  479          return (EINVAL);
 477  480  }
 478  481  
      482 +int
      483 +pthread_attr_setname_np(pthread_attr_t *attr, const char *name)
      484 +{
      485 +        thrattr_t *ap;
      486 +
      487 +        if (attr == NULL || (ap = attr->__pthread_attrp) == NULL)
      488 +                return (EINVAL);
      489 +
      490 +        if (name == NULL) {
      491 +                bzero(ap->name, sizeof (ap->name));
      492 +                return (0);
      493 +        }
      494 +
      495 +        if (strlen(name) >= sizeof (ap->name))
      496 +                return (ERANGE);
      497 +
      498 +        /*
      499 +         * We really want the ASCII version of isprint() here...
      500 +         */
      501 +        for (size_t i = 0; name[i] != '\0'; i++) {
      502 +                if (!ISPRINT(name[i]))
      503 +                        return (EINVAL);
      504 +        }
      505 +
      506 +        /*
      507 +         * not having garbage after the end of the string simplifies attr
      508 +         * comparison
      509 +         */
      510 +        bzero(ap->name, sizeof (ap->name));
      511 +        (void) strlcpy(ap->name, name, sizeof (ap->name));
      512 +        return (0);
      513 +}
      514 +
      515 +int
      516 +pthread_attr_getname_np(pthread_attr_t *attr, char *buf, size_t len)
      517 +{
      518 +        thrattr_t *ap;
      519 +
      520 +        if (buf == NULL || attr == NULL ||
      521 +            (ap = attr->__pthread_attrp) == NULL)
      522 +                return (EINVAL);
      523 +
      524 +        if (strlcpy(buf, ap->name, len) > len)
      525 +                return (ERANGE);
      526 +        return (0);
      527 +}
      528 +
 479  529  /*
 480  530   * This function is a common BSD extension to pthread which is used to obtain
 481  531   * the attributes of a thread that might have changed after its creation, for
 482  532   * example, it's stack address.
 483  533   *
 484  534   * Note, there is no setattr analogue, nor do we desire to add one at this time.
 485  535   * Similarly there is no native threads API analogue (nor should we add one for
 486  536   * C11).
 487  537   *
 488  538   * The astute reader may note that there is a GNU version of this called
↓ open down ↓ 55 lines elided ↑ open up ↑
 544  594  
 545  595          if (target->ul_usropts & THR_BOUND) {
 546  596                  ap->scope = PTHREAD_SCOPE_SYSTEM;
 547  597          } else {
 548  598                  ap->scope = PTHREAD_SCOPE_PROCESS;
 549  599          }
 550  600          ap->prio = target->ul_pri;
 551  601          ap->policy = target->ul_policy;
 552  602          ap->inherit = target->ul_ptinherit;
 553  603          ap->guardsize = target->ul_guardsize;
      604 +        (void) pthread_getname_np(tid, ap->name, sizeof (ap->name));
 554  605  
 555  606          ret = 0;
 556  607  out:
 557  608          ulwp_unlock(target, udp);
 558  609          return (ret);
 559  610  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX