On 11/22/2017 12:40 AM, Arnaldo Carvalho de Melo wrote:
Em Mon, Nov 06, 2017 at 08:21:07PM +0800, Jin Yao escreveu:
In perf record, it's walked on all samples yet. So it's very easy to get

"In the default 'perf record' configuration, all samples are processed,
to create the HEADER_BUILD_ID table. So..."

the first/last samples and save the time to perf file header via the
function write_sample_time().

In later, perf report/script will fetch the time from perf file header.

   Later, at post processing time, ...


Thanks Arnaldo! The update on patch description is good.


Change log:
-----------
v6: Currently '--buildid-all' is not enabled at default. So the walking

                 --no-buildid-all, right?


No, it is '--buildid-all'. There is no '--no-buildid-all' available now.

See in __record_options[] (builtin-record.c),

        OPT_BOOLEAN(0, "buildid-all", &record.buildid_all,
                "Record build-id of all DSOs regardless of hits"),

So by default, buildid-all is set with false.

Thanks
Jin Yao

     on all samples is the default operation. There is no big overhead
     to calculate the timestamp boundary in process_sample_event handler
     once we already go through all samples. So the timestamp boundary
     calculation is enabled by default when '--buildid-all' is not enabled.

     While if '--buildid-all' is enabled, we creates a new option
     "--timestamp-boundary" for user to decide if it enables the
     timestamp boundary calculation.

v5: There is an issue that the sample walking can only work when
     '--buildid-all' is not enabled. So we need to let the walking
     be able to work even if '--buildid-all' is enabled and let the
     processing skips the dso hit marking for this case.

     At first, I want to provide a new option "--record-time-boundaries".
     While after consideration, I think a new option is not very
     necessary.

v3: Remove the definitions of first_sample_time and last_sample_time
     from struct record and directly save them in perf_evlist.

Signed-off-by: Jin Yao <[email protected]>
---
  tools/perf/Documentation/perf-record.txt |  3 +++
  tools/perf/builtin-record.c              | 18 +++++++++++++++---
  2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt 
b/tools/perf/Documentation/perf-record.txt
index 5a626ef..3eea6de 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -430,6 +430,9 @@ Configure all used events to run in user space.
  --timestamp-filename
  Append timestamp to output file name.
+--timestamp-boundary::
+Record timestamp boundary (time of first/last samples).
+
  --switch-output[=mode]::
  Generate multiple perf.data files, timestamp prefixed, switching to a new one
  based on 'mode' value:
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f4d9fc5..082a0cb 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -78,6 +78,7 @@ struct record {
        bool                    no_buildid_cache_set;
        bool                    buildid_all;
        bool                    timestamp_filename;
+       bool                    timestamp_boundary;
        struct switch_output    switch_output;
        unsigned long long      samples;
  };
@@ -391,8 +392,15 @@ static int process_sample_event(struct perf_tool *tool,
  {
        struct record *rec = container_of(tool, struct record, tool);
- rec->samples++;
+       if (rec->evlist->first_sample_time == 0)
+               rec->evlist->first_sample_time = sample->time;
+
+       rec->evlist->last_sample_time = sample->time;
+ if (rec->buildid_all)
+               return 0;
+
+       rec->samples++;
        return build_id__mark_dso_hit(tool, event, sample, evsel, machine);
  }
@@ -417,9 +425,11 @@ static int process_buildids(struct record *rec) /*
         * If --buildid-all is given, it marks all DSO regardless of hits,
-        * so no need to process samples.
+        * so no need to process samples. But if timestamp_boundary is enabled,
+        * it still needs to walk on all samples to get the timestamps of
+        * first/last samples.
         */
-       if (rec->buildid_all)
+       if (rec->buildid_all && !rec->timestamp_boundary)
                rec->tool.sample = NULL;
return perf_session__process_events(session);
@@ -1579,6 +1589,8 @@ static struct option __record_options[] = {
                    "Record build-id of all DSOs regardless of hits"),
        OPT_BOOLEAN(0, "timestamp-filename", &record.timestamp_filename,
                    "append timestamp to output filename"),
+       OPT_BOOLEAN(0, "timestamp-boundary", &record.timestamp_boundary,
+                   "Record timestamp boundary (time of first/last samples)"),
        OPT_STRING_OPTARG_SET(0, "switch-output", &record.switch_output.str,
                          &record.switch_output.set, "signal,size,time",
                          "Switch output when receive SIGUSR2 or cross size,time 
threshold",
--
2.7.4

Reply via email to