В чем разница между использованием явных заборов и std :: atomic?
Предполагая, что выравниваемые нагрузки и хранилища указателя на целевой платформе естественно атомарны, в чем разница между этим:
// Case 1: Dumb pointer, manual fence
int* ptr;
// ...
std::atomic_thread_fence(std::memory_order_release);
ptr = new int(-4);
этот:
// Case 2: atomic var, automatic fence
std::atomic ptr;
// ...
ptr.store(new int(-4), std::memory_order_release);
и это:
// Case 3: atomic var, manual fence
std::atomic ptr;
// ...
std::atomic_thread_fence(std::memory_order_release);
ptr.store(new int(-4), std::memory_order_relaxed);
У меня сложилось впечатление, что все они были эквивалентны, однакоRelacy обнаруживает гонку данных в первом случае (только):
struct test_relacy_behaviour : public rl::test_suite
{
rl::var ptr;
rl::var data;
void before()
{
ptr($) = nullptr;
rl::atomic_thread_fence(rl::memory_order_seq_cst);
}
void thread(unsigned int id)
{
if (id == 0) {
std::string* p = new std::string("Hello");
data($) = 42;
rl::atomic_thread_fence(rl::memory_order_release);
ptr($) = p;
}
else {
std::string* p2 = ptr($); //