The relationship between Linux poll and waiting queue hibernation __linux

Source: Internet
Author: User

Description: Linux version 2.6.37.1

Combined with the summary of relevant data and summarized, to make a record, the wrong place please correct, thank you.


1.poll mechanism and wait queue

The application layer enters the kernel through the system call poll function, and the kernel executes the corresponding Sys_poll function. Call the Do_sys_poll function in the Sys_poll function. Do_sys_poll function by calling the Poll_initwait

Function initializes the Poll_wqueues variable table and assigns the __POLLWAIT function to the table. The __pollwait function here will be executed by calling the Poll_wait function in the driven poll method.

When the poll_initwait function is done, the Do_sys_poll function calls the Do_poll function.

There is a for Dead loop in the Do_poll function, the exit condition is count or timeout is Non-zero.

Count is not 0 identifies the mask returned by the DO_POLLFD function as true, and the timeout indicates a timed time.

The poll method in the drive is invoked by mask = File->f_op->poll in the DO_POLLFD function, and the poll value after the operation mask in the drive is obtained.

In the For Dead loop, the entire poll_list is polled first. Find out if there are any operations that have met the conditions in all pending poll operations, then jump out of the loop

No, continue down execution.


The wake operation in the figure above is implemented by invoking the WAKE_UP function in the driver. The example on the LDD3 is not complete,

You can learn how to drive poll using other blogs.

Summarize the mechanism of poll:

1.poll->sys_poll->do_sys_poll->poll_initwait

void poll_initwait (struct poll_wqueues *pwq)
{
Init_poll_funcptr (&pwq->pt, __pollwait);
Pwq->polling_task = current;
pwq->triggered = 0;
Pwq->error = 0;
pwq->table = NULL;
Pwq->inline_index = 0;
}

Attention should be paid here to Init_poll_funcptr (&pwq->pt, __pollwait)

Assign a function __pollwait function to a function pointer in the pooll_table structure that &pwq->pt points to.

The secondary function is called by calling the Poll_wait function in a later drive.

static inline void poll_wait (struct file * Filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (P && wait_address)
P->qproc (Filp, wait_address, p);
}

Here the P->qproc operation is pointing to the __pollwait function

2.do_sys_poll->do_polll

static int do_poll (unsigned int nfds, struct poll_list *list,
struct poll_wqueues *wait, struct timespec *end_time)
{

for (;;) {

DO_POLLFD (PFD, PT)

if (count | | timed_out)
Break

Poll_schedule_timeout (Wait, task_interruptible, to, Slack)

}
}

After the poll_initwait function is initialized, the Do_sys_poll function invokes the Do_poll function.

First call the DO_POLLFD (PFD, PT) function in the Do_poll function

static inline unsigned int do_pollfd (struct POLLFD *pollfd, poll_table *pwait)
{
Mask = file->f_op->poll (file, pwait);
}

The poll method in the drive is invoked by File->f_op->poll, and the poll method in the drive invokes the Poll_wait function

poll_wait function calls the __pollwait function registered by the POLL_INITWAIT function

static void __pollwait (struct file *filp, wait_queue_head_t *wait_address,
Poll_table *p)
{
struct Poll_wqueues *pwq = container_of (p, struct poll_wqueues, PT);
struct Poll_table_entry *entry = poll_get_entry (PWQ);
if (!entry)
Return
Get_file (FILP);
Entry->filp = FILP;
entry->wait_address = wait_address;
Entry->key = p->key;
Init_waitqueue_func_entry (&entry->wait, Pollwake);
Entry->wait.private = Pwq;
Add_wait_queue (wait_address, &entry->wait);
}

You can see that this function completes the task of adding queues.

Then proceed down to execute poll_schedule_timeout ()

After this function is executed, the process enters hibernation until it is wake_up or dormant.


So summarize the poll operation: First call the poll function to register the __POLLWAIT function into the system, and then pass F_ops->poll

Call the driven poll method, poll->poll_wait to invoke the previously registered __pollwait function,

Add a wait queue in the __pollwait function and call the Poll_schedule_timeout () function

Hibernate it, waiting for other threads to wake up. So using polll and using a wait queue for simple hibernation is as needed elsewhere

wake_up function to notify


3. Waiting for the queue to hibernate

Driver call Wait_event can put functions into hibernation, look at the specific operation
#define Wait_event (Wq, condition) \
do {\
if (condition) \
Break \
__wait_event (Wq, condition); \

} while (0)


#define __wait_event (Wq, condition) \
do {\
Define_wait (__wait); \
\
for (;;) {                            \
Prepare_to_wait (&wq, &__wait, task_uninterruptible); \
if (condition) \
Break \
Schedule (); \
}                                \
Finish_wait (&wq, &__wait); \
} while (0)

Through the __wait_event for (;;) After the loop, the queue enters hibernation. Wait for wake_up after hibernation



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.