rickhau
rickhau

Reputation: 283

what is the difference between simple sleeping (using wait_event_*() functions) and advanced sleeping (using prepare_to_wait() function)?

In LDD3 book, it introduces simple sleeping(wait_event*() functions) and advance sleeping(prepare_to_wait() function).

If my understanding is correct, wait_queue_t seems to be a process entry but wait_queue_head_t seems to be the wait queue to store the list of processes which (wait_queue_t) are being added to..

So, it comes my confusion that what situation I should use wait_event_*() functions versus prepare_to_wait with specifying the wait process.

The only reason I can tell is that I can specify the process state before sleeping versus the simple sleeping. However, simple sleeping does offer the interruptible and uninterruptible wait_event functions..

So, I am a bit confused why we need both two from both design and implementation points of view. Thanks.

Upvotes: 3

Views: 3058

Answers (1)

CL.
CL.

Reputation: 180080

This is the implementation of wait_event() (much simplified):

#define wait_event(wq, condition)
{
    DEFINE_WAIT(wait);
    for (;;) {
        prepare_to_wait(&wq, &wait, TASK_UNINTERRUPTIBLE);
        if (condition)
            break;
        schedule();
    }
    finish_wait(&wq, &wait);
}

If this implementation (or one of the many other wait_event_* variants) works for you, then you should just use it.

However, there might be situations where you need more control over this wait loop. For example, imagine that you want to wait for some data to be available in a buffer, and return it, and that both these operations need to be done under a lock, and that checking for the data and removing the data needs to be an atomic operation, i.e., both must be done under the same lock, with no unlock inbetween. Then you would have to modify the loop above like this:

void my_own_wait(...)
{
    DEFINE_WAIT(wait);
    spin_lock(&lock);
    while (!some_data_available()) {
        prepare_to_wait(&wq, &wait, TASK_xxx);
        spin_unlock(&lock);
        schedule();
        spin_lock(&lock);
        finish_wait(&wq, &wait);
    }
    take_data();
    spin_unlock(&lock);
}

Upvotes: 5

Related Questions