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