diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
| -rw-r--r-- | tools/perf/util/evsel.c | 154 | 
1 files changed, 153 insertions, 1 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d7915d4e77c..667f3b78bb2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -63,6 +63,79 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)  	return evsel;  } +void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) +{ +	struct perf_event_attr *attr = &evsel->attr; +	int track = !evsel->idx; /* only the first counter needs these */ + +	attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0; +	attr->inherit	    = !opts->no_inherit; +	attr->read_format   = PERF_FORMAT_TOTAL_TIME_ENABLED | +			      PERF_FORMAT_TOTAL_TIME_RUNNING | +			      PERF_FORMAT_ID; + +	attr->sample_type  |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; + +	/* +	 * We default some events to a 1 default interval. But keep +	 * it a weak assumption overridable by the user. +	 */ +	if (!attr->sample_period || (opts->user_freq != UINT_MAX && +				     opts->user_interval != ULLONG_MAX)) { +		if (opts->freq) { +			attr->sample_type	|= PERF_SAMPLE_PERIOD; +			attr->freq		= 1; +			attr->sample_freq	= opts->freq; +		} else { +			attr->sample_period = opts->default_interval; +		} +	} + +	if (opts->no_samples) +		attr->sample_freq = 0; + +	if (opts->inherit_stat) +		attr->inherit_stat = 1; + +	if (opts->sample_address) { +		attr->sample_type	|= PERF_SAMPLE_ADDR; +		attr->mmap_data = track; +	} + +	if (opts->call_graph) +		attr->sample_type	|= PERF_SAMPLE_CALLCHAIN; + +	if (opts->system_wide) +		attr->sample_type	|= PERF_SAMPLE_CPU; + +	if (opts->period) +		attr->sample_type	|= PERF_SAMPLE_PERIOD; + +	if (opts->sample_id_all_avail && +	    (opts->sample_time || opts->system_wide || +	     !opts->no_inherit || opts->cpu_list)) +		attr->sample_type	|= PERF_SAMPLE_TIME; + +	if (opts->raw_samples) { +		attr->sample_type	|= PERF_SAMPLE_TIME; +		attr->sample_type	|= PERF_SAMPLE_RAW; +		attr->sample_type	|= PERF_SAMPLE_CPU; +	} + +	if (opts->no_delay) { +		attr->watermark = 0; +		attr->wakeup_events = 1; +	} + +	attr->mmap = track; +	attr->comm = track; + +	if (opts->target_pid == -1 && opts->target_tid == -1 && !opts->system_wide) { +		attr->disabled = 1; +		attr->enable_on_exec = 1; +	} +} +  int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)  {  	int cpu, thread; @@ -387,7 +460,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,  		u32 val32[2];  	} u; - +	memset(data, 0, sizeof(*data));  	data->cpu = data->pid = data->tid = -1;  	data->stream_id = data->id = data->time = -1ULL; @@ -504,3 +577,82 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,  	return 0;  } + +int perf_event__synthesize_sample(union perf_event *event, u64 type, +				  const struct perf_sample *sample, +				  bool swapped) +{ +	u64 *array; + +	/* +	 * used for cross-endian analysis. See git commit 65014ab3 +	 * for why this goofiness is needed. +	 */ +	union { +		u64 val64; +		u32 val32[2]; +	} u; + +	array = event->sample.array; + +	if (type & PERF_SAMPLE_IP) { +		event->ip.ip = sample->ip; +		array++; +	} + +	if (type & PERF_SAMPLE_TID) { +		u.val32[0] = sample->pid; +		u.val32[1] = sample->tid; +		if (swapped) { +			/* +			 * Inverse of what is done in perf_event__parse_sample +			 */ +			u.val32[0] = bswap_32(u.val32[0]); +			u.val32[1] = bswap_32(u.val32[1]); +			u.val64 = bswap_64(u.val64); +		} + +		*array = u.val64; +		array++; +	} + +	if (type & PERF_SAMPLE_TIME) { +		*array = sample->time; +		array++; +	} + +	if (type & PERF_SAMPLE_ADDR) { +		*array = sample->addr; +		array++; +	} + +	if (type & PERF_SAMPLE_ID) { +		*array = sample->id; +		array++; +	} + +	if (type & PERF_SAMPLE_STREAM_ID) { +		*array = sample->stream_id; +		array++; +	} + +	if (type & PERF_SAMPLE_CPU) { +		u.val32[0] = sample->cpu; +		if (swapped) { +			/* +			 * Inverse of what is done in perf_event__parse_sample +			 */ +			u.val32[0] = bswap_32(u.val32[0]); +			u.val64 = bswap_64(u.val64); +		} +		*array = u.val64; +		array++; +	} + +	if (type & PERF_SAMPLE_PERIOD) { +		*array = sample->period; +		array++; +	} + +	return 0; +}  |