(linenum→info "unix/slp.c:2238")

glibc/2.7/nptl_db/td_thr_get_info.c

    1: /* Get thread information.
    2:    Copyright (C) 1999,2000,2001,2002,2003,2007 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #include <stddef.h>
   22: #include <string.h>
   23: #include "thread_dbP.h"
   24: 
   25: 
   26: td_err_e
   27: td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
   28: {
   29:   td_err_e err;
   30:   void *copy;
   31:   psaddr_t tls, schedpolicy, schedprio, cancelhandling, tid, report_events;
   32: 
   33:   LOG ("td_thr_get_info");
   34: 
   35:   if (th->th_unique == 0)
   36:     {
   37:       /* Special case for the main thread before initialization.  */
   38:       copy = NULL;
   39:       tls = 0;
   40:       cancelhandling = 0;
   41:       schedprio = 0;
   42:       tid = 0;
   43:       err = DB_GET_VALUE (report_events, th->th_ta_p,
   44:                           __nptl_initial_report_events, 0);
   45:     }
   46:   else
   47:     {
   48:       /* Copy the whole descriptor in once so we can access the several
   49:          fields locally.  Excess copying in one go is much better than
   50:          multiple ps_pdread calls.  */
   51:       err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread);
   52:       if (err != TD_OK)
   53:         return err;
   54: 
   55:       err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique,
   56:                                   pthread, specific, 0);
   57:       if (err != TD_OK)
   58:         return err;
   59: 
   60:       err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread,
   61:                                 schedpolicy, 0);
   62:       if (err != TD_OK)
   63:         return err;
   64:       err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread,
   65:                                 schedparam_sched_priority, 0);
   66:       if (err != TD_OK)
   67:         return err;
   68:       err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0);
   69:       if (err != TD_OK)
   70:         return err;
   71:       err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread,
   72:                                 cancelhandling, 0);
   73:       if (err != TD_OK)
   74:         return err;
   75:       err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread,
   76:                                 report_events, 0);
   77:     }
   78:   if (err != TD_OK)
   79:     return err;
   80: 
   81:   /* Fill in information.  Clear first to provide reproducable
   82:      results for the fields we do not fill in.  */
   83:   memset (infop, '\0', sizeof (td_thrinfo_t));
   84: 
   85:   infop->ti_tid = (thread_t) th->th_unique;
   86:   infop->ti_tls = (char *) tls;
   87:   infop->ti_pri = ((uintptr_t) schedpolicy == SCHED_OTHER
   88:                    ? 0 : (uintptr_t) schedprio);
   89:   infop->ti_type = TD_THR_USER;
   90: 
   91:   if ((((int) (uintptr_t) cancelhandling) & EXITING_BITMASK) == 0)
   92:     /* XXX For now there is no way to get more information.  */
   93:     infop->ti_state = TD_THR_ACTIVE;
   94:   else if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
   95:     infop->ti_state = TD_THR_ZOMBIE;
   96:   else
   97:     infop->ti_state = TD_THR_UNKNOWN;
   98: 
   99:   /* Initialization which are the same in both cases.  */
  100:   infop->ti_ta_p = th->th_ta_p;
  101:   infop->ti_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid;
  102:   infop->ti_traceme = report_events != 0;
  103: 
  104:   if (copy != NULL)
  105:     err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
  106:                               start_routine, 0);
  107:   if (copy != NULL && err == TD_OK)
  108:     {
  109:       uint32_t idx;
  110:       for (idx = 0; idx < TD_EVENTSIZE; ++idx)
  111:         {
  112:           psaddr_t word;
  113:           err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy, pthread,
  114:                                     eventbuf_eventmask_event_bits, idx);
  115:           if (err != TD_OK)
  116:             break;
  117:           infop->ti_events.event_bits[idx] = (uintptr_t) word;
  118:         }
  119:       if (err == TD_NOAPLIC)
  120:         memset (&infop->ti_events.event_bits[idx], 0,
  121:                 (TD_EVENTSIZE - idx) * sizeof infop->ti_events.event_bits[0]);
  122:     }
  123: 
  124:   return err;
  125: }
Syntax (Markdown)