Commit ce884036 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent c88a6719
......@@ -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;
}
......
......@@ -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
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment