No artigo com o mesmo título que o desta pergunta, os autores descrevem como construir uma operação CAS linearizável de múltiplas palavras sem bloqueio usando apenas um CAS de uma única palavra. Eles primeiro introduzem a operação de dupla comparação, troca única - RDCSS, da seguinte maneira:
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);
}
onde RDCSSDescriptor_t
é uma estrutura com os seguintes campos:
a1
- endereço da primeira condiçãoo1
- valor esperado no primeiro endereçoa2
- endereço da segunda condiçãoo2
- valor esperado no segundo endereçon2
- o novo valor a ser escrito no segundo endereço
Esse descritor é criado e inicializado uma vez em um encadeamento que inicia a operação RDCSS - nenhum outro encadeamento faz referência a ele até que o primeiro CAS1 da função seja RDCSS
bem-sucedido, tornando o descritor acessível (ou ativo na terminologia do artigo).
A idéia por trás do algoritmo é a seguinte - substitua o segundo local da memória por um descritor dizendo o que você deseja fazer. Em seguida, como o descritor está presente, verifique o primeiro local da memória para ver se seu valor foi alterado. Caso contrário, substitua o descritor no segundo local da memória pelo novo valor. Caso contrário, defina o segundo local da memória novamente para o valor antigo.
Os autores não explicam por que a linha com o !!
comentário é necessária no artigo. Parece-me que as CAS1
instruções na Complete
função sempre falham após essa verificação, desde que não haja modificação simultânea. E se houve uma modificação simultânea entre a verificação e a entrada do CAS Complete
, o segmento que está realizando a verificação ainda deve falhar com o seu CAS Complete
, pois a modificação simultânea não deve usar o mesmo descritor d
.
A minha pergunta é: Pode o check-in a função RDCSSS
, if (r == d->o2)...
ser omitido, com RDCSS ainda mantendo a semântica de um comparar única instrução dupla, troca que é linearizable e livre-lock ? (linha com !!
comentário)
Caso contrário, você pode descrever o cenário em que essa linha é realmente necessária para garantir a correção?
Obrigado.