Project 1 Tutorial
Download
Report
Transcript Project 1 Tutorial
Project Part I Background
Tom Roeder
CS415 2005sp
You need to implement
minithreads
synchronization
yield
fork/create/initialize
stop/start
P/V
create/initialize/destroy
FIFO non-preemptive scheduler
Test cases
Threads
Each thread must have its own control block
Contains
top pointer
base pointer
thread identifier
… whatever else you find useful
To switch between threads, must change esp
Context Switching
context_switch(new, old)
ESP
??
thread 2
registers
ret addr 2
thread 1
call stack
thread 1
thread 2
call stack
thread 2
Context Switching
context_switch(new, old)
ESP
thread 2
registers
ret addr 2
thread 1
registers
ret addr 1
thread 1
call stack
thread 1
thread 2
call stack
thread 2
Context Switching
context_switch(new, old)
ESP
thread 2
registers
ret addr 2
thread 1
registers
ret addr 1
thread 1
call stack
thread 1
thread 2
call stack
thread 2
Context Switching
context_switch(new, old)
ESP
thread 1
registers
ret addr 1
thread 1
call stack
thread 1
thread 2
call stack
thread 2
Frequently Asked Questions
How do I bootstrap into a minithreads
environment? (a.k.a. How do I context switch
into my first thread?)
Use the initial kernel thread
Wrap it in a minithread structure
The stack sometimes grows downwards and
sometimes up. What’s going on?
Normally grows down
We normally talk (and think) about it growing up
Frequently Asked Questions
How do I clean up my thread when I’m still on
its stack?
You can’t
add a garbage collection thread.
What’s the difference between create and
fork?
create results in a new not running thread
fork results in a new running thread
Scheduler
Take the first element off the run queue and
run it (FIFO)
Need to have a garbage collection thread
Need to have a system idle thread
see the System Idle Process in Ctl-Shift-Esc
Should run when nothing else is running
When all your threads exit, your program
should stay around
Software Engineering
Need to check for valid values in functions
Use AbortOnCondition
Might want to define something like:
#define AbortOnNull(var) AbortOnCondition(var == NULL, #var “ should
not be NULL”);
Use macros to your advantage
Check return values of functions with
AbortOnError(func_call());
Software Engineering
Comments
Naming
Clear and understandable
Document why not what
We should not have to guess the code’s purpose
give variables simple functional names
single letters are in general discouraged
Modularization
remember to refactor every once in a while
Testing
Write a test program
Create many threads
Create no threads
try our tests (test[1-3].c, sieve.c, buffer.c)
unit test your functions
try unreasonable values for parameters
figure out invariants and check them
The key is to systematically try as many
cases as possible
Testing
Best to automate testing:
Test each other’s code in the group
Have a test harness generate lots of tests
Especially ones that are easy to figure out what
the right answer should be
When you look at code for long enough, you don’t
always notice the bugs
Code review
especially the tricky parts of the code
Questions?
Synchronization
Recall the problem posed in 414
Enter locks
Operations that appear atomic to C are not always
Even in C, we often don’t want to be interrupted
Need a Do Not Disturb sign
allow implementation of mutual exclusion
lets N threads in at a time
Everyone else must wait outside
We will use semaphores for now
Synchronization: Semaphores
Two operations: P (proberen) and V
(verhogen)
P (test) does the following atomically:
V (increment) does the following atomically:
decrement the semaphore
if it is less than 0, block
else continue
increment the semaphore
if the value of the semaphore is now greater than or
equal to 0 and there is someone waiting, let them in
Note that we have not solved atomicity
Synchronization: Semaphores
Fortunately, there is no preemption for now
Easy to get mutual exclusion
Just don’t yield in P or V!
Ranveer will explain in 414 what to do in the
case of preemption
Don’t need to know this for this part of the project
Synchronization Example
semaphore s;
int x = 0;
thread_1 () {
while(true) {
P(s);
x = x + 10;
V(s);
}
}
thread_2 () {
while(true) {
P(s);
x = x - 10;
V(s);
}
}