J'ai un pilote qui veut envoyer une notification à l'utilisateur à propos d'un changement de statut. Dans l'implémentation actuelle, il utilise le système de fichiers proc pour ce faire. Le processus de lecture tourne autour d'un read()
vers le système de fichiers proc. Le read()
bloque avec wait_event_interruptible()
jusqu'à ce que le noyau reçoive une interruption qui amène la fonction write_new_data()
à call wake_up_interruptible()
. Voici le code de base (supprimé tout encombrement inutile):condition de course entre wait_event et wake_up
static int flag=0;
DECLARE_WAIT_QUEUE_HEAD(info_wq);
//user process call read() on /proc/myfile to get to this function
int my_proc_read (struct file *filp, char *buf, size_t count, loff_t *pos)
{
wait_event_interruptible(info_wq, flag != 0);
flag = 0;
//copy buffers to user
return 0;
}
//when an interrupt comes it schedules this function on the systems' work queue
void write_new_data()
{
//fill buffer with data
flag = 1;
wake_up_interruptible(&info_wq);
}
Considérons maintenant le flux suivant:
- processus utilisateur appelle
read()
, puis attend. L'interruption se produit ->write_new_data()
est appelée. écrit des données et appellewake_up_interruptible()
. read()
read()
est réveillé, lit les données mais le processus n'a pas réexécuté la lecture (n'était pas planifié pour exécuter, n'a pas obtenu à cause de l'interruption suivante ...).- interruption se produit ->
write_new_data()
est déclenchée à nouveau, appellewake_up_interruptible()
mais pas de fil d'attente est en attente ... - appels processus de lecture et les blocs.
Remarque: tout cela se produit sur un système monoprocesseur. En outre, il n'y a qu'un seul thread de lecture et un thread écrit de nouvelles données.
Comment puis-je éviter de manquer la seconde interruption? (Une solution consiste à utiliser les sockets netlink, mais je me demandais s'il y a un moyen de le faire dans la terre/proc)
quel type de pilote est-ce? et quel est le statut? –