Using wait_event_interruptible and wake_up_all tog

2020-07-30 02:00发布

问题:

For a class project involving scheduling processes using blocking and locks, we're supposed to use two kernel functions:

int wait_event_interruptible(wait_queue_head_t q, CONDITION);
void wake_up_all(wait_queue_head_t *q); 

The explanation of wait_event_interruptible is:

Blocks the current task on a wait queue until a CONDITION becomes true.

This is actually a macro. It repeatedly evaluates the CONDITION, which is a fragment of C code such as foo == bar or function() > 3. Once the condition is true, wait_event_interruptible returns 0. If the condition is false, the current task is added to the wait_queue_head_t list with state TASK_INTERRUPTIBLE; the current process will block until wake_up_all(&q) is called, then it will re-check the CONDITION. If the current task receives a signal before CONDITION becomes true, the macro returns -ERESTARTSYS.

And the explanation of wake_up_all is:

Wake up all tasks in the wait queue by setting their states to TASK_RUNNABLE.

I'm having a hard time figuring out how exactly these functions work and how to use them together. For example, when does the CONDITION get checked? Does wait_event_interruptible continuously poll, or does it only recheck the condition when wake_up_all is called? This explanation is a little unclear.

If you could give an example of how to use these functions together that would be very helpful.

回答1:

Does wait_event_interruptible continuously poll, or does it only recheck the condition when wake_up_all is called? This explanation is a little unclear.

The whole point of a scheduler is to avoid polling in cases like this. What happens is precisely described in what you quoted : The condition is only rechecked on wake_up, ie for example if a given task is waiting for data to be produced :

  • consumer check if data is available

  • if not (ie condition false) it goes to sleep and is added to a wait queue

  • retry when waked up

While on the producer side

  • Once data is produced, set some flag, or add something to a list so that the condition evaluated by the consumer becomes true

  • call wake_up or wake_up all on a waitqueue