cons: Support epolling /dev/null
[akaros.git] / user / parlib / debug.c
1 #include <parlib/common.h>
2 #include <parlib/parlib.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <parlib/spinlock.h>
6 #include <ros/common.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <fcntl.h>
10
11 int akaros_printf(const char *format, ...)
12 {
13         va_list ap;
14         int ret;
15
16         va_start(ap, format);
17         ret = vprintf(format, ap);
18         va_end(ap);
19         return ret;
20 }
21
22 /* Poor man's Ftrace, won't work well with concurrency. */
23 static const char *blacklist[] = {
24         "whatever",
25 };
26
27 static bool is_blacklisted(const char *s)
28 {
29         for (int i = 0; i < COUNT_OF(blacklist); i++) {
30                 if (!strcmp(blacklist[i], s))
31                         return TRUE;
32         }
33         return FALSE;
34 }
35
36 static int tab_depth = 0;
37 static bool print = TRUE;
38
39 void reset_print_func_depth(void)
40 {
41         tab_depth = 0;
42 }
43
44 void toggle_print_func(void)
45 {
46         print = !print;
47         printf("Func entry/exit printing is now %sabled\n", print ? "en" : "dis");
48 }
49
50 static spinlock_t lock = {0};
51
52 void __print_func_entry(const char *func, const char *file)
53 {
54         if (!print)
55                 return;
56         if (is_blacklisted(func))
57                 return;
58         spinlock_lock(&lock);
59         printd("Vcore %2d", vcore_id());        /* helps with multicore output */
60         for (int i = 0; i < tab_depth; i++)
61                 printf("\t");
62         printf("%s() in %s\n", func, file);
63         spinlock_unlock(&lock);
64         tab_depth++;
65 }
66
67 void __print_func_exit(const char *func, const char *file)
68 {
69         if (!print)
70                 return;
71         if (is_blacklisted(func))
72                 return;
73         tab_depth--;
74         spinlock_lock(&lock);
75         printd("Vcore %2d", vcore_id());
76         for (int i = 0; i < tab_depth; i++)
77                 printf("\t");
78         printf("---- %s()\n", func);
79         spinlock_unlock(&lock);
80 }
81
82 void trace_printf(const char *fmt, ...)
83 {
84         static int kptrace;
85         va_list args;
86         char buf[128];
87         int amt;
88
89         run_once(
90                 kptrace = open("#kprof/kptrace", O_WRITE);
91                 if (kptrace < 0)
92                         perror("Unable to open kptrace!\n");
93         );
94
95         if (kptrace < 0)
96                 return;
97         amt = snprintf(buf, sizeof(buf), "PID %d: ", getpid());
98         /* amt could be > sizeof, if we truncated. */
99         amt = MIN(amt, sizeof(buf));
100         va_start(args, fmt);
101         /* amt == sizeof is OK here */
102         amt += vsnprintf(buf + amt, sizeof(buf) - amt, fmt, args);
103         va_end(args);
104         write(kptrace, buf, MIN(amt, sizeof(buf)));
105 }