diff options
Diffstat (limited to 'libpthread/nptl_db/td_thr_get_info.c')
| -rw-r--r-- | libpthread/nptl_db/td_thr_get_info.c | 110 | 
1 files changed, 110 insertions, 0 deletions
| diff --git a/libpthread/nptl_db/td_thr_get_info.c b/libpthread/nptl_db/td_thr_get_info.c new file mode 100644 index 000000000..bb1388804 --- /dev/null +++ b/libpthread/nptl_db/td_thr_get_info.c @@ -0,0 +1,110 @@ +/* Get thread information. +   Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +   This file is part of the GNU C Library. +   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999. + +   The GNU C Library is free software; you can redistribute it and/or +   modify it under the terms of the GNU Lesser General Public +   License as published by the Free Software Foundation; either +   version 2.1 of the License, or (at your option) any later version. + +   The GNU C Library is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public +   License along with the GNU C Library; if not, write to the Free +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +   02111-1307 USA.  */ + +#include <stddef.h> +#include <string.h> +#include "thread_dbP.h" + + +td_err_e +td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop) +{ +  td_err_e err; +  void *copy; +  psaddr_t tls, schedpolicy, schedprio, cancelhandling, tid, report_events; + +  LOG ("td_thr_get_info"); + +  /* Copy the whole descriptor in once so we can access the several +     fields locally.  Excess copying in one go is much better than +     multiple ps_pdread calls.  */ +  err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread); +  if (err != TD_OK) +    return err; + +  err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique, +			      pthread, specific, 0); +  if (err != TD_OK) +    return err; + +  err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread, +			    schedpolicy, 0); +  if (err != TD_OK) +    return err; +  err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread, +			    schedparam_sched_priority, 0); +  if (err != TD_OK) +    return err; +  err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0); +  if (err != TD_OK) +    return err; +  err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread, +			    cancelhandling, 0); +  if (err != TD_OK) +    return err; +  err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread, +			    report_events, 0); +  if (err != TD_OK) +    return err; + +  /* Fill in information.  Clear first to provide reproducable +     results for the fields we do not fill in.  */ +  memset (infop, '\0', sizeof (td_thrinfo_t)); + +  infop->ti_tid = (thread_t) th->th_unique; +  infop->ti_tls = (char *) tls; +  infop->ti_pri = ((uintptr_t) schedpolicy == SCHED_OTHER +		   ? 0 : (uintptr_t) schedprio); +  infop->ti_type = TD_THR_USER; + +  if ((((int) (uintptr_t) cancelhandling) & EXITING_BITMASK) == 0) +    /* XXX For now there is no way to get more information.  */ +    infop->ti_state = TD_THR_ACTIVE; +  else if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0) +    infop->ti_state = TD_THR_ZOMBIE; +  else +    infop->ti_state = TD_THR_UNKNOWN; + +  /* Initialization which are the same in both cases.  */ +  infop->ti_ta_p = th->th_ta_p; +  infop->ti_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid; +  infop->ti_traceme = report_events != 0; + +  err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread, +			    start_routine, 0); +  if (err == TD_OK) +    { +      uint32_t idx; +      for (idx = 0; idx < TD_EVENTSIZE; ++idx) +	{ +	  psaddr_t word; +	  err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy, pthread, +				    eventbuf_eventmask_event_bits, idx); +	  if (err != TD_OK) +	    break; +	  infop->ti_events.event_bits[idx] = (uintptr_t) word; +	} +      if (err == TD_NOAPLIC) +	memset (&infop->ti_events.event_bits[idx], 0, +		(TD_EVENTSIZE - idx) * sizeof infop->ti_events.event_bits[0]); +    } + +  return err; +} | 
