Project #7: Multicore Semaphores and the Asynchronous Device Driver

Submit: Turn in your entire xinu-hw7 directory source files using the turnin command on morbius.mscsnet.mu.edu or one of the other Systems Lab machines. Please run "make clean" in the compile/ subdirectory just before submission to reduce unnecessary space consumption.

Work should be completed in pairs. Be certain to include both names in the comment block at the top of all source code files, with a TA-BOT:MAILTO comment line including any addresses that should automatically receive results. It would be courteous to confirm with your partner when submitting the assignment.

Multicore Semaphores

Classic Semaphore

You must understand classic semaphores before using them to implement this assignment. An implementation of classic semaphores with waiting queues has been provided for you, and can be found across several files including include/semaphore.h, system/semcreate.c, system/semfree.c, system/signal.c, system/signaln.c, and system/wait.c.

The implementation that is given to you is a broken implementation. It will work on a single core machine, but it will not work on a multicore machine. Part of your assignment is to fix the implementation so it will run correctly. Only a few simple modifications need to be done. There is a new file, system/atomic.S, which contains assembly methods that help with carrying out atomic operations such as incrementing and decrementing an integer.

The Asynchronous Serial Driver

You already have implemented a Synchronous Serial Driver for your operating system. Recall from Assignment 3: "The driver is synchronous because it waits for the slow I/O device to do its work, rather than using interrupts to communicate with the hardware."

Now, you will implement an Asynchronous Serial Driver (for an interrupt-driven UART) using semaphores across multiple cores. A proper asynchronous driver does not wait needlessly for the hardware, but instead only communicates with the UART when a hardware interrupt indicates to the system that it is ready for the next batch of work.

As discussed in lecture and lab, there are two parts to the asynchronous serial driver: the Lower Half and the Upper Half.

The Upper Half of the driver consists of the functions called by various user-level processes, such as getc(), putc(), and printf(). As much as possible, the upper half functions shield the user from the intricate details of the hardware.

The Lower Half of the driver consists of the handler functions run when hardware interrupt requests arrive. Lower half functions must do their work quickly, and deal with data that has been buffered up by the upper half functions.

The Lower half has been implemented for you in system/uarthandler.c. You will be working on the upper half functions in system/printf.c.

To implement your asynchronous driver, follow these steps:

  1. Begin by fixing the given implementation of semaphores in system/signal.c, system/signaln.c, system/wait.c.
  2. Implement the Upper Half driver functions in system/printf.c
  3. Write testcases that demonstrate your working implementation, as well as your understanding of the assignment, in testcases.c.

Notes


[back]

[Revised 2020 Mar 04 10:57 DWB]