]> Cypherpunks repositories - gostls13.git/commitdiff
sync: fix deficiency in RWMutex race annotations
authorDmitry Vyukov <dvyukov@google.com>
Fri, 22 Jun 2018 09:00:13 +0000 (11:00 +0200)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 22 Jun 2018 14:43:09 +0000 (14:43 +0000)
Remove unnecessary race.Release annotation from Unlock.

For RWMutex we want to establish the following happens-before (HB) edges:
1. Between Unlock and the subsequent Lock.
2. Between Unlock and the subsequent RLock.
3. Between batch of RUnlock's and the subsequent Lock.

1 is provided by Release(&rw.readerSem) in Unlock and Acquire(&rw.readerSem) in Lock.
2 is provided by Release(&rw.readerSem) in Unlock and Acquire(&rw.readerSem) in RLock.
3 is provided by ReleaseMerge(&rw.writerSem) in RUnlock in Acquire(&rw.writerSem) in Lock,
since we want to establish HB between a batch of RUnlock's this uses ReleaseMerge instead of Release.

Release(&rw.writerSem) in Unlock is simply not needed.

FWIW this is also how C++ tsan handles mutexes, not a proof but at least something.
Making 2 implementations consistent also simplifies any kind of reasoning against both of them.

Since this only affects performance, a reasonable test is not possible.
Everything should just continue to work but slightly faster.

Credit for discovering this goes to Jamie Liu.

Change-Id: Ice37d29ecb7a5faed3f7781c38dd32c7469b2735
Reviewed-on: https://go-review.googlesource.com/120495
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/sync/rwmutex.go

index 9dbebfeed77e4eed3c35420c743e73da044234cb..16a2f9227c04249f4f2b47255ce62b57d478a8b4 100644 (file)
@@ -114,7 +114,6 @@ func (rw *RWMutex) Unlock() {
        if race.Enabled {
                _ = rw.w.state
                race.Release(unsafe.Pointer(&rw.readerSem))
-               race.Release(unsafe.Pointer(&rw.writerSem))
                race.Disable()
        }