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:
Jean Sirmai 2021-04-08 09:39:13 +00:00
commit c907a02f32
1 changed files with 75 additions and 30 deletions

View File

@ -1,40 +1,85 @@
Concurrent programming for gem-graph Concurrent programming for gem-graph
Deux ressources doivent être accessibles aux threads de calcul de l'automate: Le thread maître, dans l'ordre:
- les transitions (c-a-d: l'arbre des règles) (1) - cherche, en un temps fini, un espace local dans l'espace global de préemption et, s'il le trouve:
+ car chaque thread de calcul doit choisir l'une d'entre elles + tente, en un temps fini, de le préempter et, si la préemption a été possible,
- l'état local (c-a-d: une partie de l'espace global préemptée) + crée un thread de calcul en lui communiquant l'adresse de cet espace local
+ que le thread doit lire pour choisir la règle de transition + et l'inscrit dans la liste des threads)
+ 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)
puisque les threads lisent seulement l'arbre des règles pendant leur calcul, (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:
et que le seul objet dans lequel ils doivent écrire est l'espace global, + lève la préemption de leur espace local et
il y n'y a pas de risque de race condition du fait de leurs opérations de calcul. + les retire de la liste des threads.
le thread maître (3) - affiche les résultats.
(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 Chaque thread de calcul, dans l'ordre:
(1) - cherche si une règle peut s'appliquer à son espace local. (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) (pour faire ce calcul, il n'écrit que dans des variables locales)
(2) - écrit le résultat de son calcul dans l'espace global. si échec, il se termine, sinon:
(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é)
L'espace global et la liste des threads sont donc les seuls objets où plusieurs threads doivent écrire: (2) - écrit le résultat de son calcul dans l'espace global si une règle peut être appliquée.
(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 - 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) : - chaque thread doit écrire dans les deux quand il finit son calcul :
+ son résultat dans l'espace global et + 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) + 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: Des deadlocks sont possibles si:
- le thread maître a acquis l'espace global et attend pour la liste des threads - 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 - 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): 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 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) 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 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. 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ù le thread maître vient de trouver un espace local convenable et
- le moment où il a fini de préempter cet espace local. - le moment où il a fini de préempter cet espace local.