in sweet/benchmarks/internal/driver/driver.go [430:521]
func RunBenchmark(name string, f func(*B) error, opts ...RunOption) error {
// Create a B and populate it with options.
b := newB(name)
for _, opt := range opts {
opt(b)
}
// Start the RSS sampler and start the timer.
stop := b.startRSSSampler()
// Make sure profile file(s) are created if necessary.
for _, typ := range ProfileTypes {
if b.shouldProfile(typ) {
f, err := newProfileFile(typ, b.name)
if err != nil {
return err
}
b.profiles[typ] = f
}
}
b.StartTimer()
// Run the benchmark itself.
if err := f(b); err != nil {
return err
}
if b.TimerRunning() {
b.StopTimer()
}
// Stop the RSS sampler.
if stop != nil {
stop <- struct{}{}
}
if b.doPeakRSS {
v, err := ReadPeakRSS(b.pid)
if err != nil {
warningf("failed to read RSS peak: %v", err)
} else if v != 0 {
b.setStat(StatPeakRSS, v)
}
}
if b.doPeakVM {
v, err := ReadPeakVM(b.pid)
if err != nil {
warningf("failed to read VM peak: %v", err)
} else if v != 0 {
b.setStat(StatPeakVM, v)
}
}
if b.doTime {
if b.dur == 0 {
panic("timer never stopped")
} else if b.dur < 0 {
panic("negative duration encountered")
}
if b.ops == 0 {
panic("zero ops reported")
} else if b.ops < 0 {
panic("negative ops encountered")
}
b.setStat(StatTime, uint64(b.dur.Nanoseconds())/uint64(b.ops))
}
if b.doCoreDump && coreDumpDir != "" {
// Use gcore to dump the core of the benchmark process.
cmd := exec.Command(
"gcore", "-o", filepath.Join(coreDumpDir, name), strconv.Itoa(b.pid),
)
if out, err := cmd.CombinedOutput(); err != nil {
// Just print a warning; this isn't a fatal error.
warningf("failed to dump core: %v\n%s", err, string(out))
}
}
b.wg.Wait()
// Finalize all the profile files we're handling ourselves.
for typ, f := range b.profiles {
if typ == ProfileMem {
if err := pprof.Lookup("heap").WriteTo(f, 0); err != nil {
return err
}
}
f.Close()
}
// Report the results.
b.report()
return nil
}