8 #include "ipc_timeout.h"
10 #include "jdb_kobject.h"
11 #include "jdb_kobject_names.h"
12 #include "jdb_module.h"
13 #include "jdb_screen.h"
14 #include "kernel_console.h"
18 #include "static_init.h"
20 #include "timeslice_timeout.h"
23 class Jdb_list_timeouts : public Jdb_module
26 Jdb_list_timeouts() FIASCO_INIT;
32 Timeout_timeslice = 3,
37 class Jdb_timeout_list
41 static Timeout *_t_start;
45 // available from the jdb_tcb module
46 extern int jdb_show_tcb(Thread *thread, int level) __attribute__((weak));
48 int Jdb_timeout_list::_count;
49 Timeout *Jdb_timeout_list::_t_start;
53 Jdb_timeout_list::init(Timeout *t_head)
60 Jdb_timeout_list::iter(int count, Timeout **t_start,
61 void (*iter)(Timeout *t) = 0)
64 int forw = count >= 0;
65 Timeout *t_new = *t_start;
76 for (; count; count--)
80 if (t_new->_next == Timeout_q::timeout_queue.cpu(0).first())
86 if (t_new->_prev == Timeout_q::timeout_queue.cpu(0).first())
98 bool changed = *t_start != t_new;
104 // _t_start-- if possible
107 Jdb_timeout_list::line_back(void)
109 return _t_start ? iter(-1, &_t_start) : 0;
112 // _t_start++ if possible
115 Jdb_timeout_list::line_forw(void)
117 Timeout *t = _t_start;
120 iter(+Jdb_screen::height()-2, &_t_start);
121 iter(-Jdb_screen::height()+3, &_t_start);
123 return t != _t_start;
126 // _t_start -= 24 if possible
129 Jdb_timeout_list::page_back(void)
131 return _t_start ? iter(-Jdb_screen::height()+2, &_t_start) : 0;
134 // _t_start += 24 if possible
137 Jdb_timeout_list::page_forw(void)
139 Timeout *t = _t_start;
142 iter(+Jdb_screen::height()*2-5, &_t_start);
143 iter(-Jdb_screen::height()+3, &_t_start);
145 return t != _t_start;
148 // _t_start = first element of list
151 Jdb_timeout_list::goto_home(void)
153 return _t_start ? iter(-9999, &_t_start) : 0;
156 // _t_start = last element of list
159 Jdb_timeout_list::goto_end(void)
161 Timeout *t = _t_start;
164 iter(+9999, &_t_start);
165 iter(-Jdb_screen::height()+2, &_t_start);
167 return t != _t_start;
172 Jdb_timeout_list::lookup(Timeout *t_search)
177 for (i=0, t=_t_start; i<Jdb_screen::height()-3; i++)
189 Jdb_timeout_list::index(int y)
191 Timeout *t = _t_start;
202 Jdb_timeout_list::page_show(void (*show)(Timeout *t))
204 Timeout *t = _t_start;
206 iter(Jdb_screen::height()-3, &t, show);
210 // use implicit knowledge to determine the type of a timeout because we
211 // cannot use dynamic_cast (we compile with -fno-rtti)
214 Jdb_list_timeouts::get_type(Timeout *t)
216 Address addr = (Address)t;
218 if (t == timeslice_timeout.cpu(0))
219 // there is only one global timeslice timeout
220 return Timeout_timeslice;
222 if (Timeout_q::timeout_queue.cpu(0).is_root_node(addr))
225 if ((addr % Config::thread_block_size) >= sizeof(Thread))
226 // IPC timeouts are located at the kernel stack
235 Jdb_list_timeouts::get_owner(Timeout *t)
240 return Thread::lookup(context_of (t));
241 case Timeout_deadline:
242 return Thread::lookup(context_of (t));
243 case Timeout_timeslice:
244 return kernel_thread;
245 // XXX: current_sched does not work from the debugger
246 if (Context::current_sched())
247 return Thread::lookup(Context::current_sched()->context());
255 Jdb_list_timeouts::show_header()
258 printf("%s type timeout owner name\033[m\033[K\n",
264 Jdb_list_timeouts::list_timeouts_show_timeout(Timeout *t)
267 char ownerstr[32] = "";
269 Signed64 timeout = t->get_timeout(Kip::k()->clock);
271 Kconsole::console()->getchar_chance();
277 owner = get_owner(t);
278 snprintf (ownerstr, sizeof(ownerstr), " %p", owner);
280 case Timeout_deadline:
282 owner = get_owner(t);
283 snprintf (ownerstr, sizeof(ownerstr), " %p", owner);
285 case Timeout_timeslice:
287 owner = get_owner(t);
289 snprintf (ownerstr, sizeof(ownerstr), " %p", owner);
291 strcpy (ownerstr, "destruct");
296 strcpy (ownerstr, "kern");
299 snprintf(ownerstr, sizeof(ownerstr), L4_PTR_FMT, (Address)t);
305 printf(" %-10s ", type);
311 Jdb::write_ll_ns(timeout * 1000, time_str,
312 11 < sizeof(time_str) - 1 ? 11 : sizeof(time_str) - 1,
317 Jdb_kobject_name *nx = 0;
320 nx = Jdb_kobject_extension::find_extension<Jdb_kobject_name>(owner->kobject());
322 printf(" %s %s\033[K\n", ownerstr, nx ? nx->name() : "");
326 Jdb_list_timeouts::Jdb_list_timeouts()
332 Jdb_list_timeouts::list()
335 Timeout *t_current = Timeout_q::timeout_queue.cpu(0).first();
339 Jdb_timeout_list::init(t_current);
343 y = Jdb_timeout_list::lookup(t_current);
345 for (bool resync=false; !resync; )
349 ? Jdb_timeout_list::page_show(list_timeouts_show_timeout)
352 for (unsigned i=y_max; i<Jdb_screen::height()-3; i++)
355 Jdb::printf_statline("timouts", "<CR>=select owner", "_");
357 for (bool redraw=false; !redraw; )
360 switch (int c=Jdb_core::getchar())
366 redraw = Jdb_timeout_list::line_back();
368 case KEY_CURSOR_DOWN:
372 redraw = Jdb_timeout_list::line_forw();
375 if (!(redraw = Jdb_timeout_list::page_back()))
379 if (!(redraw = Jdb_timeout_list::page_forw()))
382 case KEY_CURSOR_HOME:
383 redraw = Jdb_timeout_list::goto_home();
387 redraw = Jdb_timeout_list::goto_end();
391 if (jdb_show_tcb != 0)
394 Timeout *t = Jdb_timeout_list::index(y);
395 if (t && (owner = get_owner(t)))
397 if (!jdb_show_tcb(owner, 1))
405 Jdb::abort_command();
408 if (Jdb::is_toplevel_cmd(c))
417 Jdb_module::Action_code
418 Jdb_list_timeouts::action(int cmd, void *&, char const *&, int &)
427 Jdb_module::Cmd const *
428 Jdb_list_timeouts::cmds() const
432 { 0, "lt", "timeouts", "", "lt\tshow enqueued timeouts", 0 },
440 Jdb_list_timeouts::num_cmds() const
445 static Jdb_list_timeouts jdb_list_timeouts INIT_PRIORITY(JDB_MODULE_INIT_PRIO);