CPSC 213: Assignment 7
Due Fri Nov 9, 6pm
Goal
In this assignment you will investigate interrupts and asynchronous
programming by reading and modifying a program that uses signals to
trigger asynchronous actions. This assignment is closely modeled on
the asynchronous disk read example discussed in the lecture and gives
you a chance to experience this sort of programming first hand, using
a software environment that mimics hardware interrupts. You will be
working entirely in C.
Interrupts and Asynchronous Programming
Download the package for this assignment and extract
it. You will be modifying the file async.c, a short C
program. You should SSH into one of the x86 ugrad.cs.ubc.ca machines (annacis,
bowen, deas, lulu) to edit, compile, and debug your code. Compile it
with the command
gcc -g -m32 -o async async.c
and run it with ./async or debug it with gdb async
(You should run these commands in the same directory that you
compiled the code.)
This program ends with an infinite loop; make sure to kill it when it is
done by typing Control-C so that it does not run forever!
This program uses a Unix OS feature called "signals" to mimic hardware
interrupts. In the boot procedure, the program registers
interruptServiceRoutine as a signal handler for the
SIGALRM signal and then tells the OS to deliver this signal
to the program once every second. The program includes a method called
doAsync that schedules an asynchronous event, sort of like a
disk-read request. These events complete in order, one at a time, each
time the SIGALRM is delivered to the program. The
doAsync procedure enqueues events on a circular completion
queue and interruptServiceRoutine dequeues these completion
events when SIGALRMs arrive and delivers the completion by
calling the completion routine with two parameters, a pointer and an
int, whose meaning is determined by the completion routine.
You will note the use of the type void*. This type is called
an "opaque pointer" and is used to store pointers of any type. The
program includes a small example of the use of this system to
asynchronously print three strings.
This program is a simplified version of what an I/O controller does:
some work is done with doAsync, and then it uses
SIGALRM to signal that the work has been completed. In this
simple example, the OS isn't really doing anything other than
regularly delivering signals.
Task 1: Understand and Comment Existing Code
Your first task is to insert detailed comments in the program to
carefully explain every data structure and procedure. You
should read, compile, and run the program to understand what it does.
Do not add comments to individual lines of code, but ensure that your
other comments are detailed enough to fully explain what this code
does. Use the man command as necessary to get the documentation for
functions such as signal and ualarm, and so on. If
man presents you with multiple options, choose the commands
from sections 3 and 3p.
Task 2: Modify Code
Your second task is to modify this program to use the doAsync procedure and this
framework to implement a program using the asynchronous
operations add and subtract.
Each should be implemented by a procedure that is never called
directly but that is instead caused to run by doAsync.
First, define
a struct Triple with struct members arg0, arg1,
result, and complete that hold the arguments and result
for a simple computation. The complete field should indicate
whether the computation has been completed.
Then, write two simple procedures:
1. add (void* xp, int n) that casts xp to a struct Triple pointer and
computes xp->result = xp->arg0 + xp->arg1.
2. sub (void* xp, int n) that casts xp to a struct Triple pointer and
computes xp->result = xp->arg0 - xp->arg1.
Finally, write a procedure that uses only these two procedures and the
doAsync procedure to compute the value of the expression
((A+B)-(C+D))+E, where A, B, C, D, and E are the first through
fifth digits of your student number, except with 0 replaced by 10 (e.g.
if your student number is 12305678, compute ((1+2)-(3+10))+5.) Store the
final result in a global variable, and terminate the program after printing
its value.
A key challenge here is that some of operations use results from
previous operations. You cannot do the subtraction until the additions
for (A+B) and (C+D) have completed. You will thus
need to synchronize your program to some extent. Implement this
synchronization using a shared variable whose value indicates whether
the computation can continue and then "spin" on this variable until it
has this value. For example, the code while (n != 1) {} waits
until the variable n has the value 1. This approach is an
example of polling a variable for a value using a spinlock.
More sophisticated alternatives will be covered later in the course.
Hints
- Do not synchronize any more than necessary: for example,
(A+B) and (C+D) do not need to be synchronized with
each other.
Provided Materials
Handing In
Use the handin program. The assignment directory is a7.
Please hand in exactly and only the following files with the specified names.
- README.txt that contains
- The first three lines should be your name, student number, and 4-character CS account
name, with each on a separate line, like:
John Doe
12345678
a0b1
- The statement "I have read and understood the plagiarism policies at
http://www.ugrad.cs.ubc.ca/~cs213/winter12t1/cheat.html"
Of course, make sure that's true!
- Any additional assumptions or comments you would like to make.
Following the academic conduct guidelines, if you discussed the
assignment in detail with anybody besides the instructor or TAs, say
so explicitly and list their names here.
- async.c containing your modified version of the provided
async.c, as described above
File Format Requirements
Refer to
the section of the same name in the second assignment for the file format
requirements. All files you handin MUST be plain ASCII text, and all
source code MUST compile on the ugrad Linux x86 machines in order to
receive credit for it.
Last modified 2012-10-27 18:45