News for hackers. Stuff that matters.
Re:Data Race Patterns in Go by morelisp on Friday June 10, 2022 @06:22PM (#31700034)
> atomic.Value isn't really atomic, since the concrete type can't ever change after being set.

How does this mean it's non-atomic? As far as I know you can still never Load() a partial Store(). (Also, even if it was possible, this would never be a good idea...)

Re:Data Race Patterns in Go by bumper_crop on Friday June 10, 2022 @06:40PM (#31700164)
That's why I opened with "Look at the implementation". Go is unable to store the type and the pointer at the same time, so it warps what "atomic" means. Pretty much every other language has atomic mean "one of these will win, one will lose". Go says "one will win, one will panic and destroy the goroutine.

In fact, it's even worse than that. If the Store() caller goes to sleep between setting the type and storing the pointer, it causes every Goroutine that calls Load() to block. They can't make forward progress if the store caller hangs.

Re:Data Race Patterns in Go by yencabulator on Saturday June 11, 2022 @02:59PM (#31707157)
> If the Store() caller goes to sleep between setting the type and storing the pointer, it causes every Goroutine that calls Load() to block.

Where does this go to sleep: https://cs.opensource.google/go/go/+/refs/tags/go1.18.3:src/...

It looks like a CAS busy loop with preemption disabled, to me.

Re:Data Race Patterns in Go by bumper_crop on Monday June 20, 2022 @09:06PM (#31818489)
Make sure to read between the lines. It only looks like a busy loop. Remember, the OS can pause and preempt your thread at any time. This is a real and likely event.
Re:Data Race Patterns in Go by mbnull on Saturday July 02, 2022 @06:59AM (#31957938)
By reading the lines and not between them, you could read these two lines: runtime_procPin() and runtime_procUnpin(). With explicit comments that these pause preemption.
Re:Data Race Patterns in Go by tapirl on Saturday June 11, 2022 @01:37PM (#31706323)
> Pretty much every other language has atomic mean "one of these will win, one will lose"

Could you elaborate how "much every other language" implement it?

Re:Data Race Patterns in Go by fastest963 on Friday June 10, 2022 @07:00PM (#31700298)
This is why all the examples call Store immediately with a zero value of the type.
Re:Data Race Patterns in Go by bumper_crop on Friday June 10, 2022 @07:22PM (#31700441)
https://go.dev/play/p/xolc9oPwA0C

Interfaces don't have a zero type, which means that we can't have an atomic.Value which stores Shape. Atomic Value would be much easier to reason about if it had store semantics similar to a regular `var foo Shape = ...`. One of the other comment threads talked about generics helping this, so maybe there is hope.

Re:Data Race Patterns in Go by yencabulator on Saturday June 11, 2022 @02:58PM (#31707138)
Parent means

    var bestShape atomic.Value
    bestShape.Store((*Circle)(nil))
Re:Data Race Patterns in Go by morelisp on Saturday June 11, 2022 @05:24PM (#31708570)
Which will store it as a *Circle, and only allow more *Circles, not Shapes. That part of GP’s claim is correct.

It just had nothing to do with atomicity; it means something specific, not just “I like the failure mode.”

Re:Data Race Patterns in Go by yencabulator on Sunday June 12, 2022 @11:36AM (#31715293)
That's pretty easy to workaround:

    type shapeContainer struct { Shape }
The usual way to use atomic.Value is by writing strongly-typed wrappers anyway, so that doesn't affect your codebase beyond about 3 lines.
Re:Data Race Patterns in Go by morelisp on Saturday June 11, 2022 @03:39AM (#31702710)
Abend is a fairly normal and in many ways best way to "lose" in a race. It's fine, it's atomic.