Remove ros_debug()
[akaros.git] / user / parlib / debug.c
1 // Implementation of cprintf console output for user processes,
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
8 #include <parlib/common.h>
9 #include <parlib/parlib.h>
10 #include <stdio.h>
11 #include <parlib/spinlock.h>
12
13 // Collect up to BUF_SIZE characters into a buffer
14 // and perform ONE system call to print all of them,
15 // in order to make the lines output to the console atomic
16 // and prevent interrupts from causing context switches
17 // in the middle of a console output line and such.
18 #define BUF_SIZE 256
19 typedef struct debugbuf {
20         size_t  idx;    // current buffer index
21         size_t  cnt;    // total bytes printed so far
22         uint8_t buf[BUF_SIZE];
23 } debugbuf_t;
24
25
26 static void putch(int ch, debugbuf_t **b)
27 {
28         (*b)->buf[(*b)->idx++] = ch;
29         if ((*b)->idx == BUF_SIZE) {
30                 sys_cputs((*b)->buf, (*b)->idx);
31                 (*b)->idx = 0;
32         }
33         (*b)->cnt++;
34 }
35
36 int ros_vdebug(const char *fmt, va_list ap)
37 {
38         debugbuf_t b;
39         debugbuf_t *bp = &b;
40
41         b.idx = 0;
42         b.cnt = 0;
43         ros_vdebugfmt((void*)putch, (void*)&bp, fmt, ap);
44         sys_cputs(b.buf, b.idx);
45
46         return b.cnt;
47 }
48
49 int akaros_printf(const char *format, ...)
50 {
51         va_list ap;
52         int ret;
53
54         va_start(ap, format);
55         if (in_vcore_context())
56                 ret = ros_vdebug(format, ap);
57         else
58                 ret = vprintf(format, ap);
59         va_end(ap);
60         return ret;
61 }
62
63 /* Poor man's Ftrace, won't work well with concurrency. */
64 static const char *blacklist[] = {
65         "whatever",
66 };
67
68 static bool is_blacklisted(const char *s)
69 {
70         #define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))
71         for (int i = 0; i < ARRAY_SIZE(blacklist); i++) {
72                 if (!strcmp(blacklist[i], s))
73                         return TRUE;
74         }
75         return FALSE;
76 }
77
78 static int tab_depth = 0;
79 static bool print = TRUE;
80
81 void reset_print_func_depth(void)
82 {
83         tab_depth = 0;
84 }
85
86 void toggle_print_func(void)
87 {
88         print = !print;
89         printf("Func entry/exit printing is now %sabled\n", print ? "en" : "dis");
90 }
91
92 static spinlock_t lock = {0};
93
94 void __print_func_entry(const char *func, const char *file)
95 {
96         if (!print)
97                 return;
98         if (is_blacklisted(func))
99                 return;
100         spinlock_lock(&lock);
101         printd("Vcore %2d", vcore_id());        /* helps with multicore output */
102         for (int i = 0; i < tab_depth; i++)
103                 printf("\t");
104         printf("%s() in %s\n", func, file);
105         spinlock_unlock(&lock);
106         tab_depth++;
107 }
108
109 void __print_func_exit(const char *func, const char *file)
110 {
111         if (!print)
112                 return;
113         if (is_blacklisted(func))
114                 return;
115         tab_depth--;
116         spinlock_lock(&lock);
117         printd("Vcore %2d", vcore_id());
118         for (int i = 0; i < tab_depth; i++)
119                 printf("\t");
120         printf("---- %s()\n", func);
121         spinlock_unlock(&lock);
122 }