• Aucun résultat trouvé

4.2 Snapshot partiel

5.1.2 Objets de base utilisés dans la simulation

En plus des objets snapshot, les simulateurs coopèrent en utilisant des registres atomiques et des objets safe_agreement et arbiter dont les spécifications et les implémentations sont décrites dans cette section. Ces objets peuvent être implémentés en utilisant des registres multi-écrivains/multi-lecteurs, qui

eux-mêmes peuvent être implémentés en utilisant des objets snapshot. Le modèle de base reste donc le modèle dans lequel les processus n’ont accès qu’à des snapshots.

5.1.2.1 Le type d’objet safe_agreement

Ce type d’objet (défini dans [27, 30]) est au cœur de la simulation BG. Il fournit à chaque simulateur qideux opérations notées proposei(v) et decidei() que qipeut invoquer au maximum une fois, dans cet

ordre. L’opération proposei(v) permet à qide proposer une valeur v tandis que decidei() lui permet de

décider une valeur. Les propriétés satisfaites par un objet du type safe_agreement sont les suivantes. – Terminaison. Si aucun simulateur qxne crashe durant son exécution de proposex(), alors chaque

simulateur correct qiqui invoque decidei() termine cette invocation.

– Accord. Au plus une valeur est décidée.

– Validité. Une valeur décidée est une valeur proposée.

init : for each x : 1 ≤ x ≤ t + 1 do SM[x] ← (⊥, 0) end for. operation proposei(v) : % 1 ≤ i ≤ t + 1 %

(01) SM[i] ← (v, 1) ; (02) smi← SM.snapshot() ;

(03) if (∃x : smi[x].level = 2) then SM [i] ← (v, 0) else SM [i] ← (v, 2) end if.

operation decidei() : % 1 ≤ i ≤ t + 1 %

(04) repeat smi← SM.snapshot() until (∀x : smi[x].level 6= 1) end repeat ;

