]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_log.cpp
update
[l4.git] / kernel / fiasco / src / jdb / jdb_log.cpp
1 IMPLEMENTATION:
2
3 #include <climits>
4 #include <cstring>
5 #include <cstdio>
6
7 #include "jdb.h"
8 #include "jdb_core.h"
9 #include "jdb_module.h"
10 #include "jdb_kobject.h"
11 #include "jdb_list.h"
12 #include "jdb_screen.h"
13 #include "kernel_console.h"
14 #include "keycodes.h"
15 #include "mem_unit.h"
16 #include "ram_quota.h"
17 #include "simpleio.h"
18 #include "task.h"
19 #include "static_init.h"
20
21
22 class Jdb_log_list : public Jdb_list
23 {
24   friend class Jdb_log_list_hdl;
25 public:
26   void *get_head() const { return _log_table; }
27   char const *show_head() const { return "[Log]"; }
28
29 private:
30   static Tb_log_table_entry *_end;
31 };
32
33 Tb_log_table_entry *Jdb_log_list::_end;
34
35 class Jdb_log_list_hdl : public Jdb_kobject_handler
36 {
37 public:
38   Jdb_log_list_hdl() : Jdb_kobject_handler(0) {}
39   virtual bool show_kobject(Kobject_common *, int) { return true; }
40 };
41
42 PUBLIC
43 bool
44 Jdb_log_list_hdl::invoke(Kobject_common *, Syscall_frame *f, Utcb *utcb)
45 {
46   switch (utcb->values[0])
47     {
48       case Op_query_typeid:
49           {
50             if (f->tag().words() < 3)
51               {
52                 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
53                 return true;
54               }
55
56             unsigned char const idx = utcb->values[1];
57
58             if (_log_table + idx >= &_log_table_end)
59               {
60                 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
61                 return true;
62               }
63
64             char nbuf[32];
65             strncpy(nbuf, (char const *)&utcb->values[2], sizeof(nbuf));
66             nbuf[sizeof(nbuf) - 1] = 0;
67
68             Tb_log_table_entry *r;
69             r = Jdb_log_list::find_next_log(nbuf, nbuf, _log_table + idx);
70
71             utcb->values[0] = r ? (r - _log_table) + Tbuf_dynentries : ~0UL;
72             f->tag(Kobject_iface::commit_result(0, 1));
73             return true;
74           }
75       case Op_switch_log:
76           {
77             if (f->tag().words() < 3)
78               {
79                 f->tag(Kobject_iface::commit_result(-L4_err::EInval));
80                 return true;
81               }
82
83             bool on = utcb->values[1];
84             char nbuf[32];
85             strncpy(nbuf, (char const *)&utcb->values[2], sizeof(nbuf));
86             nbuf[sizeof(nbuf) - 1] = 0;
87
88             Tb_log_table_entry *r = _log_table;
89             while ((r = Jdb_log_list::find_next_log(nbuf, nbuf, r)))
90               {
91                 Jdb_log_list::patch_item(r, on ? Jdb_log_list::patch_val(r) : 0);
92                 r++;
93               }
94
95             f->tag(Kobject_iface::commit_result(0));
96             return true;
97           }
98     }
99
100   return false;
101 }
102
103 PUBLIC
104 int
105 Jdb_log_list::show_item(char *buffer, int max, void *item) const
106 {
107   Tb_log_table_entry const *e = static_cast<Tb_log_table_entry const*>(item);
108   char const *sc = e->name;
109   sc += strlen(e->name) + 1;
110   int pos = snprintf(buffer, max, "%s %s (%s)",
111                      *(e->patch) ? "[on ]" : "[off]",  e->name, sc);
112   return pos;
113 }
114
115 PRIVATE static inline
116 unsigned
117 Jdb_log_list::patch_val(Tb_log_table_entry const *e)
118 { return (e - _log_table) + Tbuf_dynentries; }
119
120 PRIVATE static
121 Tb_log_table_entry *
122 Jdb_log_list::find_next_log(const char *name, const char *sc,
123                             Tb_log_table_entry *i)
124 {
125   for (; i < _end; ++i)
126     if (   !strcmp(name, i->name)
127         || !strcmp(sc, i->name + strlen(i->name) + 1))
128       return i;
129   return 0;
130 }
131
132 PUBLIC
133 bool
134 Jdb_log_list::enter_item(void *item) const
135 {
136   Tb_log_table_entry const *e = static_cast<Tb_log_table_entry const*>(item);
137   patch_item(e, *(e->patch) ? 0 : patch_val(e));
138   return true;
139 }
140
141 PRIVATE static
142 void
143 Jdb_log_list::patch_item(Tb_log_table_entry const *e, unsigned char val)
144 {
145   if (e->patch)
146     {
147       *(e->patch) = val;
148       Mem_unit::clean_dcache(e->patch);
149     }
150
151   for (Tb_log_table_entry *x = _end; x < &_log_table_end; ++x)
152     {
153       if (equal(x, e) && x->patch)
154         {
155           *(x->patch) = val;
156           Mem_unit::clean_dcache(x->patch);
157         }
158     }
159 }
160
161 PRIVATE static
162 bool
163 Jdb_log_list::equal(Tb_log_table_entry const *a, Tb_log_table_entry const *b)
164 {
165   if (strcmp(a->name, b->name))
166     return false;
167
168   char const *sca = a->name; sca += strlen(sca) + 1;
169   char const *scb = b->name; scb += strlen(scb) + 1;
170
171   if (strcmp(sca, scb))
172     return false;
173
174   return a->fmt == b->fmt;
175 }
176
177 PRIVATE
178 bool
179 Jdb_log_list::next(void **item)
180 {
181   Tb_log_table_entry *e = static_cast<Tb_log_table_entry*>(*item);
182
183   while (e + 1 < &_log_table_end)
184     {
185 #if 0
186       if (equal(e, e+1))
187         ++e;
188       else
189 #endif
190         {
191           *item  = e+1;
192           return true;
193         }
194     }
195
196   return false;
197 }
198
199 PRIVATE
200 bool
201 Jdb_log_list::pref(void **item)
202 {
203   Tb_log_table_entry *e = static_cast<Tb_log_table_entry*>(*item);
204
205   if (e > _log_table)
206     --e;
207   else
208     return false;
209 #if 0
210   while (e > _log_table)
211     {
212       if (equal(e, e-1))
213         --e;
214       else
215         break;
216     }
217 #endif
218
219   *item  = e;
220   return true;
221 }
222
223 PUBLIC
224 int
225 Jdb_log_list::seek(int cnt, void **item)
226 {
227   Tb_log_table_entry *e = static_cast<Tb_log_table_entry*>(*item);
228   if (cnt > 0)
229     {
230       if (e + cnt >= _end)
231         cnt = _end - e - 1;
232     }
233   else if (cnt < 0)
234     {
235       if (e + cnt < _log_table)
236         cnt = _log_table - e;
237     }
238
239   if (cnt)
240     {
241       *item = e + cnt;
242       return cnt;
243     }
244
245   return 0;
246 }
247
248 class Jdb_log : public Jdb_module
249 {
250 public:
251   Jdb_log() FIASCO_INIT;
252 private:
253 };
254
255
256 static void swap(Tb_log_table_entry *a, Tb_log_table_entry *b)
257 {
258   Tb_log_table_entry x = *a;
259   *a = *b;
260   *b = x;
261 }
262
263 static bool lt_cmp(Tb_log_table_entry *a, Tb_log_table_entry *b)
264 {
265   if (strcmp(a->name, b->name) < 0)
266     return true;
267   else
268     return false;
269 }
270
271 static void sort_tb_log_table()
272 {
273   for (Tb_log_table_entry *p = _log_table; p < &_log_table_end; ++p)
274     {
275       for (Tb_log_table_entry *x = &_log_table_end -1; x > p; --x)
276         if (lt_cmp(x, x - 1))
277           swap(x - 1, x);
278     }
279 }
280
281 PUBLIC
282 static
283 void
284 Jdb_log_list::move_dups()
285 {
286   _end = &_log_table_end;
287   Tb_log_table_entry *const tab_end = &_log_table_end;
288   for (Tb_log_table_entry *p = _log_table + 1; p < _end;)
289     {
290       if (equal(p-1, p))
291         {
292           --_end;
293           if (p < _end)
294             {
295               Tb_log_table_entry tmp = *p;
296               memmove(p, p + 1, sizeof(Tb_log_table_entry) * (tab_end - p - 1));
297               *(tab_end - 1) = tmp;
298             }
299           else
300             break;
301         }
302       else
303         ++p;
304     }
305 }
306
307 #if 0
308 static void disable_all()
309 {
310   for (Tb_log_table_entry *p = _log_table; p < _log_table_end; ++p)
311     *(p->patch) = 0;
312 }
313 #endif
314
315
316 IMPLEMENT
317 Jdb_log::Jdb_log()
318   : Jdb_module("MONITORING")
319 {
320   //disable_all();
321   sort_tb_log_table();
322   Jdb_log_list::move_dups();
323
324   static Jdb_log_list_hdl hdl;
325   Jdb_kobject::module()->register_handler(&hdl);
326 }
327
328 PUBLIC
329 Jdb_module::Action_code
330 Jdb_log::action(int, void *&, char const *&, int &)
331 {
332   if (_log_table >= &_log_table_end)
333     return NOTHING;
334
335   Jdb_log_list list;
336   list.set_start(_log_table);
337   list.do_list();
338
339   return NOTHING;
340 }
341
342 PUBLIC
343 Jdb_module::Cmd const *
344 Jdb_log::cmds() const
345 {
346   static Cmd cs[] =
347     {
348         { 0, "O", "log", "", "O\tselect log events", 0 },
349     };
350   return cs;
351 }
352
353 PUBLIC
354 int
355 Jdb_log::num_cmds() const
356 { return 1; }
357
358 static Jdb_log jdb_log INIT_PRIORITY(JDB_MODULE_INIT_PRIO);
359