From df68e01b6860e585033156e84f8f9716d2f41a28 Mon Sep 17 00:00:00 2001 From: Daniel S Fava Date: Fri, 20 Nov 2020 21:23:45 +0100 Subject: runtime: check channel's elemsize before calling race detector When c.elemsize==0 we call raceacquire() and racerelease() as opposed to calling racereleaseacquire() The reason for this change is that, when elemsize==0, we don't allocate a full buffer for the channel. Instead of individual buffer entries, the race detector uses the c.buf as the only buffer entry. This simplification prevents us following the memory model's happens-before rules implemented in racereleaseacquire(). So, instead of calling racereleaseacquire(), we accumulate happens-before information in the synchronization object associated with c.buf. The functionality in this change is implemented in a new function called racenotify() Fixes #42598 Change-Id: I75b92708633fdfde658dc52e06264e2171824e51 Reviewed-on: https://go-review.googlesource.com/c/go/+/271987 Reviewed-by: Dmitry Vyukov Reviewed-by: Russ Cox Run-TryBot: Dmitry Vyukov TryBot-Result: Go Bot Trust: Ian Lance Taylor --- src/runtime/race/testdata/chan_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/runtime/race/testdata/chan_test.go') diff --git a/src/runtime/race/testdata/chan_test.go b/src/runtime/race/testdata/chan_test.go index 3e57b8221c..e39ad4f99c 100644 --- a/src/runtime/race/testdata/chan_test.go +++ b/src/runtime/race/testdata/chan_test.go @@ -763,3 +763,25 @@ func TestNoRaceCloseHappensBeforeRead(t *testing.T) { <-read } } + +// Test that we call the proper race detector function when c.elemsize==0. +// See https://github.com/golang/go/issues/42598 +func TestNoRaceElemetSize0(t *testing.T) { + var x, y int + var c = make(chan struct{}, 2) + c <- struct{}{} + c <- struct{}{} + go func() { + x += 1 + <-c + }() + go func() { + y += 1 + <-c + }() + time.Sleep(10 * time.Millisecond) + c <- struct{}{} + c <- struct{}{} + x += 1 + y += 1 +} -- cgit v1.3