Added ability to load an arbitrary binary from an ethernet server and launch it
[akaros.git] / user / parlib / src / debug.c
1 // Implementation of cprintf console output for user environments,
2 // based on printfmt() and the sys_cputs() system call.
3 //
4 // cprintf is a debugging statement, not a generic output statement.
5 // It is very important that it always go to the console, especially when
6 // debugging file descriptor code!
7 #ifdef __DEPUTY__
8 #pragma nodeputy
9 #endif
10
11 #include <arch/types.h>
12 #include <parlib.h>
13 #include <debug.h>
14
15 // Collect up to BUF_SIZE characters into a buffer
16 // and perform ONE system call to print all of them,
17 // in order to make the lines output to the console atomic
18 // and prevent interrupts from causing context switches
19 // in the middle of a console output line and such.
20 #define BUF_SIZE 256
21 typedef struct debugbuf {
22         size_t  idx;    // current buffer index
23         size_t  cnt;    // total bytes printed so far
24         uint8_t buf[BUF_SIZE];
25 } debugbuf_t;
26
27
28 static void putch(int ch, debugbuf_t **b)
29 {
30         (*b)->buf[(*b)->idx++] = ch;
31         if ((*b)->idx == BUF_SIZE) {
32                 sys_cputs((*b)->buf, (*b)->idx);
33                 (*b)->idx = 0;
34         }
35         (*b)->cnt++;
36 }
37
38 int vdebug(const char *fmt, va_list ap)
39 {
40         debugbuf_t b;
41         debugbuf_t *bp = &b;
42
43         b.idx = 0;
44         b.cnt = 0;
45         vdebugfmt((void*)putch, (void**)&bp, fmt, ap);
46         sys_cputs(b.buf, b.idx);
47
48         return b.cnt;
49 }
50
51 int debug(const char *fmt, ...)
52 {
53         va_list ap;
54         int cnt;
55
56         va_start(ap, fmt);
57         cnt = vdebug(fmt, ap);
58         va_end(ap);
59
60         return cnt;
61 }
62