]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: adjust malloc race instrumentation for tiny allocs
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 28 Jan 2014 18:34:32 +0000 (22:34 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 28 Jan 2014 18:34:32 +0000 (22:34 +0400)
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
src/pkg/runtime/race/testdata/mop_test.go

index 4e554a1f92ca4b9a4a1ede0e695a0ecc75fc2ed3..3dfa63dbec4ea53917af6d765b538ebe4d544963 100644 (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;
 }
 
index b0b66562cccac738b364d4b2824cd0b291174eb3..14591b184517e80abd831628ff369aba9da02850 100644 (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
+       }
+}