Nel documento con lo stesso titolo di quella di questa domanda, gli autori descrivono come costruire un bloccante linearizzabile multi-word CAS operazione utilizzando solo una parola sola CAS. Inizialmente introducono l'operazione double-compare-single-swap - RDCSS, come segue:
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);
}
dove la RDCSSDescriptor_t
è una struttura con i seguenti campi:
a1
- indirizzo della prima condizioneo1
- valore atteso al primo indirizzoa2
- indirizzo della seconda condizioneo2
- valore atteso al secondo indirizzon2
- il nuovo valore da scrivere al secondo indirizzo
Questo descrittore viene creato e inizializzato una volta in un thread che avvia l'operazione RDCSS - nessun altro thread ha un riferimento ad esso fino a quando il primo CAS1 nella funzione non RDCSS
riesce, rendendo raggiungibile il descrittore (o attivo nella terminologia del documento).
L'idea alla base dell'algoritmo è la seguente: sostituire la seconda posizione di memoria con un descrittore che dice cosa si desidera fare. Quindi, dato che il descrittore è presente, controlla la prima posizione di memoria per vedere se il suo valore è cambiato. In caso contrario, sostituire il descrittore nella seconda posizione di memoria con il nuovo valore. Altrimenti, reimpostare la seconda posizione di memoria sul vecchio valore.
Gli autori non spiegano perché la riga con il !!
commento è necessaria all'interno del documento. Mi sembra che le CAS1
istruzioni nella Complete
funzione falliranno sempre dopo questo controllo, a condizione che non vi siano modifiche simultanee. E se ci fosse una modifica simultanea tra il check e il CAS in Complete
, allora il thread che esegue il check dovrebbe comunque fallire con il suo CAS in Complete
, poiché la modifica simultanea non dovrebbe usare lo stesso descrittore d
.
La mia domanda è: può il controllo nella funzione RDCSSS
, if (r == d->o2)...
essere omesso, con RDCSS mantenendo la semantica di un confronto, di scambio di istruzioni singola doppia che è linearizzabile e senza blocchi ? (linea con !!
commento)
In caso contrario, puoi descrivere lo scenario in cui questa riga è effettivamente necessaria per garantire la correttezza?
Grazie.