func benchmarkSyscall(b *testing.B, work, excess int) { const CallsPerSched = 1000 procs := runtime.GOMAXPROCS(-1) * excess N := int32(b.N / CallsPerSched) c := make(chan bool, procs) for p := 0; p < procs; p++ { go func() { foo := 42 for atomic.AddInt32(&N, -1) >= 0 { runtime.Gosched() for g := 0; g < CallsPerSched; g++ { runtime.Entersyscall() for i := 0; i < work; i++ { foo *= 2 foo /= 2 } runtime.Exitsyscall() } } c <- foo == 42 }() } for p := 0; p < procs; p++ { <-c } }
func TestFutexsleep(t *testing.T) { if runtime.GOMAXPROCS(0) > 1 { // futexsleep doesn't handle EINTR or other signals, // so spurious wakeups may happen. t.Skip("skipping; GOMAXPROCS>1") } start := time.Now() var wg sync.WaitGroup for i := range futexsleepTests { tt := &futexsleepTests[i] tt.mtx = 0 tt.ch = make(chan *futexsleepTest, 1) wg.Add(1) go func(tt *futexsleepTest) { runtime.Entersyscall(0) runtime.Futexsleep(&tt.mtx, 0, tt.ns) runtime.Exitsyscall(0) tt.ch <- tt wg.Done() }(tt) } loop: for { select { case tt := <-futexsleepTests[beforeY2038].ch: t.Errorf("futexsleep test %q finished early after %s", tt.msg, time.Since(start)) break loop case tt := <-futexsleepTests[afterY2038].ch: // Looks like FreeBSD 10 kernel has changed // the semantics of timedwait on userspace // mutex to make broken stuff look broken. switch { case runtime.GOOS == "freebsd" && runtime.GOARCH == "386": t.Log("freebsd/386 may not work correctly after the year 2038, see golang.org/issue/7194") default: t.Errorf("futexsleep test %q finished early after %s", tt.msg, time.Since(start)) break loop } case <-time.After(time.Second): break loop } } for i := range futexsleepTests { tt := &futexsleepTests[i] atomic.StoreUint32(&tt.mtx, 1) runtime.Futexwakeup(&tt.mtx, 1) } wg.Wait() }
func benchmarkSyscall(b *testing.B, work, excess int) { b.SetParallelism(excess) b.RunParallel(func(pb *testing.PB) { foo := 42 for pb.Next() { runtime.Entersyscall(0) for i := 0; i < work; i++ { foo *= 2 foo /= 2 } runtime.Exitsyscall(0) } _ = foo }) }
func BenchmarkSyscall(b *testing.B) { const CallsPerSched = 1000 procs := runtime.GOMAXPROCS(-1) N := int32(b.N / CallsPerSched) c := make(chan bool, procs) for p := 0; p < procs; p++ { go func() { for atomic.AddInt32(&N, -1) >= 0 { runtime.Gosched() for g := 0; g < CallsPerSched; g++ { runtime.Entersyscall() runtime.Exitsyscall() } } c <- true }() } for p := 0; p < procs; p++ { <-c } }