Add putbuf().
[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 the N characters in BUFFER to the console. */
63 void
64 putbuf (const char *buffer, size_t n) 
65 {
66   if (!intr_context ())
67     lock_acquire (&console_lock);
68
69   while (n-- > 0)
70     putchar_unlocked (*buffer++);
71
72   if (!intr_context ())
73     lock_release (&console_lock);
74 }
75
76 /* Writes C to the vga display and serial port. */
77 int
78 putchar (int c) 
79 {
80   if (!intr_context ())
81     lock_acquire (&console_lock);
82
83   putchar_unlocked (c);
84
85   if (!intr_context ())
86     lock_release (&console_lock);
87
88   return c;
89 }
90 \f
91 /* Helper function for vprintf(). */
92 static void
93 vprintf_helper (char c, void *char_cnt_) 
94 {
95   int *char_cnt = char_cnt_;
96   (*char_cnt)++;
97   putchar_unlocked (c);
98 }
99
100 /* Writes C to the vga display and serial port.
101    The caller has already acquired the console lock if
102    appropriate. */
103 static void
104 putchar_unlocked (uint8_t c) 
105 {
106   serial_putc (c);
107   vga_putc (c);
108 }