tower120
tower120

Reputation: 5255

C++ atomic CAS(compare-and-swap) operation does not change value

In the following example, what actually happens? Why value does not changes after successful exchange?

Live: https://wandbox.org/permlink/f5VYSKfQ9UJqa8FQ

std::atomic<bool> flag{false};

int main()
{
    std::thread thread([](){
        while(true){        
            // wait until flag not becomes true
            {
              bool expect = true;
              while(!flag.compare_exchange_strong(expect, false, std::memory_order_acq_rel)){
                  std::cout << "wait" << std::endl;
              }
            }
            
            std::cout << "work" << std::endl;
        }
    });
    flag.store(true, std::memory_order_release);
    thread.join();
}

Output:

work
wait
work
wait
...

Upvotes: 1

Views: 8645

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126193

Consider what happens with:

          bool expect = true;
          while(!flag.compare_exchange_strong(expect, false, std::memory_order_acq_rel)){
              std::cout << "wait" << std::endl;
          }

when the flag is false. The first time the test in the while loop runs, expect will be true, so does not match the flag. So expect is updated to the false, and the function returns false. So wait is printed and the loop repeats. The second test in the loop, expect will now be false, which matches flag, so flag will be set to false (a noop as it already is), and the loop will exit.

The net effect will be to always set flag to false, and print wait if it was already false. Thus, the output you see.

Upvotes: 1

Related Questions