//    ***** ***** Index ***** *****
// 1. Eisenberg & McGuire's alg for n processes
// 2. Microcode wait(semaphore) & signal(semaphore)
// 3. Peterson's (polite) alg for 2 processes
//
// Note: if one process (currently in CS) requires
//   shared data (which at the present time n/a)
//   produced by another process, it must exit CS
//   in order for the other one (producer) to put
//   CS data. Else the result would be infinite
//   switching with one process always in CS, one
//   always isn't resulting in zero productivity
//
//================================================
// ***** 1. Eisenberg & McGuire's algorithm *****
//  - for n processes (i in code is process,
//    number, ie, P)i)
//  - j is a local varialbe (no need to init)

enum pstate {idle, want_in, in_cs};
enum pstate flag[n]; // initialize all to idle
int turn; // 0,1,..., n-1
while (1) {
  while (1) {
    flag[i] = want_in;
    j = turn;
    while (j!=i) {
      if (flag[j]!=idle)
        j = turn;
      else
        j = (j+1)%n;
    }
    flag[i] = in_cs;
    j=0;
    while ((j<n) && (j==i || flag[j]!=in_cs))
      j++;
    if ((j>=n) && (turn==i || flag[turn]==idle))
      break;
  }
  turn = i;

// *****************************
// *     Critical Section      *
// *****************************
j = (turn+1)%n;
while (flag[j]==idle)
     j = (j+1)%n;
turn = j;
flag[i] = idle;
// *****************************
// *     Remainder Section     *
// *****************************
}

//================================================
//================================================
// ***** 2. CS protection with microcode *****
// - use semaphore mutex which is an int init to 1
// - wait(semaphore) & signal(semaphore) are
//   executed without interruption (microcode)

typedef short int semaphore;
void wait(semaphore S) {
  while (S<=0)
    ;
  S--;
}

void signal(semaphore S) {
  S++;
}

semaphore mutex = 1; // initialized to 1
// ... some more code ...
while (1) {
  wait (mutex);
// *****************************
// *     Critical Section      *
// *****************************
  signal (mutex);
// *****************************
// *     Remainder Section     *
// *****************************
}

//================================================
//================================================
// **** 3. Peterson's Polite alg (2 processes) ***
// - To enter CS, P)i sets flag[i] to TRUE & set
//   turn to j, thereby asserting if the other
//   process wishes to enter CS it can do so. If
//   both processes try to enter at the same time,
//   turn will be set to i & j at roughly the same
//   time. But only one ass't will last

bool flag[2] = {FALSE, FALSE};
int turn;
// the following code is for process i, the other
//    process is process j
while (1) {
  flag[i] = TRUE;
  turn = j;
  while (flag[j] && turn==j) ;
  // *****************************
  // *     Critical Section      *
  // *****************************
  flag[i] = FALSE;
  // *****************************
  // *     Remainder Section     *
  // *****************************
}