4 #include "devices/serial.h"
5 #include "devices/vga.h"
6 #include "threads/interrupt.h"
7 #include "threads/synch.h"
9 static void vprintf_helper (char, void *);
10 static void putchar_unlocked (uint8_t c);
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;
19 /* It's possible, if you add enough debug output to Pintos, to
20 try to recursively grab console_lock from a single thread. As
21 a real example, I added a printf() call to palloc_free().
22 Here's a real backtrace that resulted:
26 printf() - palloc() tries to grab the lock again
28 schedule_tail() - another thread dying as we switch threads
31 intr_handler() - timer interrupt
36 sys_write() - one process writing to the console
40 This kind of thing is very difficult to debug, so we avoid the
41 problem by simulating a recursive lock with a depth
43 static int console_lock_depth;
45 /* Initializes the console. */
49 lock_init (&console_lock, "console");
52 /* Acquires the console lock. */
54 acquire_console (void)
58 if (lock_held_by_current_thread (&console_lock))
61 lock_acquire (&console_lock);
65 /* Releases the console lock. */
67 release_console (void)
71 if (console_lock_depth > 0)
74 lock_release (&console_lock);
78 /* The standard vprintf() function,
79 which is like printf() but uses a va_list.
80 Writes its output to both vga display and serial port. */
82 vprintf (const char *format, va_list args)
87 __vprintf (format, args, vprintf_helper, &char_cnt);
93 /* Writes string S to the console, followed by a new-line
100 putchar_unlocked (*s++);
101 putchar_unlocked ('\n');
107 /* Writes the N characters in BUFFER to the console. */
109 putbuf (const char *buffer, size_t n)
113 putchar_unlocked (*buffer++);
117 /* Writes C to the vga display and serial port. */
122 putchar_unlocked (c);
128 /* Helper function for vprintf(). */
130 vprintf_helper (char c, void *char_cnt_)
132 int *char_cnt = char_cnt_;
134 putchar_unlocked (c);
137 /* Writes C to the vga display and serial port.
138 The caller has already acquired the console lock if
141 putchar_unlocked (uint8_t c)