| |
| Posted by rm in reply to sarn | PermalinkReply |
|
rm
| On 01/06/2021 5:50, sarn wrote:
> On Sunday, 30 May 2021 at 20:58:56 UTC, IGotD- wrote:
>> Definitely, the D atomic library is cumbersome to use. C++ std::atomic supports operator overloading for example.
>>
>> atomicVar += 1;
>>
>> will create an atomic add as atomicVar is of the atomic type. D doesn't have this and I think D should add atomic types like std::atomic<T>.
>
> That was a design choice. It's because of this:
>
>> I like this because then I can easily switch between atomic operations and normal operations by just changing the type and very few changes.
>
> The trouble is that only works in a handful of simple cases (e.g., you just want a simple event counter that doesn't affect flow of control). For anything else, you need to think carefully about exactly where the atomic operations are, so there's no point making them implicit.
I agree about that. One shouldn't simply access the same memory location atomically and non-atomically interchangeably. That is a source for many bugs. Especially considering the kind of synchronization you'll have or not have as a result.
Still, there are cases where you *know* that your thread is the *only one* that can access this variable. In a case like this, only after you made sure to synchronize you can also allow for non atomic access to the variable (Though I'd still avoid this).
Alternatively, the other case is going from non-atomic to atomic. After initializing the location with an allocator in a non atomic manner, you move to use it atomically to synchronize between threads.
But regarding the design choice, if your intention is to prevent casting the atomic to non-atomic. You can simply wrap it in a struct and not allowing access to the raw value. That should be sufficient.
Anyway, I disagree about the simple cases. Because specifically the case of simple event counter that isn't require for synchronization, you should be using relaxed. There is no need for sequential consistency in this case.
|