PKUOS - Pintos
Pintos source browser for PKU Operating System course
Functions | Variables
console.c File Reference
#include <console.h>
#include <stdarg.h>
#include <stdio.h>
#include "devices/serial.h"
#include "devices/vga.h"
#include "threads/init.h"
#include "threads/interrupt.h"
#include "threads/synch.h"
Include dependency graph for console.c:

Go to the source code of this file.

Functions

static void vprintf_helper (char c, void *char_cnt_)
 Helper function for vprintf(). More...
 
static void putchar_have_lock (uint8_t c)
 Writes C to the vga display and serial port. More...
 
void console_init (void)
 Enable console locking. More...
 
void console_panic (void)
 Notifies the console that a kernel panic is underway, which warns it to avoid trying to take the console lock from now on. More...
 
void console_print_stats (void)
 Prints console statistics. More...
 
static void acquire_console (void)
 Acquires the console lock. More...
 
static void release_console (void)
 Releases the console lock. More...
 
static bool console_locked_by_current_thread (void)
 Returns true if the current thread has the console lock, false otherwise. More...
 
int vprintf (const char *format, va_list args)
 The standard vprintf() function, which is like printf() but uses a va_list. More...
 
int puts (const char *s)
 Writes string S to the console, followed by a new-line character. More...
 
void putbuf (const char *buffer, size_t n)
 Writes the N characters in BUFFER to the console. More...
 
int putchar (int c)
 Writes C to the vga display and serial port. More...
 

Variables

static struct lock console_lock
 The console lock. More...
 
static bool use_console_lock
 True in ordinary circumstances: we want to use the console lock to avoid mixing output between threads, as explained above. More...
 
static int console_lock_depth
 It's possible, if you add enough debug output to Pintos, to try to recursively grab console_lock from a single thread. More...
 
static int64_t write_cnt
 Number of characters written to console. More...
 

Function Documentation

◆ acquire_console()

static void acquire_console ( void  )
static

Acquires the console lock.

Definition at line 88 of file console.c.

References console_lock, console_lock_depth, intr_context(), lock_acquire(), lock_held_by_current_thread(), and use_console_lock.

Referenced by putbuf(), putchar(), puts(), and vprintf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ console_init()

void console_init ( void  )

Enable console locking.

Definition at line 64 of file console.c.

References console_lock, lock_init(), and use_console_lock.

Referenced by pintos_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ console_locked_by_current_thread()

static bool console_locked_by_current_thread ( void  )
static

Returns true if the current thread has the console lock, false otherwise.

Definition at line 115 of file console.c.

References console_lock, intr_context(), lock_held_by_current_thread(), and use_console_lock.

Referenced by putchar_have_lock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ console_panic()

void console_panic ( void  )

Notifies the console that a kernel panic is underway, which warns it to avoid trying to take the console lock from now on.

Definition at line 74 of file console.c.

References use_console_lock.

Referenced by debug_panic().

Here is the caller graph for this function:

◆ console_print_stats()

void console_print_stats ( void  )

Prints console statistics.

lib/kernel/console.h

Definition at line 81 of file console.c.

References printf(), and write_cnt.

Referenced by print_stats().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ putbuf()

void putbuf ( const char *  buffer,
size_t  n 
)

Writes the N characters in BUFFER to the console.

lib/kernel/stdio.h

Definition at line 153 of file console.c.

References acquire_console(), buffer, putchar_have_lock(), and release_console().

Here is the call graph for this function:

◆ putchar()

int putchar ( int  c)

Writes C to the vga display and serial port.

Definition at line 163 of file console.c.

References acquire_console(), putchar_have_lock(), and release_console().

Referenced by fail(), msg(), puts(), and read_line().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ putchar_have_lock()

static void putchar_have_lock ( uint8_t  c)
static

Writes C to the vga display and serial port.

The caller has already acquired the console lock if appropriate.

Definition at line 185 of file console.c.

References ASSERT, console_locked_by_current_thread(), serial_putc(), vga_putc(), and write_cnt.

Referenced by putbuf(), putchar(), puts(), and vprintf_helper().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ puts()

int puts ( const char *  s)

Writes string S to the console, followed by a new-line character.

Definition at line 140 of file console.c.

References acquire_console(), putchar_have_lock(), release_console(), and s.

Here is the call graph for this function:

◆ release_console()

static void release_console ( void  )
static

Releases the console lock.

Definition at line 101 of file console.c.

References console_lock, console_lock_depth, intr_context(), lock_release(), and use_console_lock.

Referenced by putbuf(), putchar(), puts(), and vprintf().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ vprintf()

int vprintf ( const char *  format,
va_list  args 
)

The standard vprintf() function, which is like printf() but uses a va_list.

Writes its output to both vga display and serial port.

Definition at line 126 of file console.c.

References __vprintf(), acquire_console(), release_console(), and vprintf_helper().

Referenced by debug_panic(), fail(), msg(), printf(), and usage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ vprintf_helper()

static void vprintf_helper ( char  c,
void *  char_cnt_ 
)
static

Helper function for vprintf().

Definition at line 174 of file console.c.

References putchar_have_lock().

Referenced by vprintf().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ console_lock

struct lock console_lock
static

The console lock.

Both the vga and serial layers do their own locking, so it's safe to call them at any time. But this lock is useful to prevent simultaneous printf() calls from mixing their output, which looks confusing.

Definition at line 18 of file console.c.

Referenced by acquire_console(), console_init(), console_locked_by_current_thread(), and release_console().

◆ console_lock_depth

int console_lock_depth
static

It's possible, if you add enough debug output to Pintos, to try to recursively grab console_lock from a single thread.

As a real example, I added a printf() call to palloc_free(). Here's a real backtrace that resulted:

lock_console() vprintf() printf() - palloc() tries to grab the lock again palloc_free()
thread_schedule_tail() - another thread dying as we switch threads schedule() thread_yield() intr_handler() - timer interrupt intr_set_level() serial_putc() putchar_have_lock() putbuf() sys_write() - one process writing to the console syscall_handler() intr_handler()

This kind of thing is very difficult to debug, so we avoid the problem by simulating a recursive lock with a depth counter.

Definition at line 57 of file console.c.

Referenced by acquire_console(), and release_console().

◆ use_console_lock

bool use_console_lock
static

True in ordinary circumstances: we want to use the console lock to avoid mixing output between threads, as explained above.

False in early boot before the point that locks are functional or the console lock has been initialized, or after a kernel panics. In the former case, taking the lock would cause an assertion failure, which in turn would cause a panic, turning it into the latter case. In the latter case, if it is a buggy lock_acquire() implementation that caused the panic, we'll likely just recurse.

Definition at line 31 of file console.c.

Referenced by acquire_console(), console_init(), console_locked_by_current_thread(), console_panic(), and release_console().

◆ write_cnt

int64_t write_cnt
static

Number of characters written to console.

Definition at line 60 of file console.c.

Referenced by console_print_stats(), and putchar_have_lock().