This is a well-known pattern (use an atomic counter to check if anyone else 
modified some data in a critical section and retry or fall back if it 
happened), but as the extensive Java docs imply, any such abstraction is 
going be fairly leaky. Java has a very thoroughly defined memory model that 
I suspect comes into play here to make the abstraction more usable (but 
don't quote me on that).

You *could* do a very close read of the Go memory model and try to do 
something similar but you end up pushing a lot of these subtleties onto the 
caller. This would also require //go:norace annotations on the caller to 
not fail in the race detector. Neither I nor the memory model docs 
recommend this.

The pattern is still useful and possible to apply in Go, however I have two 
suggestions:
1. Take the abstraction one level higher. Using the Java doc's Point 
example, what I mean is to only provide Point, not StampedLock. It's not 
too hard to implement a bespoke version of this sort of thing when you need 
it, and I find that doing these sorts of tricks benefits from breaking down 
the abstraction internally anyway, since it gives you more flexibility when 
adding new features.
2. Read and write the optimistically-read variables using the sync/atomic 
package. In the Point example from the Java docs, the optimistic read path 
would load x and y atomically (i.e. two separate Loads) and any write paths 
would store x and y atomically (i.e. two separate Stores). That's going to 
be far easier to reason about and more portable, though it might not 
achieve maximum performance on your hardware. If you're doing mostly 
optimistic reads (which I suspect is really when you'd want to consider 
this anyway), the optimistic reads themselves should scale just as well and 
you won't need to apply any //go:norace annotations. This suggestion is in 
the same vein as the "don't be clever" part of the memory model 
documentation.

On Friday, January 31, 2025 at 6:14:24 AM UTC-5 Robert Engels wrote:

> Hi,
>
> Do you think it is possible to implement a stamped lock in Go 
> https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/StampedLock.html
>  ?
>
> It would seem that the Go race detector would always report the 
> “optimistic read” mode as a data race?
>
> (The docs state for Java that the values can be wildly inconsistent when 
> the optimistic read fails).
>
> Ideas on how to implement in Go?
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/10e6c142-fbdb-4c8d-8270-a836ab4cecf8n%40googlegroups.com.

Reply via email to