Skip to content

LWG3980 [atomics.ref.ops] p19 Where is the wording that forbids the read operation to read the same initial value? #423

Closed as not planned
@xmh0511

Description

@xmh0511

Full name of submitter (unless configured in github; will be published with the issue): Jim X

[atomics.types.operations] p23 says:

bool compare_exchange_weak(T& expected, T desired, memory_order success, memory_order failure) noexcept;

Effects: Retrieves the value in expected.
It then atomically compares the value representation of the value pointed to by this for equality with that previously retrieved from expected, and if true, replaces the value pointed to by this with that in desired.
If and only if the comparison is true, memory is affected according to the value of success, and if the comparison is false, memory is affected according to the value of failure.
When only one memory_order argument is supplied, the value of success is order, and the value of failure is order except that a value of memory_order​::​acq_rel shall be replaced by the value memory_order​::​acquire and a value of memory_order​::​release shall be replaced by the value memory_order​::​relaxed.
If and only if the comparison is false then, after the atomic operation, the value in expected is replaced by the value pointed to by this during the atomic comparison. If the operation returns true, these operations are atomic read-modify-write operations ([intro.multithread]) on the memory pointed to by this. Otherwise, these operations are atomic load operations on that memory.

Consider this example:

#include <iostream>
#include <atomic>
#include <thread>
struct SpinLock{
    std::atomic<bool> atomic_;
    void lock(){
	   bool expected = false;
           while (!atomic_.compare_exchange_strong(expected,true,std::memory_order_release,std::memory_order_relaxed)){

	   }
    }
    void unlock(){
	  atomic_.store(false, std::memory_order_release);
    }
};
int main(){
	SpinLock spin{false};
        auto t1 = std::thread([&](){
		spin.lock();
		spin.unlock();
	});
	auto t2 = std::thread([&](){
		spin.lock();
		spin.unlock();
	});
	t1.join();
	t2.join();
}

This is the essence of implementing the "spinlock". However, in this example, spin is initialized with the value false, So, can the comparison in the two threads both read this initial value false and compare equally with the expected value false? IMO, there is no formal wording in the standard that forbids this possible. [intro.races] p14 just says:

The value of an atomic object M, as determined by evaluation B, shall be the value stored by some side effect A that modifies M, where B does not happen before A.

If they cannot, where does the relevant wording specify that this is impossible?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy