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.

Reply via email to