1
votes

Usually, when processes want to wait some events that are not available, we can put them into sleep and wake up them later when the events occur.

The familiar codes below fulfil this task:

while (!events) {
    DEFINE_WAIT(wait);

    prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);
    if (!events)
        schedule();
    finish_wait(&q, &wait);
}

Imagine that in a preemptive kernel there exists two processes in which process A is a producer and process B is a consumer. Process B is executing the codes above, waiting for the some datas produced by process A become valid.

Now, I think process B will lost the wake-up chance if the executing path of two processes is as below.

  1. Process B checks event in while statement, and now it is return false.
  2. Process B executes DEFIN_WAIT(wait).
  3. Process A produces some datas just after process B finished executing DEFIN_WAIT(wait) and before executing prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);.
  4. Process B executes prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);.
  5. Process B is preempted by other process just before it executes if (!events).

Because of the state of process B now is TASK_INTERRUPTIBLE, it won't be schedule to CPU again. So, I think, Process B will never be waken....

1

1 Answers

2
votes

Your final verdict is wrong: preemption does not work with task state. So, even in TASK_INTERRUPTIBLE state preempted task can gain CPU again.

See, e.g this or that.