• Aucun résultat trouvé

Raffinement simple des communications et prise en compte de leur coût

5.3 Génération de composants de communication adaptés

5.3.2 Raffinement simple des communications et prise en compte de leur coût

Pour prendre en compte le coût des communications, nous procédons à un raffinement du mod- èle initial afin d’intégrer les composants de communication introduits dans la section précédente. Nous illustrons ce raffinement à l’aide de la notation graphique d’AADL décrite par la figure 5.10.

thread process subprogram

parameter queueing port

access to shared data data

system

FIGURE5.10 – Notation graphique d’AADL

La figure 5.11 est un modèle AADL défini par l’utilisateur qui décrit une communication asyn- chrone entre la tâche émettrice T _Sender et la tâche réceptrice T _Receiver. T _Sender exécute une fonction métier Compute_Data, implémentée par l’utilisateur, et envoie la valeur de retour au port datain de T _Receiver. Ici le port datain représente une file de messages.

Compute_Data Decode_Data

Thread T_Sender Thread T_Receiver

dataout datain

FIGURE 5.11 – Modèle initial défini par l’utilisateur : communication asynchrone entre deux

tâches

Le raffinement de ce modèle consiste à introduire les composants de communication précé- dents. La figure 5.12 correspond au modèle AADL raffiné. La connexion entre ports est rem- placée à un accès à une variable partagée T _Receiver_datain qui représente le port datain de la tâche T _Receiver. Le type de T _Receiver_datain est dépendant de l’implémentation choisie (e.g. tableau, liste chaînée). Le composant T _Receiver_datain est annoté de façon à préciser la structure utilisée. Des appels aux composants Put_Value et Send_Out put sont ajoutés à la tâche émettrice T _Sender. Put_Value prend en entrée la donnée produite par Compute_Data et l’insère dans la file T _Receiver_datain. Une fois toutes les insertions réalisées (ici une seule), l’appel à Send_Out put met à disposition du destinataire les messages ajoutés. Les composants Next_Value et Receive_Input réalisent les opérations inverses et sont ajoutées à la tâche T _Receiver.

Compute_Data Thread T_Sender T_Re cei ver_d atain Put_Value Send_Output Thread T_Receiver Receive_Input Next_Value Decode_Data

5.3. GÉNÉRATION DE COMPOSANTS DE COMMUNICATION ADAPTÉS 73

Le raffinement réalisé dans cet exemple va potentiellement varier selon l’implémentation. Par exemple, l’implémentation de Send_Output peut prendre en paramètre une unique file de message ou une liste de files de messages. Lorsque la tâche émettrice écrit sur plusieurs ports, il faut réaliser dans le premier cas plusieurs appels à ce composant alors qu’un seul est nécessaire dans le second cas. La variabilité du processus de raffinement n’est donc pas seulement le choix de la version des composants à utiliser, mais également le nombre d’appels, ou encore le nombre et le type des paramètres d’entrée/sortie. En effet, les composants standard de communication AADL sont partiellement définis et ne précisent pas par exemple la modélisation des files de messages ou la prise en compte de paramètres supplémentaires nécessaires aux opérations réalisées par ces composants.

Cette variabilité a été illustré sur l’implémentation des communications différées pour répondre à l’adaptabilité du code généré. Des implémentations alternatives ont été introduites en section 4.3. Pour évaluer le coût de chacune, le processus de raffinement explicite les ressources mises en œu- vre (e.g. données, composants intergiciels). Ainsi, l’une ou l’autre des alternatives est sélectionnée selon les ressource mises en œuvre et les propriétés du système. Pour cela, on doit disposer pour chaque alternative d’un processus de raffinement ainsi qu’un ensemble de composants intergiciels. La section suivante présente plus en détails ces composants.

5.3.3 Raffinement détaillé des communications

Dans le chapitre précédent, nous avons illustré trois implémentations différentes des fonctions de communication différée : sans verrou avec indices calculés à l’exécution (PDC_Indices), sans verrou avec indices pré-calculés et stockés dans des tableaux (PDC_Indices_Array), ou bien in- sertion triée dans une liste chaînée protégée par un verrou (PDC_Insertion_Sort). On décrit cha- cun de ces modèles à l’aide d’un ensemble de composants AADL de type subprogram qui sont décrit à l’aide par exemple de l’annexe comportementale d’AADL, comme illustré par les list- ings 5.11, 5.12 et 5.13.

