Requirements for std::thread::id. Can it be atomized?
atomic, c++, c++11, language-lawyer, multithreading
Solution
Firstly, `std::atomic<std::thread::id>` is legal: `std::thread::id` is required to be trivially copyable (30.3.1.1p2), which meets the requirements of `std::atomic<>` (29.5p1).
However, it is an opaque class, so there is no requirement that the bit pattern of objects that compare equal be identical.
Consequently, if you use `compare_exchange_weak` or `compare_exchange_strong` then it may fail for values that compare equal.
Thus, the advice is to use `compare_exchange_weak` in a loop, leaving the `expected` value as the result of the previous iteration.
In your case, the semantics I interpret from your loop are: keep looping whilst `worker_id` is the ID of another thread, or `worker_id` was `std::thread::id` but the exchange failed. You can achieve this with the following:
no_id=std::thread::id();
while((no_id!=std::thread::id()) ||
!worker_id.compare_exchange_weak( no_id, self_id ) ){
if(no_id!=std::thread::id()) no_id=std::thread::id();
sleep();
}
or
no_id=std::thread::id();
while(!worker_id.compare_exchange_weak(
(no_id!=std::thread::id())?(no_id=std::thread::id())?no_id, self_id ) )
sleep();
i.e. only change the `no_id` value if it is not `std::thread::id()`.
Problem
The standard says: "An object of type thread::id provides... a single distinct value for all thread objects that do not represent a thread of execution". Is that a single/distinct value with regard to `operator==`, or is it the actual bitwise-single/distinct value? The reason for the question: MSVC2012's `std::thread::id::id()` leaves garbage in one of its fields, and it breaks code that does compare-exchange on an `std::atomic<std::thread::id>` (since the latter depends on bitwise comparisons). Is `std::atomic<std::thread::id>` a legal construct in the first place? EDIT: for the reference, the code goes like this: ``` while( !worker_id.compare_exchange_weak( no_id = thread_id_type(), self_id ) ) sleep(); ```