Есть ли какая-либо формулировка в стандарте, которая гарантирует, что расслабленные магазины для атомистики не будут подняты выше блокировки мьютекса? Если нет, есть ли какая-либо формулировка, в которой явно сказано, что это кошерно для компилятора или процессора?
Например, возьмите следующую программу:
std::mutex mu;
int foo = 0; // Guarded by mu
std::atomic<bool> foo_has_been_set{false};
void SetFoo() {
mu.lock();
foo = 1;
foo_has_been_set.store(true, std::memory_order_relaxed);
mu.unlock();
}
void CheckFoo() {
if (foo_has_been_set.load(std::memory_order_relaxed)) {
mu.lock();
assert(foo == 1);
mu.unlock();
}
}
Возможно ли, что в CheckFoo
произойдет сбой в вышеуказанной программе, если другой поток вызывает SetFoo
одновременно или есть какая-то гарантия того, что хранилище до foo_has_been_set
не может быть поднято над вызовом mu.lock
компилятором и процессором?
Это связано с старым вопросом, но мне это не на 100% понятно, что ответ на это применим. В частности, встречный пример в ответе на вопрос может применяться к двум одновременным вызовам SetFoo
, но меня интересует случай, когда компилятор знает, что есть один вызов SetFoo
и один вызов CheckFoo
, Гарантировано ли это безопасно?
Я ищу конкретные цитаты в стандарте. Спасибо!