|
33 | 33 | #include "strbuf.h" |
34 | 34 | #include "fncache.h" |
35 | 35 | #include "pmu-hybrid.h" |
| 36 | +#include "util/evsel_config.h" |
36 | 37 |
|
37 | 38 | struct perf_pmu perf_pmu__fake; |
38 | 39 |
|
@@ -1056,6 +1057,35 @@ bool evsel__is_aux_event(const struct evsel *evsel) |
1056 | 1057 | return pmu && pmu->auxtrace; |
1057 | 1058 | } |
1058 | 1059 |
|
| 1060 | +/* |
| 1061 | + * Set @config_name to @val as long as the user hasn't already set or cleared it |
| 1062 | + * by passing a config term on the command line. |
| 1063 | + * |
| 1064 | + * @val is the value to put into the bits specified by @config_name rather than |
| 1065 | + * the bit pattern. It is shifted into position by this function, so to set |
| 1066 | + * something to true, pass 1 for val rather than a pre shifted value. |
| 1067 | + */ |
| 1068 | +#define field_prep(_mask, _val) (((_val) << (ffsll(_mask) - 1)) & (_mask)) |
| 1069 | +void evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel, |
| 1070 | + const char *config_name, u64 val) |
| 1071 | +{ |
| 1072 | + u64 user_bits = 0, bits; |
| 1073 | + struct evsel_config_term *term = evsel__get_config_term(evsel, CFG_CHG); |
| 1074 | + |
| 1075 | + if (term) |
| 1076 | + user_bits = term->val.cfg_chg; |
| 1077 | + |
| 1078 | + bits = perf_pmu__format_bits(&pmu->format, config_name); |
| 1079 | + |
| 1080 | + /* Do nothing if the user changed the value */ |
| 1081 | + if (bits & user_bits) |
| 1082 | + return; |
| 1083 | + |
| 1084 | + /* Otherwise replace it */ |
| 1085 | + evsel->core.attr.config &= ~bits; |
| 1086 | + evsel->core.attr.config |= field_prep(bits, val); |
| 1087 | +} |
| 1088 | + |
1059 | 1089 | struct perf_pmu *perf_pmu__find(const char *name) |
1060 | 1090 | { |
1061 | 1091 | struct perf_pmu *pmu; |
|
0 commit comments