/* Get thread information.
   Copyright (C) 1999-2003,2007,2009 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");

  if (th->th_unique == 0)
    {
      /* Special case for the main thread before initialization.  */
      copy = NULL;
      tls = 0;
      cancelhandling = 0;
      schedpolicy = SCHED_OTHER;
      schedprio = 0;
      tid = 0;
      err = DB_GET_VALUE (report_events, th->th_ta_p,
			  __nptl_initial_report_events, 0);
    }
  else
    {
      /* 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;

  if (copy != NULL)
    err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
			      start_routine, 0);
  if (copy != NULL && 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;
}
