/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

import "protos/perfetto/trace/ftrace/ftrace_event.proto";

package perfetto.protos;

// The result of tracing one or more ftrace data pages from a single per-cpu
// kernel ring buffer. If collating multiple pages' worth of events, all of
// them come from contiguous pages, with no kernel data loss in between.
message FtraceEventBundle {
  optional uint32 cpu = 1;
  repeated FtraceEvent event = 2;

  // Set to true if there was data loss between the last time we've read from
  // the corresponding per-cpu kernel buffer, and the earliest event recorded
  // in this bundle.
  optional bool lost_events = 3;

  // Optionally-enabled compact encoding of a batch of scheduling events. Only
  // a subset of events & their fields is recorded.
  // All fields (except comms) are stored in a structure-of-arrays form, one
  // entry in each repeated field per event.
  message CompactSched {
    // Interned table of unique strings for this bundle.
    repeated string intern_table = 5;

    // Delta-encoded timestamps across all sched_switch events within this
    // bundle. The first is absolute, each next one is relative to its
    // predecessor.
    repeated uint64 switch_timestamp = 1 [packed = true];
    repeated int64 switch_prev_state = 2 [packed = true];
    repeated int32 switch_next_pid = 3 [packed = true];
    repeated int32 switch_next_prio = 4 [packed = true];
    // One per event, index into |intern_table| corresponding to the
    // next_comm field of the event.
    repeated uint32 switch_next_comm_index = 6 [packed = true];

    // Delta-encoded timestamps across all sched_waking events within this
    // bundle. The first is absolute, each next one is relative to its
    // predecessor.
    repeated uint64 waking_timestamp = 7 [packed = true];
    repeated int32 waking_pid = 8 [packed = true];
    repeated int32 waking_target_cpu = 9 [packed = true];
    repeated int32 waking_prio = 10 [packed = true];
    // One per event, index into |intern_table| corresponding to the
    // comm field of the event.
    repeated uint32 waking_comm_index = 11 [packed = true];
    repeated uint32 waking_common_flags = 12 [packed = true];
  }
  optional CompactSched compact_sched = 4;

  // traced_probes always sets the ftrace_clock to "boot". That is not available
  // in older kernels (v3.x). In that case we fallback on "global" or "local".
  // When we do that, we report the fallback clock in each bundle so we can do
  // proper clock syncing at parsing time in TraceProcessor. We cannot use the
  // TracePacket timestamp_clock_id because: (1) there is no per-packet
  // timestamp for ftrace bundles; (2) "global" does not match CLOCK_MONOTONIC.
  // Having a dedicated and explicit flag allows us to correct further misakes
  // in future by looking at the kernel version.
  // This field has been introduced in perfetto v19 / Android T (13).
  // This field is omitted when the ftrace clock is just "boot", as that is the
  // default assumption (and for consistency with the past).
  optional FtraceClock ftrace_clock = 5;

  // The timestamp according to the ftrace clock, taken at the same instant
  // as |boot_timestamp|. This is used to sync ftrace events when a non-boot
  // clock is used as the ftrace clock. We don't use the ClockSnapshot packet
  // because the ftrace global/local clocks don't match any of the clock_gettime
  // domains and can be only read by traced_probes.
  //
  // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
  //
  // Implementation note: Populated by reading the 'now ts:' field in
  // tracefs/per_cpu/cpuX/stat.
  optional int64 ftrace_timestamp = 6;

  // The timestamp according to CLOCK_BOOTTIME, taken at the same instant as
  // |ftrace_timestamp|. See documentation of |ftrace_timestamp| for
  // more info.
  //
  // Only set when |ftrace_clock| != FTRACE_CLOCK_UNSPECIFIED.
  optional int64 boot_timestamp = 7;
}

enum FtraceClock {
  // There is no FTRACE_CLOCK_BOOT entry as that's the default assumption. When
  // the ftrace clock is "boot", it's just omitted (so UNSPECIFIED == BOOT).
  FTRACE_CLOCK_UNSPECIFIED = 0;
  FTRACE_CLOCK_UNKNOWN = 1;
  FTRACE_CLOCK_GLOBAL = 2;
  FTRACE_CLOCK_LOCAL = 3;
  FTRACE_CLOCK_MONO_RAW = 4;
}
