Antoine Morrier
Antoine Morrier

Reputation: 4078

atomic thread fence: Why is there a data race on this non atomic variable? And does it matter?

Let's say we have 2 threads. One producer and one consumer. We have the producer that produce a data, and the consumer that use this data. However the guard is not atomic !

bool isDataReady = false;
int data = 0;

void Producer() {
  data = 42;
  std::atomic_thread_fence(std::memory_order_release);
  isDataReady = true;
}

void Consumer() {
  while(!isDataReady);
  std::atomic_thread_fence(std::memory_order_acquire);
  assert(data == 42);
}

I wonder why is there a data race on isDataReady. Normally, the correct code should be to use relaxed ordering on an atomic bool variable.

Is it because the write (transaction) to isDataReady could be not finished before the read? And even if it is the case, is it really an issue?

Upvotes: 2

Views: 291

Answers (1)

bartop
bartop

Reputation: 10315

TL;DR

This data race is dangerous and you should care about eliminating it. It may not manifest due to your luck, but it will eventually cause a headache.

A bit longer

This code has problems due to a few issues:

  1. While compiling Consumer compiler is not aware that isDataReady can change in background so it is perfectly reasonable to emit while(!isDataReady) an infinite loop or just nothing (due to forward progress guarantee, as was pointed out in comments).

  2. If write and/or read to bool is not atomic (which is not the case on most platforms, yet is theoretically possible) any of reads can cause getting garbage data.

  3. Memory fence with std::memory_order_release ensures that changes that happend in the thread will be visible after other thread calls fence with std::memory_order_acquire (at least in simplification). So, the change of bool variable may be invisible in other thread.

  4. Due to superscalar architecture of modern processorss, operations may be reordered in runtime by processor. So order of memory writes in Producer visible from Consumer may be different than the one put in the code.

Upvotes: 4

Related Questions