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;
30 Timeout_timeslice = 1,
41 typedef Timeout::To_list::Const_iterator To_iter;
43 int skip_empty(To_iter *c, int i)
45 while (*c == _q->first(i).end() && i < (int)_q->queues())
48 *c = _q->first(i).begin();
54 explicit Timeout_iter(Timeout_q *t)
58 explicit Timeout_iter(Timeout_q *t, bool)
59 : _q(t), _c(t->first(0).end()), _i(0)
65 _c = _q->first(0).begin();
66 _i = skip_empty(&_c, _i);
69 Timeout_iter const &operator ++ ()
71 if (_c == _q->first(_i).end())
75 _i = skip_empty(&_c, _i);
80 Timeout *operator * () const { return *_c; }
82 bool operator == (Timeout_iter const &o) const
83 { return _c == o._c; }
85 bool operator != (Timeout_iter const &o) const
86 { return _c != o._c; }
94 template< typename FWD_ITER >
98 explicit Rnd_container(FWD_ITER const &b, FWD_ITER const &e)
99 : _b(b), _e(e), _cnt(0)
101 for (FWD_ITER i = b; i != e; ++i)
105 class Iterator : public FWD_ITER
110 Iterator const &operator += (int offs)
113 return operator -= (-offs);
118 for (; *this != _c->_e && offs > 0; --offs, ++_p)
119 this->operator ++ ();
124 Iterator const &operator -= (int offs)
127 return this->operator += (-offs);
134 if (_p > (unsigned)offs)
139 for (int z = 0; z < p && i != _c->_e; ++i, ++z)
142 *this = Iterator(_c, p, i);
146 Iterator const &operator -- ()
147 { return this->operator -= (1); }
149 int pos() const { return _p; }
152 friend class Rnd_container;
154 Iterator(Rnd_container *c, unsigned long pos, FWD_ITER const &i)
155 : FWD_ITER(i), _c(c), _p(pos)
163 Iterator begin() { return Iterator(this, 0, _b); }
164 Iterator end() { return Iterator(this, _cnt, _e); }
165 unsigned long size() const { return _cnt; }
166 Iterator at(unsigned long pos)
184 // available from the jdb_tcb module
185 extern int jdb_show_tcb(Thread *thread, int level) __attribute__((weak));
187 // use implicit knowledge to determine the type of a timeout because we
188 // cannot use dynamic_cast (we compile with -fno-rtti)
191 Jdb_list_timeouts::get_type(Timeout *t)
193 for (Cpu_number i = Cpu_number::first(); i < Config::max_num_cpus(); ++i)
194 if (t == timeslice_timeout.cpu(i))
195 return Timeout_timeslice;
205 Jdb_list_timeouts::get_owner(Timeout *t)
209 case Timeout_timeslice:
210 return static_cast<Thread*>(Context::kernel_context(Cpu_number::first()));
212 // XXX: current_sched does not work from the debugger
213 if (Context::current_sched())
214 return static_cast<Thread*>(Context::current_sched()->context());
223 Jdb_list_timeouts::show_header()
225 printf("%s type timeout owner name\033[m\033[K\n",
231 Jdb_list_timeouts::list_timeouts_show_timeout(Timeout *t)
234 char ownerstr[32] = "";
236 Signed64 timeout = t->get_timeout(Kip::k()->clock);
238 Kconsole::console()->getchar_chance();
242 case Timeout_timeslice:
244 owner = get_owner(t);
246 snprintf(ownerstr, sizeof(ownerstr), " %p", owner);
248 strcpy(ownerstr, "destruct");
251 snprintf(ownerstr, sizeof(ownerstr), " 0x%lx", (Address)t);
257 printf(" %-10s ", type);
262 String_buf<12> time_str;
263 Jdb::write_ll_ns(&time_str, timeout * 1000, false);
264 time_str.terminate();
265 putstr(time_str.begin());
268 Jdb_kobject_name *nx = 0;
271 nx = Jdb_kobject_extension::find_extension<Jdb_kobject_name>(owner);
273 printf(" %s %s\033[K\n", ownerstr, nx ? nx->name() : "");
277 Jdb_list_timeouts::Jdb_list_timeouts()
283 Jdb_list_timeouts::complete_show()
285 typedef Rnd_container<Timeout_iter> Cont;
286 typedef Cont::Iterator Iter;
288 Cont to_cont(Timeout_iter(&Timeout_q::timeout_queue.cpu(Cpu_number::first())),
289 Timeout_iter(&Timeout_q::timeout_queue.cpu(Cpu_number::first()), true));
292 for (Iter i = to_cont.begin(); i != to_cont.end(); ++i)
293 list_timeouts_show_timeout(*i);
298 Jdb_list_timeouts::list()
302 typedef Rnd_container<Timeout_iter> Cont;
303 typedef Cont::Iterator Iter;
305 Cont to_cont(Timeout_iter(&Timeout_q::timeout_queue.cpu(Cpu_number::first())),
306 Timeout_iter(&Timeout_q::timeout_queue.cpu(Cpu_number::first()), true));
307 Iter first = to_cont.begin();
308 Iter current = first;
309 Iter end = to_cont.end();
319 for (bool resync=false; !resync; )
323 // need to check for y_max > Jdb_screen::height()-3 here too
324 for (Iter i = current; i != to_cont.end(); ++i, ++y_max)
325 list_timeouts_show_timeout(*i);
327 for (unsigned i=y_max; i<Jdb_screen::height()-3; ++i)
330 Jdb::printf_statline("timouts", "<CR>=select owner", "_");
332 for (bool redraw=false; !redraw; )
335 switch (int c=Jdb_core::getchar())
344 redraw = i != current;
347 case KEY_CURSOR_DOWN:
355 if (current == to_cont.end())
357 redraw = i != current;
363 current -= Jdb_screen::height()-3;
364 redraw = i != current;
372 current += Jdb_screen::height()-3;
373 if (current == to_cont.end())
375 redraw = i != current;
380 case KEY_CURSOR_HOME:
381 redraw = current != first;
386 redraw = current != end;
391 if (jdb_show_tcb != 0)
396 if (i != to_cont.end() && (owner = get_owner(*i)))
398 if (!jdb_show_tcb(owner, 1))
407 Jdb::abort_command();
410 if (Jdb::is_toplevel_cmd(c))
419 Jdb_module::Action_code
420 Jdb_list_timeouts::action(int cmd, void *&, char const *&, int &)
431 Jdb_module::Cmd const *
432 Jdb_list_timeouts::cmds() const
436 { 0, "lt", "timeouts", "", "lt\tshow enqueued timeouts", 0 },
437 { 1, "", "timeoutsdump", "", 0, 0 },
445 Jdb_list_timeouts::num_cmds() const
450 static Jdb_list_timeouts jdb_list_timeouts INIT_PRIORITY(JDB_MODULE_INIT_PRIO);