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 /* Number of characters written to console. */
46 static int64_t write_cnt;
48 /* Initializes the console. */
52 lock_init (&console_lock, "console");
55 /* Prints console statistics. */
57 console_print_stats (void)
59 printf ("Console: %lld characters output\n", write_cnt);
62 /* Acquires the console lock. */
64 acquire_console (void)
68 if (lock_held_by_current_thread (&console_lock))
71 lock_acquire (&console_lock);
75 /* Releases the console lock. */
77 release_console (void)
81 if (console_lock_depth > 0)
84 lock_release (&console_lock);
88 /* The standard vprintf() function,
89 which is like printf() but uses a va_list.
90 Writes its output to both vga display and serial port. */
92 vprintf (const char *format, va_list args)
97 __vprintf (format, args, vprintf_helper, &char_cnt);
103 /* Writes string S to the console, followed by a new-line
110 putchar_unlocked (*s++);
111 putchar_unlocked ('\n');
117 /* Writes the N characters in BUFFER to the console. */
119 putbuf (const char *buffer, size_t n)
123 putchar_unlocked (*buffer++);
127 /* Writes C to the vga display and serial port. */
132 putchar_unlocked (c);
138 /* Helper function for vprintf(). */
140 vprintf_helper (char c, void *char_cnt_)
142 int *char_cnt = char_cnt_;
144 putchar_unlocked (c);
147 /* Writes C to the vga display and serial port.
148 The caller has already acquired the console lock if
151 putchar_unlocked (uint8_t c)