// writeBlock writes the current blocking profile to w. func writeBlock(w io.Writer, debug int) error { var p []runtime.BlockProfileRecord n, ok := runtime.BlockProfile(nil) for { p = make([]runtime.BlockProfileRecord, n+50) n, ok = runtime.BlockProfile(p) if ok { p = p[:n] break } } sort.Sort(byCycles(p)) b := bufio.NewWriter(w) var tw *tabwriter.Writer w = b if debug > 0 { tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0) w = tw } fmt.Fprintf(w, "--- contention:\n") fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond()) for i := range p { r := &p[i] fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count) for _, pc := range r.Stack() { fmt.Fprintf(w, " %#x", pc) } fmt.Fprint(w, "\n") if debug > 0 { printStackRecord(w, r.Stack(), true) } } if tw != nil { tw.Flush() } return b.Flush() }
// writeBlock writes the current blocking profile to w. func writeBlock(w io.Writer, debug int) error { var p []runtime.BlockProfileRecord n, ok := runtime.BlockProfile(nil) for { // Code by analogy with writeBlock func p = make([]runtime.BlockProfileRecord, n+50) n, ok = runtime.BlockProfile(p) if ok { p = p[:n] break } } sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles }) prof := &profile.Profile{ PeriodType: &profile.ValueType{Type: "contentions", Unit: "count"}, Period: 1, SampleType: []*profile.ValueType{ {Type: "contentions", Unit: "count"}, {Type: "delay", Unit: "nanoseconds"}, }, } cpuHz := runtime_cyclesPerSecond() locs := make(map[uint64]*profile.Location) for i := range p { r := &p[i] var v1, v2 int64 v1 = r.Cycles v2 = r.Count if prof.Period > 0 { if cpuHz > 0 { cpuGHz := float64(cpuHz) / 1e9 v1 = int64(float64(v1) * float64(prof.Period) / cpuGHz) } v2 = v2 * prof.Period } value := []int64{v2, v1} var sloc []*profile.Location for _, pc := range r.Stack() { addr := uint64(pc) addr-- loc := locs[addr] if locs[addr] == nil { loc = &profile.Location{ Address: addr, } prof.Location = append(prof.Location, loc) locs[addr] = loc } sloc = append(sloc, loc) } prof.Sample = append(prof.Sample, &profile.Sample{ Value: value, Location: sloc, }) } prof.RemapAll() protopprof.Symbolize(prof) return prof.Write(w) }
// countBlock returns the number of records in the blocking profile. func countBlock() int { n, _ := runtime.BlockProfile(nil) return n }