Aller au contenu

Opérations bloquantes

Opérations d’entrées/sorties bloquantes

Quand une opération de lecture ou d’écriture doit attendre sur des données ou sur la disponibilité du périphérique, le pilote doit bloquer le thread jusqu’à ce que les données soient disponibles. Ceci peut être réalisé en le mettant en sommeil jusqu’à ce que la requête puisse être satisfaite à l’aide de waitqueues.

Déclaration de la waitqueue (<linux/wait.h>, <linux/sched.h>) et d’un fanion de signalisation

wait_queue_head_t my_queue;
int request_can_be_processed = 0;

Initialisation de la waitqueue avec la macro init_waitqueue_head

init_waitqueue_head (&my_queue);

Attendre jusqu’à ce que l’opération puisse être satisfaite (read/write) avec la macro wait_event_interruptible

wait_event_interruptible(&my_queue, request_can_be_processed != 0);

Lorsque les ressources sont disponibles, le pilote peut réveiller le thread et lui signaler que la requête peut finalement être traitée avec la macro wake_up_interruptible

request_can_be_processed = 1;
wake_up_interruptible(&my_queue);

L’application en espace utilisateur sera notifiée s’il utilise un des appels système pour la scrutation ( select, poll ou epoll). Ces opérations utilisent l’opération poll du pilote de périphérique dont les services sont disponibles dans l’interface <linux/poll.h>.

Cette méthode permet d’attendre sur les ressources en mode non bloquant et peut être pour des opérations de lecture comme d’écriture

static unsigned int skeleton_poll (struct file *f,
                                   poll_table *wait) {
    unsigned mask = 0;
    poll_wait (f, &my_queue, wait);
    if (request_can_be_processed != 0) {
        mask |= POLLIN | POLLRDNORM; // read operation
        // mask |= POLLOUT | POLLWRNORM; // write operation
    }
    return mask;
}