Needs #include <console.h>.
[pintos-anon] / src / lib / kernel / console.c
1 #include <console.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include "devices/serial.h"
5 #include "devices/vga.h"
6 #include "threads/interrupt.h"
7 #include "threads/synch.h"
8
9 static void vprintf_helper (char, void *);
10 static void putchar_unlocked (uint8_t c);
11
12 /* The console lock.
13    Both the vga and serial layers do their own locking, so it's
14    safe to call them at any time.
15    But this lock is useful to prevent simultaneous printf() calls
16    from mixing their output, which looks confusing. */
17 static struct lock console_lock;
18
19 void
20 console_init (void) 
21 {
22   lock_init (&console_lock, "console");
23 }
24
25 /* The standard vprintf() function,
26    which is like printf() but uses a va_list.
27    Writes its output to both vga display and serial port. */
28 int
29 vprintf (const char *format, va_list args) 
30 {
31   int char_cnt = 0;
32
33   if (!intr_context ())
34     lock_acquire (&console_lock);
35
36   __vprintf (format, args, vprintf_helper, &char_cnt);
37
38   if (!intr_context ())
39     lock_release (&console_lock);
40
41   return char_cnt;
42 }
43
44 /* Writes string S to the console, followed by a new-line
45    character. */
46 int
47 puts (const char *s) 
48 {
49   if (!intr_context ())
50     lock_acquire (&console_lock);
51
52   while (*s != '\0')
53     putchar_unlocked (*s++);
54   putchar_unlocked ('\n');
55
56   if (!intr_context ())
57     lock_release (&console_lock);
58
59   return 0;
60 }
61
62 /* Writes C to the vga display and serial port. */
63 int
64 putchar (int c) 
65 {
66   if (!intr_context ())
67     lock_acquire (&console_lock);
68
69   putchar_unlocked (c);
70
71   if (!intr_context ())
72     lock_release (&console_lock);
73
74   return c;
75 }
76 \f
77 /* Helper function for vprintf(). */
78 static void
79 vprintf_helper (char c, void *char_cnt_) 
80 {
81   int *char_cnt = char_cnt_;
82   (*char_cnt)++;
83   putchar_unlocked (c);
84 }
85
86 /* Writes C to the vga display and serial port.
87    The caller has already acquired the console lock if
88    appropriate. */
89 static void
90 putchar_unlocked (uint8_t c) 
91 {
92   serial_putc (c);
93   vga_putc (c);
94 }