But the lock shouldn’t be necessary I don’t think? The atomic read provides a happens before relationship - which is why removing it didn’t change anything.
I am just surprised the race detector does not complain - given my knowledge of how the race detector works it seems it should. Thanks for writing all of the code - interesting problem. The stamped lock is super efficient for many readers, rare writers - without resorting to copy on write or mutexes. > On Jan 31, 2025, at 11:13 AM, Bruno Albuquerque <b...@gmail.com> wrote: > > I did not look at the java code (I went for the description on the link you > posted). > > The idea in TryOptimisticRead() is that the TryLock() helps avoiding > reordering/cache effects. Consider this: > > Reader 1 calls TryOptimisticRead() and reads the stamp (let's say it's 100). > > Writer acquires the write lock, increments data, and increments the stamp to > 101. > > Writer releases the write lock. > > Reader 1 proceeds to read the shared data. Crucially, due to memory > reordering or caching effects, it might still see the old value of data, even > though the writer has already updated it. > > Reader 1 calls Validate(100). The stamp is now 101, so Validate() returns > false. > > The second to last step is hypothetical and I did not test it. In fact, I > just removed the TryLock() and returned the result of Adduint32 directly and > the race detector still did not complain (not sure if the results are the > expected ones. More testing would be needed). In other words, this still > seems to work: > > func (sl *StampedLock) TryOptimisticRead() uint64 { > return atomic.LoadUint64(&sl.stamp) > } > > > On Fri, Jan 31, 2025 at 12:05 PM robert engels <reng...@ix.netcom.com > <mailto:reng...@ix.netcom.com>> wrote: >> Your code seems substantially different than the Java implementation. For >> instance, in your tryOptimisticRead(), you take a lock - the Java version >> has no locking in that method (on a volatile, aka atomic read) - although I >> am not sure why you are taking the lock. >> >> func (sl *StampedLock) TryOptimisticRead() uint64 { >> stamp := atomic.LoadUint64(&sl.stamp) >> if sl.mu.TryLock() { >> sl.mu.Unlock() >> return stamp >> } >> return stamp >> } >> >> // Java - state is a “volatile” integer >> >> public long tryOptimisticRead() { >> long s; >> return (((s = state) & WBIT) == 0L) ? (s & SBITS) : 0L; >> } >> >> >>> On Jan 31, 2025, at 10:51 AM, Bruno Albuquerque <b...@gmail.com >>> <mailto:b...@gmail.com>> wrote: >>> >>> Ops. There was a bug due to left over of me testing. Here is a fixed >>> version: >>> >>> https://go.dev/play/p/UuIWVlV0UTN >>> >>> Also, don't try to run in the playground as this runs forever (it could be >>> changed but I am lazy). >>> >>> -Bruno >>> >>> >>> On Fri, Jan 31, 2025 at 11:31 AM Bruno Albuquerque <b...@gmail.com >>> <mailto:b...@gmail.com>> wrote: >>>> This seemed expected to me but I went ahead and created a Go >>>> implementation (which might not be 100% correct so take it for what it >>>> will) and I was surprised that the race detector did not really complain >>>> about anything. >>>> >>>> https://go.dev/play/p/R1alMCc-xN9 >>>> >>>> -Bruno >>>> >>>> >>>> On Fri, Jan 31, 2025, 6:13 AM Robert Engels <reng...@ix.netcom.com >>>> <mailto:reng...@ix.netcom.com>> 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 >>>>> <mailto:golang-nuts+unsubscr...@googlegroups.com>. >>>>> To view this discussion visit >>>>> https://groups.google.com/d/msgid/golang-nuts/FBEB055A-2B84-4738-AE22-C22ABAC8C4A9%40ix.netcom.com >>>>> >>>>> <https://groups.google.com/d/msgid/golang-nuts/FBEB055A-2B84-4738-AE22-C22ABAC8C4A9%40ix.netcom.com?utm_medium=email&utm_source=footer>. >>> >>> >>> -- >>> 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 >>> <mailto:golang-nuts+unsubscr...@googlegroups.com>. >>> To view this discussion visit >>> https://groups.google.com/d/msgid/golang-nuts/CAEd86TwQ_HzVt_H3rA84PWb1jdt%2BJBjQoD2Pq4VPDCVbS7d1yg%40mail.gmail.com >>> >>> <https://groups.google.com/d/msgid/golang-nuts/CAEd86TwQ_HzVt_H3rA84PWb1jdt%2BJBjQoD2Pq4VPDCVbS7d1yg%40mail.gmail.com?utm_medium=email&utm_source=footer>. >> -- 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/CB5AE61A-2A9F-401B-804C-EF44DAD0D345%40ix.netcom.com.