In this assignment, we will give you part of a working thread system. Your job is to complete it and then use it to solve several synchronization problems.
The first step is to read and understand the partial thread system we’ve provided. This thread system implements thread fork, thread completion, and semaphores for synchronization.
Properly synchronized code should work no matter what order the scheduler chooses to run the threads on the ready list. In other words, we should be able to put a call to Thread::Yield() (which causes the scheduler to pick another thread to run) anywhere in your code where interrupts are enabled without changing the correctness of your code. You will be asked to write properly synchronized code as part of later assignments, so understanding how to do this is crucial to being able to do the project.
To aid you in this task, code linked in with Nachos will cause Thread::Yield() to be called in a repeatable but unpredictable way. Nachos code is repeatable in that if you call it repeatedly with the same arguments, it will do exactly the same thing each time. However, if you invoke Nachos with “nachos -rs #”, with a different number each time, calls to Thread::Yield() will be inserted in different places in the code.
Warning: in our implementation of threads, each thread is assigned a small, fixed-size execution stack. This may cause bizarre problems (such as segmentation faults at strange lines of code) if you declare large data structures to be automatic variables (e.g., ``int buf[1000];''). You will probably not notice this during the semester, but if you do,
you may change the size of the stack by modifying the StackSize define in switch.h.
Although the solutions can be written as normal C routines, you will find organizing your code to be easier if you structure your code as C++ classes. Also, there should be no busy-waiting in any of your solutions to this assignment.
Don’t worry if you don’t have to write much code for each of these: the assignment is largely conceptual and not a programming chore.
All the code you write should be well commented so we can understand what you changed. To hand in code, one of the members of your project should use the turnin command:
To turning a set of files or directories, run:
turnin –ccse451 –pthreads {list of files or directories to turning)
For example, to turning all the files in the “threads” directory, you would run this command in the “code” directory:
turnin –ccse451 –pthreads threads
To see which files were turned in, run:
turnin –ccse451 -v
You should hand in all the code you changed as well as a file named “readme” containing your group name and the members of the team. In addition, we would like a short paper write-up describing what changes you made, how well they worked, how you tested your changes, and how each group member contributed to the project. The write-up should be mailed to the TAs by 12 noon at February 3rd, so that you won’t need to worry about working on it just before the code is due.