user3188445
user3188445

Reputation: 4748

Why is memory_order_relaxed not okay for a once_flag-like atomic_bool?

On slide 54 of Herb Sutter's talk on "atomic<> Weapons" (which unfortunately he didn't have time to present in the video), he suggests the following code is incorrect:

struct widget {
  static inline atomic<widget *> instance = nullptr;
  static inline atomic<bool> create = false;

  static widget *get_instance()
  {
    if (instance.load(memory_order_acquire) == nullptr) {
      if (!create.exchange(true, memory_order_relaxed)) // <- BAD?
        instance.store(new widget(), memory_order_release);
      else
        while (instance.load(memory_order_acquire) == nullptr)
          ;
    }
    return instance.load(memory_order_acquire);
  }
};

Supposedly the line labeled // <- BAD? should be:

      if (!create.exchange(true, memory_order_acquire)) // <- GOOD?

My question: what can go wrong with the BAD line (even on contrived pathological architectures that do not exist)? Equivalently, what's wrong with the following argument for why the BAD line is actually okay?

Upvotes: 5

Views: 107

Answers (0)

Related Questions