|
@@ -592,6 +592,9 @@ static void record__init_features(struct record *rec)
|
|
if (!rec->opts.full_auxtrace)
|
|
if (!rec->opts.full_auxtrace)
|
|
perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
|
|
perf_header__clear_feat(&session->header, HEADER_AUXTRACE);
|
|
|
|
|
|
|
|
+ if (!(rec->opts.use_clockid && rec->opts.clockid_res_ns))
|
|
|
|
+ perf_header__clear_feat(&session->header, HEADER_CLOCKID);
|
|
|
|
+
|
|
perf_header__clear_feat(&session->header, HEADER_STAT);
|
|
perf_header__clear_feat(&session->header, HEADER_STAT);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -897,6 +900,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
|
|
|
|
|
|
record__init_features(rec);
|
|
record__init_features(rec);
|
|
|
|
|
|
|
|
+ if (rec->opts.use_clockid && rec->opts.clockid_res_ns)
|
|
|
|
+ session->header.env.clockid_res_ns = rec->opts.clockid_res_ns;
|
|
|
|
+
|
|
if (forks) {
|
|
if (forks) {
|
|
err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
|
|
err = perf_evlist__prepare_workload(rec->evlist, &opts->target,
|
|
argv, data->is_pipe,
|
|
argv, data->is_pipe,
|
|
@@ -1337,6 +1343,19 @@ static const struct clockid_map clockids[] = {
|
|
CLOCKID_END,
|
|
CLOCKID_END,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static int get_clockid_res(clockid_t clk_id, u64 *res_ns)
|
|
|
|
+{
|
|
|
|
+ struct timespec res;
|
|
|
|
+
|
|
|
|
+ *res_ns = 0;
|
|
|
|
+ if (!clock_getres(clk_id, &res))
|
|
|
|
+ *res_ns = res.tv_nsec + res.tv_sec * NSEC_PER_SEC;
|
|
|
|
+ else
|
|
|
|
+ pr_warning("WARNING: Failed to determine specified clock resolution.\n");
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int parse_clockid(const struct option *opt, const char *str, int unset)
|
|
static int parse_clockid(const struct option *opt, const char *str, int unset)
|
|
{
|
|
{
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
struct record_opts *opts = (struct record_opts *)opt->value;
|
|
@@ -1360,7 +1379,7 @@ static int parse_clockid(const struct option *opt, const char *str, int unset)
|
|
|
|
|
|
/* if its a number, we're done */
|
|
/* if its a number, we're done */
|
|
if (sscanf(str, "%d", &opts->clockid) == 1)
|
|
if (sscanf(str, "%d", &opts->clockid) == 1)
|
|
- return 0;
|
|
|
|
|
|
+ return get_clockid_res(opts->clockid, &opts->clockid_res_ns);
|
|
|
|
|
|
/* allow a "CLOCK_" prefix to the name */
|
|
/* allow a "CLOCK_" prefix to the name */
|
|
if (!strncasecmp(str, "CLOCK_", 6))
|
|
if (!strncasecmp(str, "CLOCK_", 6))
|
|
@@ -1369,7 +1388,8 @@ static int parse_clockid(const struct option *opt, const char *str, int unset)
|
|
for (cm = clockids; cm->name; cm++) {
|
|
for (cm = clockids; cm->name; cm++) {
|
|
if (!strcasecmp(str, cm->name)) {
|
|
if (!strcasecmp(str, cm->name)) {
|
|
opts->clockid = cm->clockid;
|
|
opts->clockid = cm->clockid;
|
|
- return 0;
|
|
|
|
|
|
+ return get_clockid_res(opts->clockid,
|
|
|
|
+ &opts->clockid_res_ns);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|