code: func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {
  	sampleData := contentionSampleRE.FindStringSubmatch(line)
  	if sampleData == nil {
  		return nil, nil, errUnrecognized
  	}
  
  	v1, err := strconv.ParseInt(sampleData[1], 10, 64)
  	if err != nil {
  		return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err)
  	}
  	v2, err := strconv.ParseInt(sampleData[2], 10, 64)
  	if err != nil {
  		return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err)
  	}
  
  	// Unsample values if period and cpuHz are available.
  	// - Delays are scaled to cycles and then to nanoseconds.
  	// - Contentions are scaled to cycles.
  	if period > 0 {
  		if cpuHz > 0 {
  			cpuGHz := float64(cpuHz) / 1e9
  			v1 = int64(float64(v1) * float64(period) / cpuGHz)
  		}
  		v2 = v2 * period
  	}
  
  	value = []int64{v2, v1}
  	addrs, err = parseHexAddresses(sampleData[3])
  	if err != nil {
  		return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err)
  	}
  
  	return value, addrs, nil
  }
docs: // parseContentionSample parses a single row from a contention profile
  // into a new Sample.