diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2018-06-22 11:00:13 +0200 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2018-06-22 14:43:09 +0000 |
commit | f451a318bbc8f8cc6afb5a6d2dcb2234924b6271 (patch) | |
tree | 2a8b8567f3ab7f67bbe5a37febbdc47168122667 /src/sync | |
parent | 00eac8921e04c07df2d25df33b9401226f5d0326 (diff) | |
download | go-f451a318bbc8f8cc6afb5a6d2dcb2234924b6271.tar.gz go-f451a318bbc8f8cc6afb5a6d2dcb2234924b6271.zip |
sync: fix deficiency in RWMutex race annotations
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>
Diffstat (limited to 'src/sync')
-rw-r--r-- | src/sync/rwmutex.go | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/src/sync/rwmutex.go b/src/sync/rwmutex.go index 9dbebfeed7..16a2f9227c 100644 --- a/src/sync/rwmutex.go +++ b/src/sync/rwmutex.go @@ -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() } |