0
votes

I was reading the OS textbook, in the synchronization chapter,it says :

In particular, most implementations of thread systems enforce the invariant that a thread always disables interrupts before performing a context switch

Hence when writing Aquire() before go to sleep it will first disable interrupt.

My question is why interrupt disable is needed before context switch, is it use to protect the registers and keep the Aquire() atomic?

Aquire() is used before the critical section as:

Aquire(){
 disable interrupt;
 if (is busy){
    put on wait queue;
    sleep();
 }
 else set_busy;
 enable interrupt;
}

Go to sleep will implement context switch,why should we disable interrupt during context switch?Can we change the code to :

Aquire(){
 disable interrupt;
 if (is busy){
    enable interrupt;
    put on wait queue;
    sleep();
 }
 else set_busy;
 enable interrupt;
}

That is enables interrupt in thread A instead of letting other thread B after context switch(after A go to sleep) enable interrupt?

1
What is Aquire()?curiousguy
There are many types of aquire() ,I have corrected my question.yi li

1 Answers

1
votes

Typically, a synchronization primitive requires updating multiple data locations simultaneously. For example, a semaphore Acquire might require changing the state of the current thread to blocked, updating the count of the semaphore, removing the current thread from a queue and placing it on another queue. Since simultaneously isn't really possible(*), it is necessary to devise an access protocol to simulate this. In a single cpu system, the easiest way to do this is disable interrupts, perform the updates, then re-enable interrupts. All software following this protocol will see the updates at once.

Multi-cpu systems typically need something extra to synchronize threads on separate cpus from interfering. Disabling interrupts is insufficient, since that only affects the current cpu. The something extra is typically a spin lock, which behaves much like a mutex or binary semaphore, except that the caller sits in a retry loop until it becomes available.

Even in the multi-cpu system, the operation has to be performed with interrupts disabled. Imagine Thread#0 has acquired a spinlock on cpu#0; then an interrupt on cpu#0 causes Thread#1 to preempt, and Thread#1 then attempts to acquire the same spinlock. There are many scenarios which amount to this.

(*) Transaction-al Memory provides something like this, but with limited applicability, and the implementation has to provide an independent implementation to ensure forward progress. Also, since transactions do not nest, they really need to disable interrupts as well.