aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/header.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/header.c')
-rw-r--r--tools/perf/util/header.c130
1 files changed, 128 insertions, 2 deletions
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7c0e9d587bfa..a326e0d8b5b6 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -15,9 +15,8 @@
15#include <linux/bitops.h> 15#include <linux/bitops.h>
16#include <linux/stringify.h> 16#include <linux/stringify.h>
17#include <sys/stat.h> 17#include <sys/stat.h>
18#include <sys/types.h>
19#include <sys/utsname.h> 18#include <sys/utsname.h>
20#include <unistd.h> 19#include <linux/time64.h>
21 20
22#include "evlist.h" 21#include "evlist.h"
23#include "evsel.h" 22#include "evsel.h"
@@ -37,6 +36,7 @@
37#include <api/fs/fs.h> 36#include <api/fs/fs.h>
38#include "asm/bug.h" 37#include "asm/bug.h"
39#include "tool.h" 38#include "tool.h"
39#include "time-utils.h"
40 40
41#include "sane_ctype.h" 41#include "sane_ctype.h"
42 42
@@ -1182,6 +1182,20 @@ static int write_stat(struct feat_fd *ff __maybe_unused,
1182 return 0; 1182 return 0;
1183} 1183}
1184 1184
1185static int write_sample_time(struct feat_fd *ff,
1186 struct perf_evlist *evlist)
1187{
1188 int ret;
1189
1190 ret = do_write(ff, &evlist->first_sample_time,
1191 sizeof(evlist->first_sample_time));
1192 if (ret < 0)
1193 return ret;
1194
1195 return do_write(ff, &evlist->last_sample_time,
1196 sizeof(evlist->last_sample_time));
1197}
1198
1185static void print_hostname(struct feat_fd *ff, FILE *fp) 1199static void print_hostname(struct feat_fd *ff, FILE *fp)
1186{ 1200{
1187 fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); 1201 fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
@@ -1507,6 +1521,28 @@ static void print_group_desc(struct feat_fd *ff, FILE *fp)
1507 } 1521 }
1508} 1522}
1509 1523
1524static void print_sample_time(struct feat_fd *ff, FILE *fp)
1525{
1526 struct perf_session *session;
1527 char time_buf[32];
1528 double d;
1529
1530 session = container_of(ff->ph, struct perf_session, header);
1531
1532 timestamp__scnprintf_usec(session->evlist->first_sample_time,
1533 time_buf, sizeof(time_buf));
1534 fprintf(fp, "# time of first sample : %s\n", time_buf);
1535
1536 timestamp__scnprintf_usec(session->evlist->last_sample_time,
1537 time_buf, sizeof(time_buf));
1538 fprintf(fp, "# time of last sample : %s\n", time_buf);
1539
1540 d = (double)(session->evlist->last_sample_time -
1541 session->evlist->first_sample_time) / NSEC_PER_MSEC;
1542
1543 fprintf(fp, "# sample duration : %10.3f ms\n", d);
1544}
1545
1510static int __event_process_build_id(struct build_id_event *bev, 1546static int __event_process_build_id(struct build_id_event *bev,
1511 char *filename, 1547 char *filename,
1512 struct perf_session *session) 1548 struct perf_session *session)
@@ -2148,6 +2184,27 @@ out_free_caches:
2148 return -1; 2184 return -1;
2149} 2185}
2150 2186
2187static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
2188{
2189 struct perf_session *session;
2190 u64 first_sample_time, last_sample_time;
2191 int ret;
2192
2193 session = container_of(ff->ph, struct perf_session, header);
2194
2195 ret = do_read_u64(ff, &first_sample_time);
2196 if (ret)
2197 return -1;
2198
2199 ret = do_read_u64(ff, &last_sample_time);
2200 if (ret)
2201 return -1;
2202
2203 session->evlist->first_sample_time = first_sample_time;
2204 session->evlist->last_sample_time = last_sample_time;
2205 return 0;
2206}
2207
2151struct feature_ops { 2208struct feature_ops {
2152 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); 2209 int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
2153 void (*print)(struct feat_fd *ff, FILE *fp); 2210 void (*print)(struct feat_fd *ff, FILE *fp);
@@ -2205,6 +2262,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
2205 FEAT_OPN(AUXTRACE, auxtrace, false), 2262 FEAT_OPN(AUXTRACE, auxtrace, false),
2206 FEAT_OPN(STAT, stat, false), 2263 FEAT_OPN(STAT, stat, false),
2207 FEAT_OPN(CACHE, cache, true), 2264 FEAT_OPN(CACHE, cache, true),
2265 FEAT_OPR(SAMPLE_TIME, sample_time, false),
2208}; 2266};
2209 2267
2210struct header_print_data { 2268struct header_print_data {
@@ -3258,6 +3316,74 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
3258 return err; 3316 return err;
3259} 3317}
3260 3318
3319static bool has_unit(struct perf_evsel *counter)
3320{
3321 return counter->unit && *counter->unit;
3322}
3323
3324static bool has_scale(struct perf_evsel *counter)
3325{
3326 return counter->scale != 1;
3327}
3328
3329int perf_event__synthesize_extra_attr(struct perf_tool *tool,
3330 struct perf_evlist *evsel_list,
3331 perf_event__handler_t process,
3332 bool is_pipe)
3333{
3334 struct perf_evsel *counter;
3335 int err;
3336
3337 /*
3338 * Synthesize other events stuff not carried within
3339 * attr event - unit, scale, name
3340 */
3341 evlist__for_each_entry(evsel_list, counter) {
3342 if (!counter->supported)
3343 continue;
3344
3345 /*
3346 * Synthesize unit and scale only if it's defined.
3347 */
3348 if (has_unit(counter)) {
3349 err = perf_event__synthesize_event_update_unit(tool, counter, process);
3350 if (err < 0) {
3351 pr_err("Couldn't synthesize evsel unit.\n");
3352 return err;
3353 }
3354 }
3355
3356 if (has_scale(counter)) {
3357 err = perf_event__synthesize_event_update_scale(tool, counter, process);
3358 if (err < 0) {
3359 pr_err("Couldn't synthesize evsel counter.\n");
3360 return err;
3361 }
3362 }
3363
3364 if (counter->own_cpus) {
3365 err = perf_event__synthesize_event_update_cpus(tool, counter, process);
3366 if (err < 0) {
3367 pr_err("Couldn't synthesize evsel cpus.\n");
3368 return err;
3369 }
3370 }
3371
3372 /*
3373 * Name is needed only for pipe output,
3374 * perf.data carries event names.
3375 */
3376 if (is_pipe) {
3377 err = perf_event__synthesize_event_update_name(tool, counter, process);
3378 if (err < 0) {
3379 pr_err("Couldn't synthesize evsel name.\n");
3380 return err;
3381 }
3382 }
3383 }
3384 return 0;
3385}
3386
3261int perf_event__process_attr(struct perf_tool *tool __maybe_unused, 3387int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
3262 union perf_event *event, 3388 union perf_event *event,
3263 struct perf_evlist **pevlist) 3389 struct perf_evlist **pevlist)