1 // Simple implementation of cprintf console output for the kernel,
2 // based on printfmt() and the kernel console's cputchar().
5 #include <ros/common.h>
13 spinlock_t output_lock = SPINLOCK_INITIALIZER_IRQSAVE;
15 void putch(int ch, int **cnt)
21 // buffered putch to (potentially) speed up printing.
22 // static buffer is safe because output_lock must be held.
23 // ch == -1 flushes the buffer.
24 void buffered_putch(int ch, int **cnt)
26 #define buffered_putch_bufsize 64
27 static char buf[buffered_putch_bufsize];
28 static int buflen = 0;
36 if(ch == -1 || buflen == buffered_putch_bufsize)
43 int vcprintf(const char *fmt, va_list ap)
45 struct per_cpu_info *pcpui;
54 trace_vprintk(fmt, args);
57 /* this ktrap depth stuff is in case the kernel faults in a printfmt call.
58 * we disable the locking if we're in a fault handler so that we don't
61 pcpui = &per_cpu_info[0];
63 pcpui = &per_cpu_info[core_id()];
64 /* lock all output. this will catch any printfs at line granularity. when
65 * tracing, we short-circuit the main lock call, so as not to clobber the
66 * results as we print. */
67 if (!ktrap_depth(pcpui)) {
68 #ifdef CONFIG_TRACE_LOCKS
69 disable_irqsave(&irq_state);
70 __spin_lock(&output_lock);
72 spin_lock_irqsave(&output_lock);
76 // do the buffered printf
77 vprintfmt((void*)buffered_putch, (void*)&cntp, fmt, ap);
79 // write out remaining chars in the buffer
80 buffered_putch(-1,&cntp);
82 if (!ktrap_depth(pcpui)) {
83 #ifdef CONFIG_TRACE_LOCKS
84 __spin_unlock(&output_lock);
85 enable_irqsave(&irq_state);
87 spin_unlock_irqsave(&output_lock);
94 int cprintf(const char *fmt, ...)
103 cnt = vcprintf(fmt, ap);