1 | # |
---|
2 | # RTEMS Threads Support |
---|
3 | # Copyright 2010 Chris Johns (chrisj@rtems.org) |
---|
4 | # |
---|
5 | # $Id$ |
---|
6 | # |
---|
7 | |
---|
8 | import gdb |
---|
9 | |
---|
10 | import chains |
---|
11 | import objects |
---|
12 | |
---|
13 | def task_chain(chain): |
---|
14 | tasks = [] |
---|
15 | node = chain.first() |
---|
16 | while not node.null(): |
---|
17 | tasks.append(control(node.cast('Thread_Control'))) |
---|
18 | node.next() |
---|
19 | return tasks |
---|
20 | |
---|
21 | class state: |
---|
22 | |
---|
23 | ALL_SET = 0x000fffff |
---|
24 | READY = 0x00000000 |
---|
25 | DORMANT = 0x00000001 |
---|
26 | SUSPENDED = 0x00000002 |
---|
27 | TRANSIENT = 0x00000004 |
---|
28 | DELAYING = 0x00000008 |
---|
29 | WAITING_FOR_TIME = 0x00000010 |
---|
30 | WAITING_FOR_BUFFER = 0x00000020 |
---|
31 | WAITING_FOR_SEGMENT = 0x00000040 |
---|
32 | WAITING_FOR_MESSAGE = 0x00000080 |
---|
33 | WAITING_FOR_EVENT = 0x00000100 |
---|
34 | WAITING_FOR_SEMAPHORE = 0x00000200 |
---|
35 | WAITING_FOR_MUTEX = 0x00000400 |
---|
36 | WAITING_FOR_CONDITION_VARIABLE = 0x00000800 |
---|
37 | WAITING_FOR_JOIN_AT_EXIT = 0x00001000 |
---|
38 | WAITING_FOR_RPC_REPLY = 0x00002000 |
---|
39 | WAITING_FOR_PERIOD = 0x00004000 |
---|
40 | WAITING_FOR_SIGNAL = 0x00008000 |
---|
41 | WAITING_FOR_BARRIER = 0x00010000 |
---|
42 | WAITING_FOR_RWLOCK = 0x00020000 |
---|
43 | INTERRUPTIBLE_BY_SIGNAL = 0x10000000 |
---|
44 | LOCALLY_BLOCKED = \ |
---|
45 | WAITING_FOR_BUFFER | \ |
---|
46 | WAITING_FOR_SEGMENT | \ |
---|
47 | WAITING_FOR_MESSAGE | \ |
---|
48 | WAITING_FOR_SEMAPHORE | \ |
---|
49 | WAITING_FOR_MUTEX | \ |
---|
50 | WAITING_FOR_CONDITION_VARIABLE | \ |
---|
51 | WAITING_FOR_JOIN_AT_EXIT | \ |
---|
52 | WAITING_FOR_SIGNAL | \ |
---|
53 | WAITING_FOR_BARRIER | \ |
---|
54 | WAITING_FOR_RWLOCK |
---|
55 | WAITING_ON_THREAD_QUEUE = \ |
---|
56 | LOCALLY_BLOCKED | WAITING_FOR_RPC_REPLY |
---|
57 | BLOCKED = \ |
---|
58 | DELAYING | \ |
---|
59 | WAITING_FOR_TIME | \ |
---|
60 | WAITING_FOR_PERIOD | \ |
---|
61 | WAITING_FOR_EVENT | \ |
---|
62 | WAITING_ON_THREAD_QUEUE | \ |
---|
63 | INTERRUPTIBLE_BY_SIGNAL |
---|
64 | |
---|
65 | masks = { |
---|
66 | ALL_SET : 'all-set', |
---|
67 | READY : 'ready', |
---|
68 | DORMANT : 'dormant', |
---|
69 | SUSPENDED : 'suspended', |
---|
70 | TRANSIENT : 'transient', |
---|
71 | DELAYING : 'delaying', |
---|
72 | WAITING_FOR_TIME : 'waiting-for-time', |
---|
73 | WAITING_FOR_BUFFER : 'waiting-for-buffer', |
---|
74 | WAITING_FOR_SEGMENT : 'waiting-for-segment', |
---|
75 | WAITING_FOR_MESSAGE : 'waiting-for-message', |
---|
76 | WAITING_FOR_EVENT : 'waiting-for-event', |
---|
77 | WAITING_FOR_SEMAPHORE : 'waiting-for-semaphore', |
---|
78 | WAITING_FOR_MUTEX : 'waiting-for-mutex', |
---|
79 | WAITING_FOR_CONDITION_VARIABLE : 'waiting-for-condition-variable', |
---|
80 | WAITING_FOR_JOIN_AT_EXIT : 'waiting-for-join-at-exit', |
---|
81 | WAITING_FOR_RPC_REPLY : 'waiting-for-rpc-reply', |
---|
82 | WAITING_FOR_PERIOD : 'waiting-for-period', |
---|
83 | WAITING_FOR_SIGNAL : 'waiting-for-signal', |
---|
84 | WAITING_FOR_BARRIER : 'waiting-for-barrier', |
---|
85 | WAITING_FOR_RWLOCK : 'waiting-for-rwlock' |
---|
86 | } |
---|
87 | |
---|
88 | def __init__(self, s): |
---|
89 | self.s = s |
---|
90 | |
---|
91 | def to_string(self): |
---|
92 | if (self.s & self.LOCALLY_BLOCKED) == self.LOCALLY_BLOCKED: |
---|
93 | return 'locally-blocked' |
---|
94 | if (self.s & self.WAITING_ON_THREAD_QUEUE) == self.WAITING_ON_THREAD_QUEUE: |
---|
95 | return 'waiting-on-thread-queue' |
---|
96 | if (self.s & self.BLOCKED) == self.BLOCKED: |
---|
97 | return 'blocked' |
---|
98 | s = ',' |
---|
99 | for m in self.masks: |
---|
100 | if (self.s & m) == m: |
---|
101 | s = self.masks[m] + ',' |
---|
102 | return s[:-1] |
---|
103 | |
---|
104 | class wait_info: |
---|
105 | |
---|
106 | def __init__(self, info): |
---|
107 | self.info = info |
---|
108 | |
---|
109 | def id(self): |
---|
110 | return self.info['id'] |
---|
111 | |
---|
112 | def count(self): |
---|
113 | return self.info['count'] |
---|
114 | |
---|
115 | def return_arg(self): |
---|
116 | return self.info['return_argument'] |
---|
117 | |
---|
118 | def option(self): |
---|
119 | return self.info['option'] |
---|
120 | |
---|
121 | def block2n(self): |
---|
122 | return task_chain(chains.control(self.info['Block2n'])) |
---|
123 | |
---|
124 | def queue(self): |
---|
125 | return task_chain(chains.control(self.info['queue'])) |
---|
126 | |
---|
127 | class control: |
---|
128 | |
---|
129 | def __init__(self, ctrl): |
---|
130 | self.ctrl = ctrl |
---|
131 | self.object = objects.control(ctrl['Object']) |
---|
132 | |
---|
133 | def id(self): |
---|
134 | return self.object.id() |
---|
135 | |
---|
136 | def name(self): |
---|
137 | return self.object.name() |
---|
138 | |
---|
139 | def current_state(self): |
---|
140 | return state(self.ctrl['current_state']).to_string() |
---|
141 | |
---|
142 | def current_priority(self): |
---|
143 | return self.ctrl['current_priority'] |
---|
144 | |
---|
145 | def real_priority(self): |
---|
146 | return self.ctrl['real_priority'] |
---|
147 | |
---|
148 | def suspends(self): |
---|
149 | return self.ctrl['suspend_count'] |
---|
150 | |
---|
151 | def post_task_switch_ext(self): |
---|
152 | return self.ctrl['do_post_task_switch_extension'] |
---|
153 | |
---|
154 | def preemptible(self): |
---|
155 | return self.ctrl['is_preemptible'] |
---|
156 | |
---|
157 | def cpu_time_budget(self): |
---|
158 | return self.ctrl['cpu_time_budget'] |
---|
159 | |
---|
160 | def wait_info(self): |
---|
161 | return wait_info(self.ctrl['Wait']) |
---|
162 | |
---|
163 | def brief(self): |
---|
164 | return "'%s' (c:%d, r:%d)" % \ |
---|
165 | (self.name(), self.current_priority(), self.real_priority()) |
---|
166 | |
---|
167 | class queue: |
---|
168 | """Manage the Thread_queue_Control.""" |
---|
169 | |
---|
170 | priority_headers = 4 |
---|
171 | |
---|
172 | def __init__(self, que): |
---|
173 | self.que = que |
---|
174 | |
---|
175 | def fifo(self): |
---|
176 | return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_FIFO' |
---|
177 | |
---|
178 | def priority(self): |
---|
179 | return str(self.que['discipline']) == 'THREAD_QUEUE_DISCIPLINE_PRIORITY' |
---|
180 | |
---|
181 | def state(self): |
---|
182 | return state(self.que['state']).to_string() |
---|
183 | |
---|
184 | def tasks(self): |
---|
185 | if self.fifo(): |
---|
186 | t = task_chain(chains.control(self.que['Queues']['Fifo'])) |
---|
187 | else: |
---|
188 | t = [] |
---|
189 | for ph in range(0, self.priority_headers): |
---|
190 | t.extend(task_chain(chains.control( \ |
---|
191 | self.que['Queues']['Priority'][ph]))) |
---|
192 | return t |
---|
193 | |
---|
194 | |
---|
195 | |
---|