1
0
mirror of https://github.com/golang/go synced 2024-11-13 19:10:22 -07:00

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
This commit is contained in:
Dmitriy Vyukov 2014-01-28 22:34:32 +04:00
parent c88a671925
commit ce884036d2
2 changed files with 24 additions and 2 deletions

View File

@ -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;
}

View File

@ -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
}
}