memoryaccess(addr, 0, (uintptr)runtime·getcallerpc(&addr), true);
}
+// func RaceReadRange(addr unsafe.Pointer, len int)
+#pragma textflag 7
+void
+runtime·RaceReadRange(void *addr, intgo len)
+{
+ rangeaccess(addr, len, 1, 0, (uintptr)runtime·getcallerpc(&addr), false);
+}
+
+// func RaceWriteRange(addr unsafe.Pointer, len int)
+#pragma textflag 7
+void
+runtime·RaceWriteRange(void *addr, intgo len)
+{
+ rangeaccess(addr, len, 1, 0, (uintptr)runtime·getcallerpc(&addr), true);
+}
+
// func RaceDisable()
void
runtime·RaceDisable(void)
func RaceRead(addr unsafe.Pointer)
func RaceWrite(addr unsafe.Pointer)
+func RaceReadRange(addr unsafe.Pointer, len int)
+func RaceWriteRange(addr unsafe.Pointer, len int)
func RaceSemacquire(s *uint32)
func RaceSemrelease(s *uint32)
package race_test
import (
+ "crypto/sha1"
"errors"
"fmt"
+ "io"
+ "os"
"runtime"
"sync"
"testing"
y.x.y = 42
<-c
}
+
+func TestRaceIssue5567(t *testing.T) {
+ defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+ in := make(chan []byte)
+ res := make(chan error)
+ go func() {
+ var err error
+ defer func() {
+ close(in)
+ res <- err
+ }()
+ path := "mop_test.go"
+ f, err := os.Open(path)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+ var n, total int
+ b := make([]byte, 17) // the race is on b buffer
+ for err == nil {
+ n, err = f.Read(b)
+ total += n
+ if n > 0 {
+ in <- b[:n]
+ }
+ }
+ if err == io.EOF {
+ err = nil
+ }
+ }()
+ h := sha1.New()
+ for b := range in {
+ h.Write(b)
+ }
+ _ = h.Sum(nil)
+ err := <-res
+ if err != nil {
+ t.Fatal(err)
+ }
+}
func raceReleaseMerge(addr unsafe.Pointer) {
runtime.RaceReleaseMerge(addr)
}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+ runtime.RaceReadRange(addr, len)
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+ runtime.RaceWriteRange(addr, len)
+}
func raceReleaseMerge(addr unsafe.Pointer) {
}
+
+func raceReadRange(addr unsafe.Pointer, len int) {
+}
+
+func raceWriteRange(addr unsafe.Pointer, len int) {
+}
}
func Read(fd int, p []byte) (n int, err error) {
- n, err = Pread(fd, p, -1)
- if raceenabled && err == nil {
- raceAcquire(unsafe.Pointer(&ioSync))
- }
- return
+ return Pread(fd, p, -1)
}
func Write(fd int, p []byte) (n int, err error) {
- if raceenabled {
- raceReleaseMerge(unsafe.Pointer(&ioSync))
- }
return Pwrite(fd, p, -1)
}
func Read(fd int, p []byte) (n int, err error) {
n, err = read(fd, p)
- if raceenabled && err == nil {
- raceAcquire(unsafe.Pointer(&ioSync))
+ if raceenabled {
+ if n > 0 {
+ raceWriteRange(unsafe.Pointer(&p[0]), n)
+ }
+ if err == nil {
+ raceAcquire(unsafe.Pointer(&ioSync))
+ }
}
return
}
if raceenabled {
raceReleaseMerge(unsafe.Pointer(&ioSync))
}
- return write(fd, p)
+ n, err = write(fd, p)
+ if raceenabled && n > 0 {
+ raceReadRange(unsafe.Pointer(&p[0]), n)
+ }
+ return
}
func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
return 0, e
}
if raceenabled {
+ if done > 0 {
+ raceWriteRange(unsafe.Pointer(&p[0]), int(done))
+ }
raceAcquire(unsafe.Pointer(&ioSync))
}
return int(done), nil
if e != nil {
return 0, e
}
+ if raceenabled && done > 0 {
+ raceReadRange(unsafe.Pointer(&p[0]), int(done))
+ }
return int(done), nil
}