LE PROTOCOLE DE SYNCHRONISATION
Des tâches au temps
L’élaboration du temps dans NJN est intimement liée aux problèmes de propagation des données à travers la structure hiérarchique dynamique de l’application. La première section extrait du modèle structurel d’NJN les éléments qui participent à la structure de l’exécutif. LE PROTOCOLE DE SYNCHRONISATION 60 – Chapitre 3 1.1 Du modèle structurel au modèle d’exécution L’exécutif d’une application NJN se résume essentiellement à des tâches et aux signaux qui les interconnectent, nous avons déjà parlé de ce point brièvement. Les tâches proviennent des éléments structurels de même nom (RTTask, VTTask, ClockBox et DecouplingBox) et les signaux sont les objets qui supportent l’information véhiculée par les variables. De la structure hiérarchique d’origine, c’est-à-dire des composants, subsistent cependant quelques traces dans l’exécutif, des traces liées aux facultés de reconfigurabilité dynamique d’NJN. La structure de l’application peut en effet évoluer au cours de l’exécution si bien que les connexions entre variables ne sont pas établies de façon statique. Il est par conséquent difficile de réduire le chemin matérialisé par un ensemble de variables connectées entre elles à un seul objet en faisant disparaitre tout aspect structurel au niveau de l’exécutif. Les variables et les ports de communication d’une part et les connexions d’autre part, laissent donc leur empreinte dans le modèle exécutif : chaque variable se traduit par l’existence d’un signal au niveau de l’exécutif ; chaque connecteur associant deux variables fait apparaitre dans l’exécutif une tâche particulière appelée répéteur qui a pour fonction de faire transiter l’information entre les deux signaux correspondants. Voyons par exemple l’application représentée figure 26. Cinq tâches sont hébergées au sein d’une structure hiérarchique de six composants. Les tâches sont reliées entre elles à travers un réseau de douze variables dont certaines sont des ports d’entrée ou de sortie. La connexion entre T1 et T3 par exemple nécessite quatre variables dont l’une est un port de sortie et deux sont des ports d’entrées. Trois connecteurs assemblent ces variables. Figure 26. Une application NJN simple. La figure 27 montre l’exécutif correspondant à l’application de la figure 26. La hiérarchie de composants a disparu. Les quatre variables associant entre elles les tâches T1 et T3 ont fait apparaitre quatre signaux reliés par des répéteurs. Le protocole de synchronisation – 61 Figure 27. Exécutif correspondant à l’architecture de la figure 26. Lorsque l’exécutif est distribué, les tâches de l’application, répéteurs compris, sont réparties sur différents processus logiques (figure 28). La structure hiérarchique d’origine joue ici un rôle important : l’élément distribuable dans NJN est en effet le composant. Il en résulte que les chemins de données sont interrompus au niveau des ports des composants distribués. Du point de vue de l’exécutif, c’est aux abords des répéteurs que la distribution va avoir lieu. Le répéteur reste accroché à son signal source. Les données transmises sont adressées au signal cible sous la forme de messages par l’intermédiaire d’un service distant. Ce type de service permet à un processus logique d’émettre des messages ou des requêtes à destination d’un autre processus logique. Une file de messages est associée au service côté émetteur et côté récepteur de manière à assurer la synchronisation des deux processus. Figure 28. Distribution de l’application de la figure 26 dans deux processus logiques distincts. La figure 28 montre le résultat de la distribution de notre application sur deux processus logiques. Les composants C1, C2 et C5 ont été placés dans le processus logique LP1 tandis que le composant Top et par conséquent les composants C3 et C4 ont été placés dans le processus logique LP2. La connexion entre les tâches T1 et T3 s’en trouve affectée. La cible du premier répéteur est en effet distante. C’est donc à travers un service distant que l’information transitera vers le signal cible. Notre exemple montre bien les différents éléments que le modèle d’exécution doit gérer. Le moteur d’NJN devra assurer l’ordonnancement des tâches et des 62 – Chapitre 3 répéteurs mais également assurer l’envoi et l’exécution de requêtes de services distants. Un élément manque à notre modèle d’exécution, élément nécessaire dans des classes d’applications particulières. Certaines applications séparent en effet l’acheminement de l’information de la synchronisation des opérations. Elles utilisent des signaux spécifiques pour déclencher les différentes tâches de l’application indépendamment des signaux de données. Ces signaux sont appelés horloges et sont placés dans la liste de sensibilité des tâches concernées. Des opérations sur ces horloges peuvent être nécessaires : classiquement multiplication ou division de leur fréquence, fusion entre deux horloges, etc. Afin d’implémenter ces opérations particulières, NJN définit une classe de tâches spécifiques, les boites d’horloges, dont le comportement temporel est à rapprocher des répéteurs. On notera cependant deux différences entre les boites d’horloges et les répéteurs : premièrement, les boites d’horloges sont définies par le programmeur ; deuxièmement, elles peuvent être déclenchées par plusieurs signaux.
Les problèmes de propagation, de convergence et de causalité : deux cas tordus
Dans NJN, les processus logiques ont pour rôle de supporter la distribution de l’application sur plusieurs cibles matérielles ou d’isoler des sections critiques de code dans des processus. On peut considérer en première approche que chaque processus logique est hébergé par un processeur différent ce qui place le problème de son ordonnancement au second plan. En pratique, le système d’exploitation hôte se chargera de cet aspect de l’exécutif selon des principes d’ordonnancement classiques. Notre problème se situe plutôt au sein même d’un processus logique : gérer l’ordonnancement de l’ensemble des tâches hébergées par un processus. Comme l’a montré la section précédente, l’exécutif est constitué de tâches et de signaux. On appelle évènement d’exécution l’objet rattaché à l’exécution d’une tâche par le processus logique à une date donnée. Cette tâche, si elle effectue des opérations d’écritures, produit des évènements d’écriture sur les signaux de l’exécutif. Les évènements sont datés de manière à garantir les propriétés causales de l’exécution, la règle de causalité étant la suivante : un évènement d’exécution ne peut produire des évènements d’écriture qu’à des dates qui lui sont strictement postérieures. Comme nous l’avons vu, afin de gérer convenablement les chaines de causalité, NJN utilise la notion de cycle Δ [58]1 . Il s’agit d’une durée strictement nulle qui établit un ordre partiel des évènements de l’application. Un évènement traité au premier Δ d’une date donnée est antérieur à un évènement exécuté au second Δ de cette même date, etc. L’écart temporel entre l’exécution d’une tâche et ses écritures est arbitrairement fixée à un cycle Δ. Autrement dit, sauf mention explicite contraire au moment de l’écriture, les messages sont postérieurs d’un cycle Δ aux évènements qui les ont produits.
De la définition du temps
NJN définit trois dates courantes : une date de lecture tR, une date d’exécution tE et une date d’écriture tW. La date d’exécution correspond à la date de l’évènement en cours de traitement. La date de lecture est antérieure ou égale à la date d’exécution. En pratique, ces deux dates sont le plus souvent égales. La date d’écriture quant à elle est strictement postérieure aux deux autres. La relation cidessous est donc vérifiée à chaque instant : t Rt Et W Lorsqu’un évènement est traité, l’état observable du système est celui défini à la date de lecture. Il est éventuellement possible de connaitre l’état qu’avait un signal à une date antérieure. En revanche, aucune lecture à une date postérieure n’est possible. De façon analogue, les écritures sur les signaux de l’application sont effectuées à la date d’écriture. Il est éventuellement possible de retarder une écriture en précisant un délai explicite. Mais toute tentative d’écriture à une date antérieure est prohibée1 . Une tâche est composée de deux éléments : un corps qui renferme le code exécutable de la tâche et des conditions d’activation. Les conditions d’activation peuvent être de nature temporelle. On peut par exemple vouloir qu’une tâche soit exécutée à intervalles de temps réguliers (timeslot) ou au bout d’un certain temps d’inactivité (timeout). Les conditions d’activation peuvent également prendre la forme d’une liste de sensibilité qui énonce l’ensemble des signaux du système qu’il faut surveiller. L’exécution du corps de la tâche sera alors programmé chaque fois qu’une modification affectera l’un des signaux de la liste. Les règles d’exécution des tâches sont les suivantes : lorsque les conditions d’activation d’une tâche sont remplies, un évènement d’exécution est programmé. 1 Nous verrons un peu plus loin qu’il existe une exception avec les boites de découplage. Le protocole de synchronisation – 65 La date associée à cet évènement dépend de la nature des conditions d’activation. S’il s’agit d’un déclenchement temporel, la datation de l’évènement est immédiate. Si le déclenchement est dû à un évènement d’écriture de l’un des signaux de la liste de sensibilité, la date d’activation correspond à la date de l’évènement d’écriture1 . Lorsque l’évènement d’exécution est traité, c’est-à-dire lorsque la tâche est exécutée, la date d’exécution tE est fixée à la date de l’évènement. Figure 31. Modèle temporelle d’NJN. Deux cycles sont définis dans NJN (figure 31) : les delta, notés Δ et les microdelta notés δ. La relation d’ordre entre deux dates (t1, Δ1, δ1) et (t2, Δ2, δ2) est définie de la façon suivante : Si t1 est égal à t2 alors la relation d’ordre est établie en comparant Δ1 et Δ2. Si ces derniers sont également identiques, c’est la relation entre δ1 et δ2 qui est examinée. L’écart temporel entre tE et tW dépend alors de la nature de la tâche. Pour une tâche classique (RTTask ou VTTask), il est d’un Δ. Pour un répéteur ou une boite d’horloges (ClockBox), il est d’un δ. Les cycles Δ ne sont incrémentés que lorsque les cycles δ ont permis de propager les données à travers le réseau de signaux. Le tableau II résume les relations temporelles entre les trois dates définies par NJN en fonction du type d’évènement traité.