Dekker's algorithm in Operating System

Dekker’s algorithm is the first solution of critical section problem. There are many versions of this algorithms, the 5th or final version satisfies the all the conditions below and is the most efficient among all of them.
The solution to critical section problem must ensure the following three conditions:
Mutual Exclusion
Progress
Bounded Waiting
Dekker’s algorithm succeeds to achieve mutual exclusion.
It uses variables to control thread execution.
It constantly checks whether critical section available.
main(){
   int thread_no = 1;
   startThreads();
}
Thread1(){
   do {
      // entry section
      // wait until threadno is 1
      while (threado == 2)
            ;
      // critical section
      // exit section
      // give access to the other thread
      threadno = 2;
      // remainder section
   } while (completed == false)
}
Thread2(){
   do {
      // entry section
      // wait until threadno is 2
      while (threadno == 1)
            ;
      // critical section
      // exit section
      // give access to the other thread
      threadno = 1;
      // remainder section
   } while (completed == false)
}
The problem of this first version of Dekker’s algorithm is implementation of lockstep synchronization. It means each thread depends on other to complete its execution. If one of the two processes completes its execution, then the second process runs. Then it gives access to the completed one and waits for its run. But the completed one would never run and so it would never return access back to the second process. Thus the second process waits for infinite time.
In Second version of Dekker’s algorithm, lockstep synchronization is removed. It is done by using two flags to indicate its current status and updates them accordingly at the entry and exit section.
main(){
   // flags to indicate whether each thread is in
   // its critial section or not.
   boolean th1 = false;
   boolean th2 = false;
   startThreads();
}
Thread1(){
   do {
      // entry section
      // wait until th2 is in its critical section
      while (th2 == true);
      // indicate thread1 entering its critical section
      th1 = true;
      // critical section
      // exit section
      // indicate th1 exiting its critical section
      th1 = false;
      // remainder section
   } while (completed == false)
}
Thread2(){
   do {
      // entry section
      // wait until th1 is in its critical section
      while (th1 == true);
      // indicate th2 entering its critical section
      th2 = true;
      // critical section
      // exit section
      // indicate th2 exiting its critical section
      th2 = false;
      // remainder section
   } while (completed == false)
}
Mutual exclusion is violated in this version. During flag update, if threads are preempted then both the threads enter into the critical section. Once the preempted thread is restarted, also the same can be observed at the start itself, when both the flags are false.
In this version, critical section flag is set before entering critical section test to ensure mutual exclusion.
main(){
   // flags to indicate whether each thread is in
   // queue to enter its critical section
   boolean th1wantstoenter = false;
   boolean th2wantstoenter = false;
   startThreads();
}
Thread1(){
   do {
      th1wantstoenter = true;
      // entry section
      // wait until th2 wants to enter
      // its critical section
      while (th2wantstoenter == true)
               ;
      // critical section
      // exit section
      // indicate th1 has completed
      // its critical section
      th1wantstoenter = false;
      // remainder section
   } while (completed == false)
}
Thread2(){
   do {
      th2wantstoenter = true;
      // entry section
      // wait until th1 wants to enter
      // its critical section
      while (th1wantstoenter == true)
               ;
      // critical section
      // exit section
      // indicate th2 has completed
      // its critical section
      th2wantstoenter = false;
      // remainder section
   } while (completed == false)
}
This version failed to solve the problem of mutual exclusion. It also introduces deadlock possibility, both threads could get flag simultaneously and they will wait for infinite time.
In this version of Dekker’s algorithm, it sets flag to false for small period of time to provide control and solves the problem of mutual exclusion and deadlock.
main(){
   // flags to indicate whether each thread is in
   // queue to enter its critical section
   boolean th1wantstoenter = false;
   boolean th2wantstoenter = false;
   startThreads();
}
Thread1(){
   do {
      th1wantstoenter = true;
      while (th2wantstoenter == true) {
      // gives access to other thread
      // wait for random amount of time
      th1wantstoenter = false;
      th1wantstoenter = true;
   }
   // entry section
   // wait until th2 wants to enter
   // its critical section
   // critical section
   // exit section
   // indicate th1 has completed
   // its critical section
   th1wantstoenter = false;
   // remainder section
   } while (completed == false)
}
Thread2(){
   do {
      th2wantstoenter = true;
      while (th1wantstoenter == true) {
      // gives access to other thread
      // wait for random amount of time
      th2wantstoenter = false;
      th2wantstoenter = true;
   }
   // entry section
   // wait until th1 wants to enter
   // its critical section
   // critical section
   // exit section
   // indicate th2 has completed
   // its critical section
   th2wantstoenter = false;
   // remainder section
   } while (completed == false)
}
Indefinite postponement is the problem of this version. Random amount of time is unpredictable depending upon the situation in which the algorithm is being implemented, hence it is not acceptable in case of business critical systems.
Fifth Version (Final Solution)
In this version, flavored thread motion is used to determine entry to critical section. It provides mutual exclusion and avoiding deadlock, indefinite postponement or lockstep synchronization by resolving the conflict that which thread should execute first. This version of Dekker’s algorithm provides the complete solution of critical section problems.
main(){
   // to denote which thread will enter next
   int favouredthread = 1;
   // flags to indicate whether each thread is in
   // queue to enter its critical section
   boolean th1wantstoenter = false;
   boolean th2wantstoenter = false;
   startThreads();
}
Thread1(){
   do {
      thread1wantstoenter = true;
      // entry section
      // wait until th2 wants to enter
      // its critical section
      while (th2wantstoenter == true) {
         // if 2nd thread is more favored
         if (favaouredthread == 2) {
            // gives access to other thread
            th1wantstoenter = false;
            // wait until this thread is favored
            while (favouredthread == 2);
            th1wantstoenter = true;
         }
      }
      // critical section
      // favor the 2nd thread
      favouredthread = 2;
      // exit section
      // indicate th1 has completed
      // its critical section
      th1wantstoenter = false;
      // remainder section
   } while (completed == false)
}
Thread2(){
   do {
      th2wantstoenter = true;
      // entry section
      // wait until th1 wants to enter
      // its critical section
      while (th1wantstoenter == true) {
         // if 1st thread is more favored
         if (favaouredthread == 1) {
            // gives access to other thread
            th2wantstoenter = false;
            // wait until this thread is favored
            while (favouredthread == 1);
            th2wantstoenter = true;
         }
      }
      // critical section
      // favour the 1st thread
      favouredthread = 1;
      // exit section
      // indicate th2 has completed
      // its critical section
      th2wantstoenter = false;
      // remainder section
   } while (completed == false)
}