diff options
author | Dhananjay Balan <mb.dhananjay@gmail.com> | 2013-06-17 22:40:17 +0530 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2014-08-25 09:52:40 +1000 |
commit | 56a70aec5536a568fe302a3c84b349fcf17db2fa (patch) | |
tree | 0f1043e21f214f7e3b3d1063f446073980859c15 /tools/gdb/python/threads.py | |
parent | Initial commit (diff) | |
download | rtems-tools-56a70aec5536a568fe302a3c84b349fcf17db2fa.tar.bz2 |
Intial commit.
Chris's intial work on the extenstions.
Diffstat (limited to 'tools/gdb/python/threads.py')
-rw-r--r-- | tools/gdb/python/threads.py | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/tools/gdb/python/threads.py b/tools/gdb/python/threads.py new file mode 100644 index 0000000..906cf5a --- /dev/null +++ b/tools/gdb/python/threads.py @@ -0,0 +1,207 @@ +# +# RTEMS Threads Support +# Copyright 2010 Chris Johns (chrisj@rtems.org) +# +# $Id$ +# + +import gdb + +import chains +import objects + +def task_chain(chain): + tasks = [] + node = chain.first() + while not node.null(): + print node.addr + tasks.append(control(node.cast('Thread_Control'))) + node.next() + return tasks + +class state: + + ALL_SET = 0x000fffff + READY = 0x00000000 + DORMANT = 0x00000001 + SUSPENDED = 0x00000002 + TRANSIENT = 0x00000004 + DELAYING = 0x00000008 + WAITING_FOR_TIME = 0x00000010 + WAITING_FOR_BUFFER = 0x00000020 + WAITING_FOR_SEGMENT = 0x00000040 + WAITING_FOR_MESSAGE = 0x00000080 + WAITING_FOR_EVENT = 0x00000100 + WAITING_FOR_SEMAPHORE = 0x00000200 + WAITING_FOR_MUTEX = 0x00000400 + WAITING_FOR_CONDITION_VARIABLE = 0x00000800 + WAITING_FOR_JOIN_AT_EXIT = 0x00001000 + WAITING_FOR_RPC_REPLY = 0x00002000 + WAITING_FOR_PERIOD = 0x00004000 + WAITING_FOR_SIGNAL = 0x00008000 + WAITING_FOR_BARRIER = 0x00010000 + WAITING_FOR_RWLOCK = 0x00020000 + INTERRUPTIBLE_BY_SIGNAL = 0x10000000 + LOCALLY_BLOCKED = \ + WAITING_FOR_BUFFER | \ + WAITING_FOR_SEGMENT | \ + WAITING_FOR_MESSAGE | \ + WAITING_FOR_SEMAPHORE | \ + WAITING_FOR_MUTEX | \ + WAITING_FOR_CONDITION_VARIABLE | \ + WAITING_FOR_JOIN_AT_EXIT | \ + WAITING_FOR_SIGNAL | \ + WAITING_FOR_BARRIER | \ + WAITING_FOR_RWLOCK + WAITING_ON_THREAD_QUEUE = \ + LOCALLY_BLOCKED | WAITING_FOR_RPC_REPLY + BLOCKED = \ + DELAYING | \ + WAITING_FOR_TIME | \ + WAITING_FOR_PERIOD | \ + WAITING_FOR_EVENT | \ + WAITING_ON_THREAD_QUEUE | \ + INTERRUPTIBLE_BY_SIGNAL + + masks = { + ALL_SET : 'all-set', + READY : 'ready', + DORMANT : 'dormant', + SUSPENDED : 'suspended', + TRANSIENT : 'transient', + DELAYING : 'delaying', + WAITING_FOR_TIME : 'waiting-for-time', + WAITING_FOR_BUFFER : 'waiting-for-buffer', + WAITING_FOR_SEGMENT : 'waiting-for-segment', + WAITING_FOR_MESSAGE : 'waiting-for-message', + WAITING_FOR_EVENT : 'waiting-for-event', + WAITING_FOR_SEMAPHORE : 'waiting-for-semaphore', + WAITING_FOR_MUTEX : 'waiting-for-mutex', + WAITING_FOR_CONDITION_VARIABLE : 'waiting-for-condition-variable', + WAITING_FOR_JOIN_AT_EXIT : 'waiting-for-join-at-exit', + WAITING_FOR_RPC_REPLY : 'waiting-for-rpc-reply', + WAITING_FOR_PERIOD : 'waiting-for-period', + WAITING_FOR_SIGNAL : 'waiting-for-signal', + WAITING_FOR_BARRIER : 'waiting-for-barrier', + WAITING_FOR_RWLOCK : 'waiting-for-rwlock' + } + + def __init__(self, s): + self.s = s + + def to_string(self): + if (self.s & self.LOCALLY_BLOCKED) == self.LOCALLY_BLOCKED: + return 'locally-blocked' + if (self.s & self.WAITING_ON_THREAD_QUEUE) == self.WAITING_ON_THREAD_QUEUE: + return 'waiting-on-thread-queue' + if (self.s & self.BLOCKED) == self.BLOCKED: + return 'blocked' + s = ',' + for m in self.masks: + if (self.s & m) == m: + s = self.masks[m] + ',' + return s[:-1] + +class wait_info: + + def __init__(self, info): + self.info = info + + def id(self): + return self.info['id'] + + def count(self): + return self.info['count'] + + def return_arg(self): + return self.info['return_argument'] + + def option(self): + return self.info['option'] + + def block2n(self): + return task_chain(chains.control(self.info['Block2n'])) + + def queue(self): + return task_chain(chains.control(self.info['queue'])) + +class control: + + def __init__(self, ctrl): + self.ctrl = ctrl + self.object = objects.control(ctrl['Object']) + + def id(self): + return self.object.id() + + def name(self): + return self.object.name() + + def current_state(self): + return state(self.ctrl['current_state']).to_string() + + def current_priority(self): + return self.ctrl['current_priority'] + + def real_priority(self): + return self.ctrl['real_priority'] + + def suspends(self): + return self.ctrl['suspend_count'] + + def post_task_switch_ext(self): + return self.ctrl['do_post_task_switch_extension'] + + def preemptible(self): + return self.ctrl['is_preemptible'] + + def cpu_time_budget(self): + return self.ctrl['cpu_time_budget'] + + def wait_info(self): + return wait_info(self.ctrl['Wait']) + + def brief(self): + return "'%s' (c:%d, r:%d)" % \ + (self.name(), self.current_priority(), self.real_priority()) + +class queue: + """Manage the Thread_queue_Control.""" + + priority_headers = 4 + + def __init__(self, que): + self.que = que + + def fifo(self): + return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_FIFO' + + def priority(self): + return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_PRIORITY' + + def state(self): + return state(self.que['state']).to_string() + + def tasks(self): + if self.fifo(): + t = task_chain(chains.control(self.que['Queues']['Fifo'])) + else: + t = [] + for ph in range(0, self.priority_headers): + t.extend(task_chain(chains.control(self.que['Queues']['Fifo']))) + return t + + def to_string(self): + if self.fifo(): + s = 'fifo' + else: + s = 'priority' + return + +class state_printer: + + def __init__(self, s): + self.s = state(s) + + def to_string(self): + return self.s.to_string() |