Здравствуйте, WolfHound, Вы писали:
V>>В момент чтения b = lbuckets[bucketNumber] без всяких барьеров можно прочитать в поля bucket значения из памяти в произвольном порядке, например прочитать в b.val null, в то время как b.key и b.hash_coll будут еще валидными.
WH>В этом случае сработает вот это условие
WH>WH>isWriterInProgress || (currentversion != version)
WH>
WH>И значение будет считано ещё раз.
Я как раз указал на то, что коль содержимое this.buckets не является volatile, а операция b = lbuckets[bucketNumber] независима по данным с isWriterInProgress || (currentversion != version), то процессор имеет полное право эти операции переупорядочить. Посмотри внимательно еще раз. Обращение к isWriterInProgress и currentversion идет по чтению:
Accure fence гарантирует что инструкции, стоящие после барьера, не будут перемещены в позицию до барьера.
Но обратное разрешено.
Т.е. косяк есть и не срабатывает он лишь по той причине, что в текущих процах x86 и AMD64 нет разделения на Release fence и Accure fence, т.е. барьер всегда только один — полный Strict fence (оно же std::memory_order_seq_cst в С++11). Зато в Итаниуме и PowerPC барьеры разные.