1 #include <parlib/common.h>
2 #include <parlib/assert.h>
3 #include <parlib/stdio.h>
4 #include <parlib/parlib.h>
6 #include <parlib/spinlock.h>
7 #include <ros/common.h>
12 /* This is called from glibc in delicate places, like signal handlers. We might
13 * as well just write any valid output to FD 2. */
14 int akaros_printf(const char *format, ...)
21 ret = vsnprintf(buf, sizeof(buf), format, ap);
25 write(2, buf, MIN(sizeof(buf), ret));
29 /* Poor man's Ftrace, won't work well with concurrency. */
30 static const char *blacklist[] = {
34 static bool is_blacklisted(const char *s)
36 for (int i = 0; i < COUNT_OF(blacklist); i++) {
37 if (!strcmp(blacklist[i], s))
43 static int tab_depth = 0;
44 static bool print = TRUE;
46 void reset_print_func_depth(void)
51 void toggle_print_func(void)
54 printf("Func entry/exit printing is now %sabled\n", print ? "en" :
58 static spinlock_t lock = {0};
60 void __print_func_entry(const char *func, const char *file)
64 if (is_blacklisted(func))
67 printd("Vcore %2d", vcore_id()); /* helps with multicore output */
68 for (int i = 0; i < tab_depth; i++)
70 printf("%s() in %s\n", func, file);
71 spinlock_unlock(&lock);
75 void __print_func_exit(const char *func, const char *file)
79 if (is_blacklisted(func))
83 printd("Vcore %2d", vcore_id());
84 for (int i = 0; i < tab_depth; i++)
86 printf("---- %s()\n", func);
87 spinlock_unlock(&lock);
92 static void trace_init(void *arg)
94 kptrace = open("#kprof/kptrace", O_WRITE);
96 perror("Unable to open kptrace!\n");
99 int trace_printf(const char *fmt, ...)
104 static parlib_once_t once = PARLIB_ONCE_INIT;
106 parlib_run_once(&once, trace_init, NULL);
109 amt = snprintf(buf, sizeof(buf), "PID %d: ", getpid());
110 /* amt could be > sizeof, if we truncated. */
111 amt = MIN(amt, sizeof(buf));
113 /* amt == sizeof is OK here */
114 amt += vsnprintf(buf + amt, sizeof(buf) - amt, fmt, args);
116 amt = MIN(amt, sizeof(buf));
117 write(kptrace, buf, amt);