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