From: Dmitriy Vyukov Date: Tue, 28 Jan 2014 18:34:32 +0000 (+0400) Subject: runtime: adjust malloc race instrumentation for tiny allocs X-Git-Tag: go1.3beta1~855 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ce884036d2199ebec22e4f9200789a532a1225d1;p=gostls13.git 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 --- 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 + } +}