Earlier quoted context omitted.
> so the signed integer you're using to count stuff up from zero might be -16 now, which is astonishing Actually, if it is an int, it is guaranteed to not be any number not explicitly set to (java has no-out-of-thin-air guarantees for 32-bit primitives). In practice on every modern implementation it is true of 64-bit primitives as well. So the prototypical data race condition of incrementing a primitive counter from…
Ooh, I did not know this. Do you happen to know where the "no-out-of-thin-air" guarantee is for the 32-bit primitives? Presumably in the Memory model docs somewhere?
Data Race Patterns in Go
201–205 of 205 posts
Re: Data Race Patterns in Go
#202Earlier quoted context omitted.
Ooh, I did not know this. Do you happen to know where the "no-out-of-thin-air" guarantee is for the 32-bit primitives? Presumably in the Memory model docs somewhere?
I quickly glanced at the spec, but didn’t find it. But I didn’t make it up though, I remember reading it on the jvm mailing list and I found it here described by Brian Goetz himself: https://openjdk.org/projects/valhalla/design-notes/state-of-...
Re: Data Race Patterns in Go
#203Earlier quoted context omitted.
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…
> 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
#204Earlier quoted context omitted.
That’s certainly how I interpreted it. It never occurred to me to think it meant “thread handles” specifically.
I meant it more in that "first-class" tends to mean "this is a thing that is represented in the language / type system". Go has first-class functions, because you can make a `var fn func() string` field/variable/argument/etc that holds a reference to a func that returns a string. Go does not have first-class types, because you can't reference or store a type directly. You can use reflection to pass a reflected thing…
AIUI Rust's async/await still has quite a lot of special case support. IMO concurrency is only really first-class in languages like Haskell where you can manipulate async actions the same way as a user-defined type and implement concurrency-related operations in plain old code.
Re: Data Race Patterns in Go
#205Earlier quoted context omitted.
> 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.
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.