Dans l' article portant le même titre que celui de cette question, les auteurs décrivent comment construire une opération CAS multi-mots linéarisable non bloquante en utilisant uniquement un CAS en un seul mot. Ils introduisent d'abord l'opération de double comparaison-échange simple - RDCSS, comme suit:
word_t RDCSS(RDCSSDescriptor_t *d) {
do {
r = CAS1(d->a2, d->o2, d);
if (IsDescriptor(r)) Complete(r);
} while (IsDescriptor(r));
if (r == d->o2) Complete(d); // !!
return r;
}
void Complete(RDCSSDescriptor_t *d) {
v = *(d->a1);
if (v == d->o1) CAS1(d->a2, d, d->n2);
else CAS1(d->a2, d, d->o2);
}
où RDCSSDescriptor_t
est une structure avec les champs suivants:
a1
- adresse de la première conditiono1
- valeur attendue à la première adressea2
- adresse de la deuxième conditiono2
- valeur attendue à la deuxième adressen2
- la nouvelle valeur à écrire à la deuxième adresse
Ce descripteur est créé et initialisé une fois dans un thread qui initie l'opération RDCSS - aucun autre thread n'y fait référence jusqu'à ce que le premier CAS1 de la fonction RDCSS
réussisse, ce qui rend le descripteur accessible (ou actif dans la terminologie du papier).
L'idée derrière l'algorithme est la suivante - remplacez le deuxième emplacement de mémoire par un descripteur indiquant ce que vous voulez faire. Puis, étant donné que le descripteur est présent, vérifiez le premier emplacement de mémoire pour voir si sa valeur a changé. Si ce n'est pas le cas, remplacez le descripteur au deuxième emplacement mémoire par la nouvelle valeur. Sinon, redéfinissez le deuxième emplacement de mémoire sur l'ancienne valeur.
Les auteurs n'expliquent pas pourquoi la ligne avec le !!
commentaire est nécessaire dans l'article. Il me semble que les CAS1
instructions de la Complete
fonction échoueront toujours après cette vérification, à condition qu'il n'y ait pas de modification simultanée. Et s'il y avait une modification simultanée entre la vérification et le CAS dans Complete
, alors le thread effectuant la vérification devrait toujours échouer avec son CAS dans Complete
, car la modification simultanée ne devrait pas utiliser le même descripteur d
.
Ma question est la suivante: la vérification de la fonction peut RDCSSS
-elle if (r == d->o2)...
être omise, RDCSS conservant toujours la sémantique d'une instruction de comparaison double et de permutation simple qui est linéarisable et sans verrouillage ? (ligne avec !!
commentaire)
Sinon, pouvez-vous décrire le scénario où cette ligne est réellement nécessaire pour garantir l'exactitude?
Je vous remercie.