Merge branch 'Jean-master-patch-93152' into 'master'
Concurrent programming for gem-graph See merge request gem-graph-team/gem-graph!13
This commit is contained in:
commit
c907a02f32
|
@ -1,40 +1,85 @@
|
|||
Concurrent programming for gem-graph
|
||||
|
||||
Deux ressources doivent être accessibles aux threads de calcul de l'automate:
|
||||
- les transitions (c-a-d: l'arbre des règles)
|
||||
+ car chaque thread de calcul doit choisir l'une d'entre elles
|
||||
- l'état local (c-a-d: une partie de l'espace global préemptée)
|
||||
+ que le thread doit lire pour choisir la règle de transition
|
||||
+ et où il doit écrire le résultat de son calcul en cas de succès
|
||||
(le thread n'est crée que si cette préemption a été possible)
|
||||
Le thread maître, dans l'ordre:
|
||||
(1) - cherche, en un temps fini, un espace local dans l'espace global de préemption et, s'il le trouve:
|
||||
+ tente, en un temps fini, de le préempter et, si la préemption a été possible,
|
||||
+ crée un thread de calcul en lui communiquant l'adresse de cet espace local
|
||||
+ et l'inscrit dans la liste des threads)
|
||||
|
||||
(2) - cherche, en un temps fini, dans la liste des threads s'il y a qui ont fini leur calcul et, s'il y en a:
|
||||
+ lève la préemption de leur espace local et
|
||||
+ les retire de la liste des threads.
|
||||
|
||||
(3) - affiche les résultats.
|
||||
|
||||
puisque les threads lisent seulement l'arbre des règles pendant leur calcul,
|
||||
et que le seul objet dans lequel ils doivent écrire est l'espace global,
|
||||
il y n'y a pas de risque de race condition du fait de leurs opérations de calcul.
|
||||
|
||||
le thread maître
|
||||
(1) - cherche un espace local dans l'espace global et, s'il le trouve, le préempte.
|
||||
(2) - crée un thread de calcul en lui communiquant l'adresse de cet espace local.
|
||||
(3) - cherche s'il y a des threads qui ont fini leur calcul et, s'il y en a,
|
||||
(4) - lève la préemption de leur espace local et les retire de la liste des threads.
|
||||
les recherches (1) et (3) doivent s'effectuer en un temps fini.
|
||||
|
||||
le thread de calcul
|
||||
(1) - cherche si une règle peut s'appliquer à son espace local.
|
||||
Chaque thread de calcul, dans l'ordre:
|
||||
(1) - lit son espace local et les règles écrites dans l'arbre des transitions et les compare.
|
||||
(pour faire ce calcul, il n'écrit que dans des variables locales)
|
||||
(2) - écrit le résultat de son calcul dans l'espace global.
|
||||
(3) - écrit qu'il est terminé dans une liste où le thread maître peut lire et écrire.
|
||||
cette écriture est sa dernière instruction. (après, il est terminé)
|
||||
si échec, il se termine, sinon:
|
||||
|
||||
(2) - écrit le résultat de son calcul dans l'espace global si une règle peut être appliquée.
|
||||
|
||||
L'espace global et la liste des threads sont donc les seuls objets où plusieurs threads doivent écrire:
|
||||
(3) - écrit qu'il est terminé dans une liste où le thread maître peut lire et écrire.
|
||||
si succès, cette écriture est sa dernière instruction. (après, il est terminé)
|
||||
|
||||
|
||||
> engine (top-level) boucle infinie:
|
||||
|
||||
opération type ressource thread maître thread de calcul
|
||||
--------- ---- ---------- ------------- ----------------
|
||||
recherche espace local boucle finie liste des flèches lecture
|
||||
espace global de préemption lecture
|
||||
|
||||
préemption espace local section critique espace global de préemption fermeture verrou
|
||||
vérification boucle finie espace global de préemption lecture
|
||||
si confirmation: boucle finie espace global de préemption écriture
|
||||
fin section c. espace global de préemption ouverture verrou
|
||||
si succès préemption:
|
||||
création d'un thread section critique liste des threads fermeture verrou
|
||||
boucle finie liste des threads lecture
|
||||
si succès, assignment liste des threads écriture
|
||||
fin section c. liste des threads ouverture verrou
|
||||
assignment mémoire / CPU système écriture
|
||||
|
||||
recherche règle de transition parcours d'arbre arbre des transitions lecture
|
||||
espace global graphique lecture
|
||||
|
||||
si succès, transition locale boucle finie espace global graphique écriture
|
||||
|
||||
terminaison d'un thread section critique liste des threads fermeture verrou
|
||||
(adresse connue) assignment liste des threads écriture
|
||||
fin section c. liste des threads ouverture verrou
|
||||
fin du thread
|
||||
|
||||
levée préemption espace local section critique liste des threads fermeture verrou
|
||||
boucle finie liste des threads lecture
|
||||
si succès, assignment liste des threads écriture
|
||||
fin section c. liste des threads ouverture verrou
|
||||
|
||||
thread d'affichage boucle finie recherche résultats lecture
|
||||
sorties système écriture
|
||||
--------- ---- ---------- ------------- ----------------
|
||||
|
||||
Trois ressources doivent être accessibles aux threads de calcul de l'automate:
|
||||
- les transitions (c-a-d: l'arbre des règles) en lecture seulement:
|
||||
- l'état local (c-a-d: une partie de l'espace global préemptée) pour:
|
||||
(1) lire les contraintes nécéssaires pour le choix de la règle de transition
|
||||
(2) puis écrire le résultat de son calcul en cas de succès
|
||||
|
||||
Le thread n'est crée que si la préemption a été possible
|
||||
Son calcul aboutit au choix de l'une des règles ou échoue
|
||||
comme les threads ont seulement besoin de lire l'arbre des règles pendant leur calcul.
|
||||
Ces lectures ne causent pas de risque de race condition.
|
||||
|
||||
L'espace global de préemption et la liste des threads sont les seuls objets où plusieurs threads doivent écrire:
|
||||
- le thread maître doit écrire dans les deux au début du calcul (quand il préempte et crée un thread) et
|
||||
- chaque thread doit écrire dans les deux quand il finit son calcul (si son calcul a abouti) :
|
||||
+ son résultat dans l'espace global et
|
||||
- chaque thread doit écrire dans les deux quand il finit son calcul :
|
||||
+ son résultat dans l'espace global (si son calcul a abouti) et
|
||||
+ son état dans la liste des threads (sinon, le thread maître ne saura pas qu'il peut lever la préemption)
|
||||
|
||||
Des deadlocks sont possibles si:
|
||||
- le thread maître a acquis l'espace global et attend pour la liste des threads
|
||||
- un thread de calcul a acquis la liste des threads et attend pour l'espace global
|
||||
- le thread maître a acquis l'espace global de préemption et attend pour la liste des threads
|
||||
- un thread de calcul a acquis la liste des threads et attend pour l'espace global de préemption
|
||||
|
||||
Mais si les acquisitions se font dans le même ordre pour tous les threads (maître et calcul):
|
||||
en premier l'espace global et en second la liste des threads, alors il ne peut y avoir de deadlock
|
||||
|
@ -44,9 +89,9 @@ Une première solution est donc de ne réaliser que simultanément l'ensemble de
|
|||
sur l'espace global et la liste des threads (en début comme en fin de calcul)
|
||||
et de ne les réaliser que lorsque les deux ressources ont été acquises
|
||||
par le thread maître en début de calcul ou par le thread de calcul lorsqu'il a fini.
|
||||
Cette solution peut être coûteuse en temps d'attente.
|
||||
Cette solution est coûteuse en temps d'attente.
|
||||
|
||||
Le point délicat est qu'il ne faut pas que l'espace global soit modifié entre:
|
||||
Le point délicat est qu'il ne faut pas que l'espace global de préemption soit modifié entre:
|
||||
- le moment où le thread maître vient de trouver un espace local convenable et
|
||||
- le moment où il a fini de préempter cet espace local.
|
||||
|
||||
|
|
Loading…
Reference in New Issue