Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
L’objectif de la conception préemptible et interromptible du système d’exploitation est d’optimiser les performances du système. Tout thread peut être préempté par un thread avec une priorité plus élevée, et toute routine de service d’interruption du pilote (ISR) peut être interrompue par une routine qui s’exécute à un niveau de demande d’interruption plus élevé (IRQL).
Le composant noyau détermine quand une séquence de code s’exécute, selon l’un des critères de hiérarchisation suivants :
Schéma de priorité d’exécution défini par le noyau pour les threads.
Chaque thread du système a un attribut de priorité associé. En règle générale, la plupart des threads ont des attributs de priorité variable : ils sont toujours préemptibles et sont planifiés pour s'exécuter en mode round-robin avec tous les autres threads actuellement au même niveau de priorité. Certains threads ont des attributs de priorité en temps réel : ces threads critiques s’exécutent jusqu’à la fin, sauf s’ils sont préemptés par un thread qui a un attribut de priorité en temps réel plus élevé. L’architecture Microsoft Windows ne fournit pas de système en temps réel.
Quel que soit son attribut de priorité, tout thread du système peut être préempté lorsque des interruptions matérielles et certains types d’interruptions logicielles se produisent.
Niveau de requête d’interruption défini par le noyau (IRQL) auquel un vecteur d’interruption particulier est affecté sur une plateforme donnée.
Le noyau hiérarchise les interruptions matérielles et logicielles afin que certains codes en mode noyau, y compris la plupart des pilotes, s’exécutent à des IRQL plus élevés, ce qui lui donne une priorité de planification plus élevée que d’autres threads du système. Le runtime irQL particulier auquel un élément de code de pilote en mode noyau s’exécute est déterminé par la priorité matérielle de son appareil sous-jacent.
Le code en mode noyau est toujours interrompt : une interruption avec une valeur IRQL plus élevée peut se produire à tout moment, ce qui entraîne l’exécution immédiate d’un autre élément de code en mode noyau qui a un IRQL attribué par le système plus élevé immédiatement sur ce processeur. Toutefois, lorsqu’un élément de code s’exécute à un irQL donné, le noyau masque tous les vecteurs d’interruption avec une valeur IRQL inférieure ou égale sur le processeur.
Le niveau IRQL le plus bas est appelé PASSIVE_LEVEL. À ce niveau, aucun vecteur d’interruption n’est masqué. Les threads s’exécutent généralement à IRQL=PASSIVE_LEVEL. Les niveaux IRQL supérieurs suivants concernent les interruptions logicielles. Ces niveaux incluent APC_LEVEL, DISPATCH_LEVEL ou, pour le débogage du noyau, WAKE_LEVEL. Les interruptions de l'appareil ont des valeurs IRQL encore plus élevées. Le noyau réserve les valeurs IRQL les plus élevées pour les interruptions critiques système, telles que celles de l’horloge système ou des erreurs de bus.
Certaines routines de support du système s'exécutent à IRQL=PASSIVE_LEVEL, soit parce qu'elles sont implémentées en tant que code paginable, soit parce qu'elles accèdent à des données paginables, soit parce que certains composants en mode noyau configurent leurs propres threads.
De même, certaines routines de pilotes standard s’exécutent généralement au niveau IRQL=PASSIVE_LEVEL. Toutefois, plusieurs routines de pilotes standard s’exécutent à IRQL=DISPATCH_LEVEL ou, pour un pilote de niveau le plus bas, au niveau de l’IRQL de l’appareil (également appelé DIRQL). Pour plus d’informations sur les listes IRQL, consultez Gestion des priorités matérielles.
Chaque routine d’un pilote est interromptable. Cela inclut toutes les routines qui s’exécutent à un irQL supérieur à PASSIVE_LEVEL. Toute routine qui s’exécute à un IRQL particulier conserve le contrôle du processeur uniquement si aucune interruption pour un IRQL supérieur se produit pendant l’exécution de cette routine.
Contrairement aux pilotes dans certains systèmes d’exploitation d’ordinateurs personnels plus anciens, l’ISR d’un pilote Microsoft Windows n’est jamais une routine volumineuse et complexe qui effectue la plupart du traitement des E/S du pilote. Cela est dû au fait que toute routine de service d’interruption du pilote (ISR) peut être interrompue par une autre routine (par exemple, par l’ISR d’un autre pilote) qui s’exécute à un irQL supérieur. Ainsi, l'ISR du pilote ne conserve pas nécessairement un contrôle continu du processeur du début à la fin de son chemin d'exécution.
Dans les pilotes Windows, un ISR enregistre généralement les informations d’état matériel, met en file d’attente un appel de procédure différée (DPC), puis se ferme rapidement. Plus tard, le système retire de la file d’attente le DPC du pilote afin que le pilote puisse effectuer des opérations d’E/S à un IRQL inférieur (DISPATCH_LEVEL). Pour obtenir de bonnes performances système globales, toutes les routines qui s’exécutent à des IRQL élevés doivent libérer rapidement le contrôle de l’unité centrale.
Dans Windows, tous les threads ont un contexte de thread. Ce contexte se compose d’informations qui identifient le processus propriétaire du thread, ainsi que d’autres caractéristiques telles que les droits d’accès du thread.
En général, seul un pilote de niveau supérieur est appelé dans le contexte du thread qui demande l’opération d’E/S actuelle du pilote. Un pilote de niveau intermédiaire ou de niveau le plus bas ne peut jamais supposer qu’il s’exécute dans le contexte du thread qui a demandé son opération d’E/S actuelle.
Par conséquent, les routines de pilote s’exécutent généralement dans un contexte de thread arbitraire , le contexte de tout thread actuel lorsqu’une routine de pilote standard est appelée. Pour des raisons de performances (pour éviter les commutateurs de contexte), très peu de pilotes configurent leurs propres threads.