Le premier listing décrit l’implémentation du composant Put_Value avec le calcul d’indice à l’exécution. Les éléments déclarés dans la section features sont les paramètres d’entrée/sortie de la fonction Put_Value. Pour le calcul d’indice, la fonction a besoin notamment des propriétés temporelles de l’ensemble du jeu de tâche et de l’identifiant de la tâche courante. Ces paramètres correspondent aux features context et taskID. L’implémentation du service est spécifiée à l’aide de l’annexe comportementale (section behavior_specification). Le service exécute en premier la fonction Compute_CDW (CDW : Current Deadline Write) qui réalise le calcul d’indice d’écriture. L’indice calculé est retourné dans la variable CDWIndex déclarée dans l’annexe comportementale. Ensuite, la donnée value est écrite à l’emplacement CDWIndex du tableau buffer modélisant la file de message du consommateur. Le type de la donnée value est dépendant de l’architecture modélisée. Il n’est donc pas connu statiquement. On le déclare alors dans la section prototypes (t_value) pour indiquer qu’il devra être précisé lorsque le composant Put_Value sera intégré à l’architecture. 1 subprogram P u t _ V a l u e 2 p r o t o t y p e s 3 t _ v a l u e : data ; 4 t _ c o n t e x t : data ; 5 f e a t u r e s

6 t a s k I D : i n parameter Base_Types : : I n t e g e r _ 1 6 ; 7 c o n t e x t : r e q u i r e s data a c c e s s t _ c o n t e x t ; 8 I t e r a t i o n C o u n t e r : i n parameter Base_Types : : I n t e g e r _ 1 6 ; 9 v a l u e : i n parameter t _ v a l u e ; 10 b u f f e r : r e q u i r e s data a c c e s s ArrayDataType { A c c e s s _ R i g h t => w r i t e _ o n l y ; } ; 11 annex b e h a v i o r _ s p e c i f i c a t i o n {∗∗ 12 s t a t e s s : i n i t i a l f i n a l s t a t e ; 13 v a r i a b l e s CDWIndex : Base_Types : : I n t e g e r _ 1 6 ; 14 t r a n s i t i o n s 15 t : s −[]−> s { 16 −− CDWIndex : o u t p a r a m e t e r 17 Compute_CDW ! ( t a s k I D , I t e r a t i o n C o u n t e r , c o n t e x t , CDWIndex ) ; 18 b u f f e r [ CDWIndex ] : = v a l u e 19 } ; 20 ∗ ∗ } ; 21 end P u t _ V a l u e ;

Listing 5.11 – Composant Put_Value selon l’implémentation PDC_Indices

Le listing 5.12 décrit Put_Value pour la seconde implémentation (modèle PDC_Indices_Array). Ici, les indices sont calculés hors-ligne et stockés dans un tableau CDW . La fonction écrit alors à l’indice CDW [IterationCounter] du tableau bu f f er, IterationCounter étant le compteur de péri- odes de la tâche courante. Par rapport à la première version, cette deuxième version du composant Put_Valueutilise des paramètres différents notamment le tableau CDW stockant les indices.

1 subprogram P u t _ V a l u e 2 p r o t o t y p e s 3 t _ v a l u e : data ; 4 f e a t u r e s 5 I t e r a t i o n C o u n t e r : i n parameter Base_Types : : I n t e g e r _ 1 6 ; 6 CDW: i n parameter ArrayDataType ; 7 v a l u e : i n parameter t _ v a l u e ; 8 b u f f e r : r e q u i r e s data a c c e s s ArrayDataType { A c c e s s _ R i g h t => w r i t e _ o n l y ; } ; 9 annex b e h a v i o r _ s p e c i f i c a t i o n {∗∗ 10 s t a t e s s : i n i t i a l f i n a l s t a t e ; 11 t r a n s i t i o n s 12 t : s −[]−> s { 13 b u f f e r [CDW[ I t e r a t i o n C o u n t e r ] ] : = v a l u e 14 } ; 15 ∗ ∗ } ; 16 end P u t _ V a l u e ;

Listing 5.12 – Composant Put_Value selon l’implémentation PDC_Indices_Array

Le listing 5.13 fournit la description du composant Put_Value pour la troisième implémentation (modèle PDC_InsertionSort). Ce composant réalise une insertion triée sur le port, modélisé par une liste chaînée et protégé par un verrou à l’aide des fonctions Get et Release. Ces dernières doivent être fournis au composant pour qu’il s’adapte aux différentes plates-formes et mécanismes d’exclusion mutuelle (e.g. Mutex POSIX, Semaphores ARINC653). Par conséquent, les fonctions Get et Release sont déclarées dans la section prototypes. L’annexe comportementale décrit cette troisième implémentation : l’appel à la fonction findNextLink détermine à quel maillon doit être rattaché le maillon à insérer, les maillons étant ordonnés par date (paramètre currentDeadline) et par priorité (paramètre uniqueIndex) en cas de dates égales. Par conséquent, ces paramètres supplémentaires currentDeadline et uniqueIndex sont rajoutés dans la section features. Ensuite,

