2007-07-06 18:24:13 +08:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
2010-03-16 17:38:11 +08:00
|
|
|
* Copyright (C) 2004, 2007-2010, Karlsruhe University
|
2007-07-06 18:24:13 +08:00
|
|
|
*
|
|
|
|
* File path: kdb/api/v4/thread.cc
|
|
|
|
* Description: Kdebug stuff for V4 threads
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* $Id: thread.cc,v 1.5 2005/06/03 15:54:04 joshua Exp $
|
|
|
|
*
|
|
|
|
********************************************************************/
|
|
|
|
#include <kdb/tid_format.h>
|
|
|
|
#include INC_API(thread.h)
|
|
|
|
#include INC_API(tcb.h)
|
|
|
|
|
|
|
|
|
|
|
|
/* From generic/print.cc */
|
|
|
|
|
|
|
|
int print_hex (const word_t val,
|
|
|
|
int width,
|
|
|
|
int precision,
|
|
|
|
bool adjleft = false,
|
|
|
|
bool nullpad = false);
|
|
|
|
int print_string (const char * s,
|
|
|
|
const int width = 0,
|
|
|
|
const int precision = 0);
|
|
|
|
int print_hex_sep (const word_t val,
|
|
|
|
const int bits,
|
|
|
|
const char *sep);
|
|
|
|
int print_dec (const word_t val,
|
|
|
|
const int width = 0,
|
|
|
|
const char pad = ' ');
|
|
|
|
|
|
|
|
|
|
|
|
int print_tid (word_t val, word_t width, word_t precision, bool adjleft)
|
|
|
|
{
|
|
|
|
tcb_t * tcb;
|
|
|
|
threadid_t tid;
|
|
|
|
space_t * dummy = NULL;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
print_string ("<");
|
|
|
|
print_dec (width);
|
|
|
|
print_string (":");
|
|
|
|
print_dec (precision);
|
|
|
|
print_string (">");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// If val is within TCB area, treat it as a tcb address. If not,
|
2008-01-25 23:24:47 +08:00
|
|
|
// treat it as a thread ID.
|
2007-07-06 18:24:13 +08:00
|
|
|
|
2010-03-16 17:38:11 +08:00
|
|
|
if (tcb_t::is_tcb ((addr_t) val) ||
|
2007-12-08 01:56:40 +08:00
|
|
|
addr_to_tcb((addr_t) val) == get_idle_tcb() ||
|
|
|
|
addr_to_tcb((addr_t) val) == get_kdebug_tcb())
|
2007-07-06 18:24:13 +08:00
|
|
|
{
|
|
|
|
tcb = addr_to_tcb ((addr_t) val);
|
|
|
|
tid = tcb->get_global_id ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tid.set_raw (val);
|
2010-03-16 17:38:11 +08:00
|
|
|
tcb = tcb_t::get_tcb (tid);
|
2007-07-06 18:24:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (kdb_tid_format.X.human)
|
|
|
|
{
|
|
|
|
// Convert special thread IDs to human readable form
|
2010-03-02 06:33:11 +08:00
|
|
|
threadid_t ktid;
|
|
|
|
ktid.set_global_id (get_kip ()->thread_info.get_system_base (), 1);
|
|
|
|
|
|
|
|
if (tcb->get_global_id() == ktid)
|
|
|
|
return print_string ("KRN_THRD", width, precision);
|
|
|
|
|
2008-01-25 23:24:47 +08:00
|
|
|
if (tcb == get_idle_tcb ())
|
|
|
|
return print_string ("IDLETHRD", width, precision);
|
|
|
|
|
|
|
|
if (tcb == get_kdebug_tcb())
|
|
|
|
return print_string ("KDBTHRD", width, precision);
|
|
|
|
|
2007-07-06 18:24:13 +08:00
|
|
|
if (tid.is_nilthread ())
|
|
|
|
return print_string ("NIL_THRD", width, precision);
|
|
|
|
|
|
|
|
if (tid.is_anythread())
|
|
|
|
return print_string ("ANY_THRD", width, precision);
|
|
|
|
|
|
|
|
if (tid.is_interrupt ())
|
|
|
|
{
|
|
|
|
print_string ("IRQ_");
|
|
|
|
return 4 + print_dec (tid.get_irqno(), width - 4, '0');
|
|
|
|
}
|
|
|
|
word_t base_id = tid.get_threadno () -
|
|
|
|
get_kip()->thread_info.get_user_base ();
|
|
|
|
if (base_id < 3)
|
|
|
|
{
|
|
|
|
const char *names[3] = { "SIGMA0", "SIGMA1", "ROOTTASK" };
|
|
|
|
return print_string (names[base_id], width, precision);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We're dealing with something which is not a special thread ID.
|
|
|
|
|
|
|
|
word_t n = 0;
|
|
|
|
bool f_both = TID_FORMAT_VALUE_BOTH == kdb_tid_format.X.value;
|
|
|
|
bool f_gid = TID_FORMAT_VALUE_GID == kdb_tid_format.X.value;
|
|
|
|
bool f_tcb = TID_FORMAT_VALUE_TCB == kdb_tid_format.X.value;
|
|
|
|
bool f_ver = TID_FORMAT_VERSION_OFF != kdb_tid_format.X.version;
|
|
|
|
|
|
|
|
if (f_gid || f_both)
|
|
|
|
{
|
|
|
|
// Getting a consistent output width with separators is pretty
|
|
|
|
// much hopeless depending on the position of the separator,
|
|
|
|
// additional hex characters become necessary
|
|
|
|
|
|
|
|
if (TID_FORMAT_VERSION_INLINE == kdb_tid_format.X.version)
|
|
|
|
{
|
|
|
|
// Do not separate version from threadno
|
|
|
|
if (kdb_tid_format.X.sep != 0)
|
|
|
|
// Insert a separator into threadno
|
|
|
|
n = print_hex_sep (tid.get_raw (),
|
|
|
|
kdb_tid_format.X.sep +
|
|
|
|
L4_GLOBAL_VERSION_BITS, ".");
|
|
|
|
else
|
|
|
|
// No separator at all
|
|
|
|
n = print_hex (tid.get_raw (), 0, sizeof (word_t) * 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (kdb_tid_format.X.sep != 0)
|
|
|
|
// Insert a separator into threadno
|
|
|
|
n = print_hex_sep (tid.get_threadno (),
|
|
|
|
kdb_tid_format.X.sep, ".");
|
|
|
|
else
|
|
|
|
// Print threadno without separator
|
|
|
|
n = print_hex (tid.get_threadno (),
|
|
|
|
f_both || f_ver ? 0 : width,
|
|
|
|
0, adjleft);
|
|
|
|
|
|
|
|
if (f_ver)
|
|
|
|
{
|
|
|
|
// Add a separator between threadno and version
|
|
|
|
n += print_string ("v");
|
|
|
|
// print_dec (width); print_string (">");
|
|
|
|
width -= width > n ? n : 0;
|
|
|
|
n += print_hex (tid.get_version (),
|
|
|
|
f_both ? 0 : width, 0, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f_both)
|
|
|
|
n += print_string ("/");
|
|
|
|
|
|
|
|
if (f_tcb || f_both)
|
|
|
|
// Print plain TCB address
|
|
|
|
n += print_hex ((word_t) tcb, 0, sizeof (word_t) * 2);
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|