CHESS и store buffer vulnerability
От: Mr.Cat  
Дата: 04.06.10 22:14
Оценка:
Анализирую сабжем одну программку и получаю сабж. Суть такова (от кода оставлена только концепция, мог слегка лажануть — но реальный код по всем признакам рабочий).

Есть некий глобальный объект.
volatile object globalOne = ...

Иногда он модифицируется вот таким вот одноразовым методом одноразового инстанса (т.е. инстанс создается на 1 модификацию и метод вызывается единожды):
class ObjectMutator
{
  volatile object oldOne;
  volatile object newOne;
  volatile bool completed = false;

  void Mutate()
  {
    oldOne = globalOne;
    globalOne = this;
    newOne = f(...);
    completed = true; //3
    globalOne = newOne; //1
  }
}

И читается он тоже иногда — вот так вот:
var current = globalOne; //2
if(globalOne is ObjectMutator)
{
  var mutator = (ObjectMutator)globalOne;
  return mutator.completed ? mutator.newOne : mutator.oldOne;
}
else
  return current;

CHESS видит store buffer vulnerability и указывает на строки 1 и 2, при этом перестает ругаться, если 1 заменить на
Interloked.CompareExchange(ref globalOne, newOne, this);

Возникает вопрос, в чем заключается этот самый store buffer vulnerability и почему он исчезает при использовании cas.

Поковырявшись в гугле я родил предположение, что теоретически мутатор может совсем не опубликовать свою мутацию — отложить всю свою запись до следующей среды — и будет прав. А Interlocked-операции заставляют его-таки что-нибудь опубликовать.

Фишка в том, что обычно задержку публикации приводят как раз как пример использования volatile (который тут и так есть), а не cas. И кому в итоге верить? В принципе, я больше верю CHESS. Таки согласно ecma, volatile имеет отношение только к упорядочиванию (типа "если наш volatile read увидел эффект вашего volatite write, то...").
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.