Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a write to std::atomic go unseen by other threads while using std::atomic::compare_exchange_strong?

std::atomic<int> g_atomic;

void thread0()
{
  int oldVal = 0;
  int newVal = 1;
  while (g_atomic.compare_exchange_strong(oldVal, newVal, std::memory_order_acq_rel, std::memory_order_acquire))
  {
    // forever counting from 0 to 100 until unexpected value appears
    oldVal = newVal;
    newVal = (oldVal + 1) % 100;
  };
}

void thread1()
{
  // set unexpected value
  g_atomic.store(-1, std::memory_order_release);
}

int main()
{
  g_atomic.store(0);
  std::thread t0(thread0);
  std::thread t1(thread1);
  t0.join();
  t1.join();
  return 0;
}

Can it happen that the write from thread1 is somehow overwritten in the loop of thread0 before it gets visible in thread0? The program would then run forever. This does not happen in my tests however im interested if there is any guarantee saying this will always be the case.

like image 654
Katz389 Avatar asked Feb 01 '19 13:02

Katz389


1 Answers

So, to provide a definitive answer to this, no, a write from thread1 will never be missed by thread0.

This is because std::atomic::compare_exchange_strong is an atomic operation so the write from thread0 either happens before this operation starts (in which case it returns false) or after it completes (in which case the call will fail next time round the loop).

If it was any other way, compare_exchange_strong would have no utility, no?

like image 144
Paul Sanders Avatar answered Nov 02 '22 02:11

Paul Sanders