/* Get access to process table atomically.  ("exchangeword"
   is like "test_and_set") */
void StartUsingProcessTable(void) {
  int flag;
  extern in ProcessTableFreeFlag;
  
  /* busy wait until get a 1 from shared flag */
  while (1) {
    asm {
      move 0,r1;
      exchangeword r1, ProcessTableFreeFlag;
      store r1,flag;
    }
    if (flag == 1)		/* do we have access to proc table? */
      break;
  }

}

void FinishUsingProcessTable(void) {
  ProcessTableFreeFlag = 1;
}

int SelectProcessToRun(void) {
  static int next_proc = MAX_PROCESSES;
  static int return_value = -1;	/* NEW CODE: cannot return immediately */

  StartUsingProcessTable();	/* NEW CODE */

  /* NEW CODE: which processor are we? */
  if (ProcessorExecutingThisCode() == 1)
    current_process = p1_current_process;
  else
    current_process = p2_current_process;

  if (current_process > 0 
      && pd[current_process].slotAllocated
      && pd[current_process].state == READY
      && pd[current_process].timeLeft > 0)
    return_value = current_process;

  else {

    for (int i=1; i < MAX_PROCESSES; i++) {
      next_proc++;
      if (next_proc >= MAX_PROCESSES)
	next_proc = 1;
      if (pd[next_proc].slotAllocated && pd[next_proc].state == READY) {
	pd[next_proc].timeLeft = TIME_QUANTUM;
	pd[next_proc].state = RUNNING;
      return_value = next_proc;
      }
    }
  }

  FinishUsingProcessTable();	/* NEW CODE */

  return return_value;
}