(05) let x = min({k | smi[k].level = 2) ; res ← smi[x].value ;

(06) return(res).

FIGURE5.1 – Une implémentation du type safe_agreement [30] (code de qi)

Une implémentation L’implémentation du type safe_agreement décrite dans la figure 5.1 vient de [30]. Cette construction est basée sur un objet snapshot SM (avec une entrée par simulateur qi). Chaque

entrée SM[i] de l’objet snapshot a deux champs : SM[i].value qui contient une valeur et SM[i].level qui contient son niveau. Le niveau 0 signifie que la valeur correspondante est sans importance, 1 signifie qu’elle est instable et 2 qu’elle est stable.

Quand un simulateur qiinvoque proposei(v), il écrit d’abord la paire (v, 1) dans SM [i] (ligne 01),

puis lit l’objet snapshot SM (ligne 02). S’il y a une valeur stable dans SM, pi“annule” la valeur qu’il

propose, sinon il la rend stable (ligne 03).

Un simulateur qiinvoque decidei() après avoir invoqué proposei(). Son but est de renvoyer la même

valeur stable à tous les processus qui invoquent cette opération (ligne 06). Pour cela, qicalcule en boucle

un snapshot de SM jusqu’à ce qu’il n’observe plus de valeur instable dans SM (ligne 04). Remarquons que, comme un simulateur qin’invoque decidei() qu’après avoir invoqué proposei(v), il y a au moins

une valeur stable dans SM quand il exécute la ligne 05. Finalement, pour que la même valeur stable soit renvoyée à tous les processus, qi renvoie la valeur stable proposée par le processus qui a l’identité la plus

petite (ligne 05).

Une preuve formelle que cet algorithme implémente le type safe_agreement est donnée dans [30].

5.1.2.2 Le type d’objet arbiter

Définition Chaque objet du type arbiter a un simulateur propriétaire qj prédéfini statiquement. Un tel

objet fournit aux processus une seule opération notée arbitratei,j() (où i est l’identité du processus qui

elle termine, cette invocation renvoie une valeur à qi. Les propriétés d’un objet arbiter dont le propriétaire

est qjsont les suivantes.

– Terminaison. Si le propriétaire qj invoque arbitratej,j() et est correct, ou s’il n’invoque pas

arbitratej,j(), ou si un simulateur qitermine son invocation arbitratei,j(), alors tous les processus

corrects terminent leur invocation arbitratei,j().

– Accord. Au plus une valeur est décidée.

– Validité. La valeur renvoyée est 1 (propriétaire) ou 0 (autre). De plus, si le propriétaire n’invoque pas arbitratej,j(), la valeur 1 ne peut pas être renvoyée et, si seul le propriétaire invoque arbitratei,j(),

la valeur 0 ne peut pas être renvoyée.

Une implémentation Une implémentation d’un objet du type arbiter est décrite dans la figure 5.2. Elle est basée sur un objet snapshot PART (initialisé à [false, . . . , false]) et un registre atomique WINNER (initialisé à ⊥).

Quand il invoque arbitratei,j(), le simulateur qi annonce qu’il participe (ligne 01) et effectue un

snapshot pour connaitre l’ensemble des simulateurs qui ont commencé à participer (line 02). Si qiest le

propriétaire de l’objet, (i = j, ligne 03), il vérifie s’il est le premier participant (prédicat parti = {i}).

Si c’est le cas, il affecte 1 à WINNER. Sinon, il lui affecte 0 (line 04). Si pin’est pas le propriétaire de

l’objet (i 6= j), il vérifie si le propriétaire a commencé sa participation (prédicat j ∈ parti). Si c’est le cas,

qiattend de savoir quelle valeur a été affectée à WINNER. Sinon, il affecte 0 à WINNER. Finalement,

qitermine en renvoyant la valeur de WINNER.

operation arbitratei,j() : % 1 ≤ i, j ≤ t + 1 %

(01) PART [i] ← true ;

(02) auxi← PART .snapshot() ; parti← {x | auxi[x]} ;

(03) if (i = j) % piis the owner of the associated arbiter type object %

(04) then if (parti= {i}) then WINNER ← 1 else WINNER ← 0 end if

(05) else if (j ∈ parti) then wait (WINNER 6= ⊥) else WINNER ← 0 end if

(06) end if ;

(07) return(WINNER).

FIGURE5.2 – L’opération arbitratei,j() du type arbiter (code de qi)

La démonstration que cette construction est une implémentation correcte du type arbiter est donnée ci-dessous.

Lemme 5.1. Si le propriétaire participe et est correct, alors tous les processus corrects qui participent terminent.

Démonstration. Il n’y a pas de boucle et la seule instruction bloquante de l’algorithme est l’instruction wait à la ligne 05 dans laquelle un processus pi attend qu’une valeur soit assignée à WINNER. Le

propriétaire (pj) affecte une valeur à WINNER avant de terminer (ligne 04), donc si le propriétaire

participe et est correct, alors tous les processus corrects qui participent terminent.

Lemme 5.2. Si le propriétaire ne participe pas, alors tous les processus corrects qui participent terminent. Démonstration. De nouveau, il n’y a pas de boucle et la seule instruction bloquante de l’algorithme est l’instruction wait à la ligne 05. Cette instruction n’est exécutée que si le processus observe que le propriétaire a commencé à participer donc, si le propriétaire ne participe pas, alors tous les processus corrects qui participent terminent.

Démonstration. De nouveau, il n’y a pas de boucle et la seule instruction bloquante de l’algorithme est l’instruction wait à la ligne 05 (elle attend qu’une valeur soit affectée à WINNER). Si un processus n’exécute pas cette instruction, il affecte une valeur à WINNER. Donc si un processus termine, alors tous les processus corrects qui participent terminent.

Lemme 5.4. Tous les processus renvoient la même valeur.

Démonstration. Le seul processus qui peut affecter à WINNER une valeur différente de 0 est le pro- priétaire (ligne 04). Nous n’avons donc que ce cas à considérer. Si le propriétaire affecte la valeur 1 à WINNER, cela signifie que dans le snapshot qu’il a pris à la ligne 02, il n’a observé aucun autre processus (ligne 04). Comme les snapshots sont linéarisables et le propriétaire annonce qu’il a démarré avant de prendre le snapshot (ligne 01), tous les autres processus observeront que le propriétaire a commencé et exécuteront l’instruction d’attente (ligne 05) au lieu d’affecter la valeur 0 à WINNER. Tous les processus renvoient donc la même valeur.

Lemme 5.5. Si le propriétaire ne participe pas, la valeur renvoyée est 0.

Démonstration. Le seul processus qui peut affecter une valeur différente de 0 à WINNER est le proprié- taire (ligne 04). Donc si le propriétaire ne participe pas, la valeur de WINNER est 0 et tous les processus renvoient cette valeur.

Lemme 5.6. Si le propriétaire est le seul participant, la valeur renvoyée est 1.

Démonstration. Si le propriétaire n’observe aucun autre participant, il affecte la valeur 1 à WINNER. Donc si le propriétaire est le seul participant, la valeur renvoyée est 1.

Théorème 5.7. L’algorithme présenté dans la figure 5.2 est une implémentation correcte du type d’objet arbiter.

Démonstration. Les lemmes 5.1, 5.2, 5.3, 5.4, 5.5 et 5.6 montrent que l’algorithme de la figure 5.2 respecte les spécifications du type d’objet arbiter.