Finish monday
parent
b6749b36d1
commit
a0c0091bde
|
@ -318,4 +318,59 @@ main() {
|
|||
|
||||
|
||||
|
||||
### Preemptive Kernel
|
||||
|
||||
* Preemption, thread objects and the timer interrupt
|
||||
* Enabling synchronization: Busy waiting, tes-and-set, disabling the timer interrupt
|
||||
* Blocking and suspend & resume
|
||||
* An API for synchronization? Semaphores!
|
||||
|
||||
|
||||
#### Preemption
|
||||
|
||||
* Make a handler for a timer interrupt
|
||||
* Store all registers (including IP & SP) in a "thread object"
|
||||
* Organize queue of processes (Round Robin e.g. - a collection of thread objects?)
|
||||
* Can synchronize by: while(!ready); (busy wating, "spin locks")
|
||||
|
||||
**Bad solution**
|
||||
|
||||
{% highlight c%}
|
||||
while(lock==1) {}
|
||||
lock = 1;
|
||||
// We may run
|
||||
lock = 0;
|
||||
{% endhighlight %}
|
||||
|
||||
**Better solution**
|
||||
|
||||
{% highlight c%}
|
||||
void t1() {
|
||||
flag1 = 1; // Declare my intention
|
||||
turn = 2; // But try to be polite
|
||||
while(flag2 == 1 && turn == 2) {}
|
||||
// We may run
|
||||
flag1 = 0;
|
||||
}
|
||||
{% endhighlight %}
|
||||
|
||||
##### Looking more closely at the arsenal
|
||||
|
||||
**How can we make basic synchronization under preemption?**
|
||||
|
||||
* Spin locks (wasting time and cpu)
|
||||
* Test&Set (swap) assembly instruction (atomic, but not obvious)
|
||||
* Disable interrupt (steals control from OS/scheduler)
|
||||
|
||||
**But**
|
||||
* If we disable the timer interrupt we don not have preemption any more
|
||||
* And... Are these good abstractions in the application programmer domain?
|
||||
|
||||
#### Blocked threads
|
||||
|
||||
**Let us introduce another queue; the collection of threads not running, waiting for something**
|
||||
|
||||
* Fixes the bad performance of spin locks. Is conceptually better.
|
||||
* "Suspend" moves a thread object from "run" queue to "blocked" queue
|
||||
* "Resume" moves it back.
|
||||
|
||||
|
|
Loading…
Reference in New Issue