5.3. GÉNÉRATION DE COMPOSANTS DE COMMUNICATION ADAPTÉS 75

la fonction findFreeLink trouve un maillon libre de la liste chaînée. Ce dernier est réutilisé. Il est initialisé avec la donnée et connecté au maillon précédent.

1 subprogram P u t _ V a l u e 2 p r o t o t y p e s 3 t _ v a l u e : data ; 4 Get : subprogram G e t _ R e s o u r c e ; 5 R e l e a s e : subprogram R e l e a s e _ R e s o u r c e ; 6 f e a t u r e s 7 v a l u e : i n parameter t _ v a l u e ; 8 c u r r e n t D e a d l i n e : i n parameter Base_Types : : I n t e g e r ; 9 u n i q u e I n d e x : i n parameter Base_Types : : I n t e g e r ; 10 b u f f e r : r e q u i r e s data a c c e s s L i n k e d L i s t { A c c e s s _ R i g h t => w r i t e _ o n l y ; } ; 11 annex b e h a v i o r _ s p e c i f i c a t i o n {∗∗ 12 s t a t e s 13 s : i n i t i a l f i n a l s t a t e ; 14 v a r i a b l e s 15 f r e e L i n k : L i n k e d L i s t L i n k ; 16 n e x t L i n k : L i n k e d L i s t L i n k ; 17 t r a n s i t i o n s 18 t : s −[]−> s { 19 Get ! ( b u f f e r ) ; 20 f i n d N e x t L i n k ! ( b u f f e r , c u r r e n t D e a d l i n e , u n i q u e I n d e x , n e x t L i n k ) ; 21 f i n d F r e e L i n k ! ( b u f f e r , f r e e L i n k ) ; 22 i f ( f r e e L i n k . IS_AVAILABLE ) { 23 f r e e L i n k . v a l u e : = v a l u e ; 24 f r e e L i n k . t i m e s t a m p : = c u r r e n t D e a d l i n e ; 25 f r e e L i n k . u n i q u e I n d e x : = u n i q u e I n d e x ; 26 moveLink ! ( f r e e L i n k , n e x t L i n k ) 27 } ; 28 Rel ! ( b u f f e r ) 29 } ; 30 ∗ ∗ } ; 31 end P u t _ V a l u e ;

Listing 5.13 – Composant Put_Value selon l’implémentation PDC_InsertionSort

La modélisation des composants intergiciels rend possible leur analyse et l’évaluation de leur impact sur les performances du système.

– Empreinte mémoire L’ajout de paramètres spécifiques à chaque implémentation nécessite des données supplémentaires. Par exemple, l’implémentation PDC_Indices_Array requiert des tableaux stockant les indices d’écriture pour chaque tâche. Ces données sont introduites dans le modèle raffiné et correspondent à des composants data dont les propriétés précisent leur type et leur taille. On évalue alors l’empreinte mémoire du modèle raffiné en parcourant les composants datadu modèle raffiné.

– Surcoût en temps d’exécution L’introduction des composants intergiciels au sein de la de- scription des tâches (composants thread) nécessite une réévaluation du pire temps d’exécution (WCET) ce ces dernières. En considérant qu’une première évaluation du WCET est connue et annoté à chaque tâche, il faut y ajouter le WCET des composants intergiciels introduits lors du raffinement. En disposant de leur description comportementale qui détaille précisément leur im- plémentation, celle-ci est traduite en graphe d’exécution à partir duquel le WCET du composant peut être calculé. Cette valeur est ensuite ajoutée au précédent WCET de la tâche courante.

Le choix de l’implémentation adaptée à l’architecture est ainsi rendu possible grâce à l’intro- duction des composants intergiciels dans le processus de raffinement. De plus, l’évaluation du coût à partir du modèle raffiné assure une démarche de validation cohérente puisque ce dernier est di- rectement traduit en code exécutable à l’aide d’un pretty-printer. Ce processus de raffinement sera détaillé en section 7.2. Dans la prochaine section nous détaillons l’implémentation sans verrou (PDC_Indices, PDC_Indices_Array) avec notamment les calculs d’indices.