So does a process pre-empt if it's busy waiting? - yes. From the perspective of a pre-emptive scheduler it is yet another process consuming CPU cycles, and can be swapped out.
But wouldn't this again require P1 to be pre-empted, and bring back P0 from 'Ready' to 'Running' and get it executed ? - No, this will not be required.
Let's consider the following for reference, (from Sec. 2.3 Modern Operating Systems 4th edition by Andrew S. Tanenbaum & Herbert Bos)
#define FALSE 0
#define TRUE 1
#define N 2 /*number of processes*/
int turn; /*whose turn is it?*/
int interested[N]; /*all values initially 0 (FALSE)*/
void enter_region(int process); /*process is 0 or 1*/
int other; /*number of the other process*/
other = 1-process; /*the opposite of process*/
interested[process] = TRUE; /*show that you are interested*/
turn = process; /*set flag*/
while (turn == process && interested[other] == TRUE) /*null statement*/;
void leave_region(int process) /*process: who is leaving*/
interested[process] = FALSE; /*indicate departure from critical region*/
FALSE (interested here is the
flag in your code) - indicating that no one is interested in entering the critical region initially.
As you mentioned, let's suppose process
0 needs to enter the critical region and calls into
enter_region first. It sets
0. Let's suppose process
0 is pre-empted now - before it could execute the
while loop condition.
1 needs the critical region and calls
enter_region now, sets
while loop condition is
while (turn == 1 && interested == TRUE)
Think of this is as, "if it's my turn but someone else is interested in getting in - be nice to them, let them in and wait here". (it is not
while (turn == 0 && interested == TRUE) like you've mentioned) process
1 enters the loop and cannot return.
Suppose the scheduler decides to pre-empt process
1 and process
0 gets a chance to run. It returns from
enter_region immediately to enter the critical region. Remember that the loop condition for process
turn == 0 && interested == TRUE which is certainly not true at this time as
After some time let's suppose process
0 exits the critical region and calls
leave_region - it sets
FALSE indicating that it is not interested in the critical region anymore.
Later when process
1 gets to run again, it fails
turn == 1 && interested == TRUE (as
FALSE), and enters the critical region - as you can see, process
1 did not have to wait for process