From ce884036d2199ebec22e4f9200789a532a1225d1 Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Tue, 28 Jan 2014 22:34:32 +0400 Subject: [PATCH] runtime: adjust malloc race instrumentation for tiny allocs Tiny alloc memory block is shared by different goroutines running on the same thread. We call racemalloc after enabling preemption in mallocgc, as the result another goroutine can act on not yet race-cleared tiny block. Call racemalloc before enabling preemption. Fixes #7224. LGTM=dave R=golang-codereviews, dave CC=golang-codereviews https://golang.org/cl/57730043 --- src/pkg/runtime/malloc.goc | 4 ++-- src/pkg/runtime/race/testdata/mop_test.go | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index 4e554a1f92..3dfa63dbec 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -182,6 +182,8 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) m->mallocing = 0; if(UseSpanType && !(flag & FlagNoScan) && typ != 0 && m->settype_bufsize == nelem(m->settype_buf)) runtime·settype_flush(m); + if(raceenabled) + runtime·racemalloc(v, size); m->locks--; if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; @@ -208,8 +210,6 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) if(!(flag & FlagNoInvokeGC) && mstats.heap_alloc >= mstats.next_gc) runtime·gc(0); - if(raceenabled) - runtime·racemalloc(v, size); return v; } diff --git a/src/pkg/runtime/race/testdata/mop_test.go b/src/pkg/runtime/race/testdata/mop_test.go index b0b66562cc..14591b1845 100644 --- a/src/pkg/runtime/race/testdata/mop_test.go +++ b/src/pkg/runtime/race/testdata/mop_test.go @@ -1933,3 +1933,25 @@ func TestRaceMethodThunk4(t *testing.T) { *(*int)(d.Base) = 42 <-done } + +func TestNoRaceTinyAlloc(t *testing.T) { + const P = 4 + const N = 1e6 + var tinySink *byte + done := make(chan bool) + for p := 0; p < P; p++ { + go func() { + for i := 0; i < N; i++ { + var b byte + if b != 0 { + tinySink = &b // make it heap allocated + } + b = 42 + } + done <- true + }() + } + for p := 0; p < P; p++ { + <-done + } +} -- 2.48.1