• Aucun résultat trouvé

Les diérentes gardes

4.2 Syntaxe et sémantique du langage

4.2.6 Les diérentes gardes

?coucou -> !go :4(G1[1..5]) ;

}

Group G1

{

size = 50 ;

daemon = Adv8 ;

}

Fig. 4.13 Envoi d'un entier attaché à un message

Dans cet exemple, l'automate Adv8 envoie le message go aux 5 premières machines

du tableau des machines du groupe G1 en attachant à ce message la valeur entière 4.

4.2.6 Les diérentes gardes

Les gardes sont des conjonctions d'entités à valeur booléenne. La conjonction d'entités

est réalisée avec les signes && . Diérentes entités pouvant constituer une garde ont

été dénies.

Réception d'un message

La réception d'un message se fait à l'aide du caractère ? . La réception d'un message

est ponctuel. Ce qui implique que lors d'une réception, les gardes sont testées et si l'une

d'entre elles est valide, alors les actions correspondantes sont exécutées. A la n de ces

exécutions, toutes les gardes dépendantes de la réception de ce message ne sont plus

valides (elles seront potentiellement valides lors d'une prochaine réception de ce message).

La gure 4.14 présente un exemple de réception du message coucou .

Dans cet exemple, lorsque la machine Comp1 reçoit le message coucou , elle fait

crasher le processus qu'elle était en train d'exécuter (ici le programme test ). Le

Daemon crasheur

{

?coucou -> halt ;

}

Computer Comp1

{

program = "test" ;

daemon = crasheur ;

}

Fig. 4.14 Exemple de réception d'un message

message reçu peut contenir une valeur entière (cela dépend de l'envoi, voir la section 4.2.5),

l'automate peut alors la stocker dans une variable grâce au caractère : placé après le

nom du message, suivi de la variable à laquelle la valeur sera aectée.

La gure 4.15 présente un exemple de réception du message coucou avec aectation

de la valeur qui lui est attachée à la variable count .

Daemon crasheur

{ int count = 0 ;

?coucou :count -> halt ; }

Computer Comp1

{ program = "test" ;

daemon = crasheur ; }

Fig. 4.15 Exemple d'aectation d'une valeur reçue

Dans cet exemple, lors de la réception du message coucou , la valeur entière attachée

est aectée à la variable count ; cette variable peut alors être utilisée dans les actions

ou même dans la garde où il y a eu réception du message. La gure 4.16 illustre l'utilisation

de cette variable.

Dans cet exemple, lors de la réception du message coucou , la valeur attachée est

aectée à la variable count , puis un test d'égalité est eectué et suivant la valeur de

Daemon crasheur

{ int count = 0 ;

?coucou :count && count == 3 -> halt ; }

Computer Comp1

{ program = "test" ;

daemon = crasheur ; }

Fig. 4.16 Exemple d'utilisation d'une valeur reçue

count , la commande halt est eectuée ou pas.

Test d'une variable

Une garde peut être un test d'égalité, d'inégalité ou de diérence d'une variable par

rapport à une valeur. La gure 4.17 présente ces diérents tests.

Daemon test

{ int test = 0 ;

?incr && test<>19 -> test = test + 1 ; // dierence

?incr && test==19 -> halt ; // egalite }

Fig. 4.17 Exemple de test d'une variable

Dans cet exemple, l'automate test fait crasher le processus lorsqu'il reçoit 20

messages incr .

Remarque 1 IMPORTANTE : les gardes doivent être vraies à des instants ponctuels.

C'est pour cela que FAIL dénit des types d'entités et des restrictions sur les gardes

(voir la section 4.2.11).

Remarque 2 : pour les inégalités, les signes utilisés sont les signes suivants : <

pour l'inférieur stricte, > pour le supérieur stricte, <= pour l'inférieur ou

égal et >= pour le supérieur ou égal.

Test d'un minuteur

Une garde peut être un test sur un minuteur. La gure 4.18 présente un exemple

montrant la déclaration d'un minuteur et l'utilisation de celui-ci dans une garde.

Daemon test

{ // Declaration du minuteur.

time_g timer = 20 ;

timer -> halt ; }

Fig. 4.18 Exemple de test d'un minuteur

Dans cet exemple, un minuteur de 20 secondes est déclaré. Lors de l'expiration de ce

minuteur au bout de 20 secondes d'exécution de l'application testée, l'automate

inter-rompt dénitivement cette application.

Il existe deux types de minuteurs :

les minuteurs globaux déclarés grâce au mot clé time_g,

et les minuteurs locaux déclarés grâce au mot clé time_l.

Un minuteur global a pour unité de temps la seconde et un minuteur local a pour unité de

temps la milliseconde. Dans un scénario, les deux types de minuteur peuvent être utilisés

selon la précision nécessaire en utilisant la déclaration correspondante.

Test sur appel de fonction

Une garde peut être un test sur un appel d'une fonction du programme sous test.

La gure 4.19 présente un exemple montrant la déclaration d'une fonction à tester et

l'utilisation de cette fonction dans une garde.

// Declaration de la fonction "calcul" a espionner.

spyfunc calcul ;

Daemon test

{ before(calcul) -> halt ; }

Fig. 4.19 Exemple de test sur appel de fonction

Dans cet exemple, lorsque le programme testé fait appel à la fonction calcul ,

l'automate le fait crasher avant qu'il n'exécute cette fonction.

Une garde peut être un test sur l'arrivée du programme testé à une ligne particulière

du code source. L'exemple de la gure 4.20 nous montre la déclaration d'un lien vers une

ligne particulière d'un chier source du programme à tester et l'utilisation de ce lien dans

une garde.

Daemon test

{ ln ligne_test = toto.c :25 ; // Declaration d'un lien vers

// la ligne 25 du chier toto.c

ligne_test -> halt ; } // Utilisation du lien dans une garde

Computer Comp1

{ program = "client -i console" ;

daemon = test ; }

Fig. 4.20 Exemple de point d'arrêt sur une ligne du code source

Dans cet exemple, lorsque le programme client -i console exécuté sur la machine

Comp1 arrive à la ligne 25 du chier toto.c, il s'interrompt dénitivement (il crashe).

Les informations de débogage sont, dans ce cas, utilisées pour repérer les fonctions ou les

lignes de code particulières.