Software Systems
Fall 2006
Homework 5
Due: Monday 6 November
The purpose of this assignment is to experiment with several
implementations of locks, and to measure the frequency of errors
caused by incorrect synchronization primitives.
Pick up the code by running
wget http://wb/ss/code/lock.tgz
tar -xzf lock.tgz
cd lock
The file lock.c contains an incorrect implementation
of a lock written in C. The file lock.x86.s contains
a correct (I think) implementation of a lock written in
Intel x86 assembler code. I will explain it in
class. The Makefile shows how to make programs called
goodlock and badlock based on the two versions
of a lock. Compile and run both programs.
The file example.c contains the skeleton of a multi-threaded
program with shared state. The shared state is encapsulated in
an object called Environment. Compile and run example.
- Starting with a copy of example.c, write a program that
uses at least two threads and that accesses a shared variable
concurrently. Your goal is to get both threads to access the shared
variable over and over in order to check whether any synchronization
errors occur, and if so, to characterize how often they occur. We
will discuss this in class.
- Run the program and see how frequently
synchronization errors occur when there is no synchronization control.
- Now use the broken lock implementation to enforce exclusive access to
the shared variable. Test whether your program is in fact achieving
mutual exclusion. What is the frequency of synchronization errors
now?
- Finally, replace the broken lock implementation with the `correct'
one. What is the frequency of synchronization errors now? Can we
prove that the `correct' implementation is correct?
- Read the handout from Programming with POSIX threads
(butenhof97mutex.pdf) that describes pthread mutexes. Print the
documentation of the relevant library functions.
- Make a copy of lock.c and call it mutex.c. Change the
implementation of make_lock, acquire and release
so that they use pthread mutexes. This should be a trivial
implementation, since mutexes are the same thing as locks.
All you are doing is creating a veneer that changes the interface.
- What is the frequency of synchronization errors using the
pthread lock implementation?
- Time your program to compare the efficiency of my lock implementation
with pthread mutexes. Which is faster? Where is the extra time spent,
in user code, system code, or operating system overhead?
- Read the handout from Programming with POSIX threads
(butenhof97condition.pdf) that describes pthread condition variables.
Print the documentation of the relevant library functions.
- Write an implementation of a Semaphore using pthread mutexes
and condition variables. Your implementation should provide functions
named make_semaphore, semaphore_wait, and semaphore_signal,
in a file named semaphore.c. You should also provide a header
file named semaphore.h that includes the type definition for
Semaphore and prototypes of the semaphore `methods'.
- Create a modified version of your program that uses your Semaphore
implementation as a mutex.
- Add a line to the Makefile to build a program named semlock
using your Semaphore implementation.
- Run your program and confirm that there are no synchronization
errors.
- Time your program to compare the efficiency of using your
Semaphore as a mutex as opposed to using a pthread mutex. Which is
faster? Where is the extra time spent, in user code, system code, or
operating system overhead?
|