Any device driver does not start independently; the device driver starts on behalf of the process through system calls.
Suppose that any device driver calls down_interruptible();
, this means that if the semaphore is unavailable, the corresponding process will be placed on the semaphore waiting queue. And the state of the task will be changed to TASK_INTERRUPTIBLE
, and the scheduler is called to start any other process. Now the sleep process can be awakened either by an event for its expectation (semaphore), or by a signal.
Example: kill -SIGINT <pid>
will cause the process to change its state to TASK_RUNNING
and add a process to start the queue.
Here it is the pseudo code of the wait queue, as the process is waiting for an event.
/* ‘q’ is the wait queue we wish to sleep on */
DEFINE_WAIT(wait);
add_wait_queue(q, &wait);
while (!condition) /* condition is the event that we are waiting for */
{
prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);
if (!signal_pending(current))
{
schedule();
continue;
}
ret = -ERESTARTSYS;
}
finish_wait(&q, &wait);
, . , , -ERESTARTSYS
, .