/*
 * Copyright (C) 2021 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";

package perfetto.protos;

// Next id: 12
message PerfEvents {
  // What event to sample on, and how often. Commented from the perspective of
  // its use in |PerfEventConfig|.
  message Timebase {
    // How often the per-cpu sampling will occur. Not guaranteed to be honored
    // as the kernel can throttle the sampling rate if it's too high.
    // If unset, an implementation-defined default is used.
    oneof interval {
      // Per-cpu sampling frequency in Hz, as requested from the kernel. Not the
      // same as 1/period.
      // Details: the actual sampling will still be based on a period, but the
      // kernel will dynamically adjust it based on the observed event rate, to
      // approximate this frequency. Works best with steady-rate events like
      // timers.
      uint64 frequency = 2;

      // Per-cpu sampling will occur every |period| counts of |event|.
      // Prefer |frequency| by default, as it's easier to oversample with a
      // fixed period.
      uint64 period = 1;
    }

    // Counting event to use as a timebase for the sampling.
    // If unset, implies the CPU timer (SW_CPU_CLOCK) as the event,
    // which is what you usually want.
    // See common/perf_events.proto for the definitions.
    oneof event {
      Counter counter = 4;
      Tracepoint tracepoint = 3;
      RawEvent raw_event = 5;
    }

    // If set, samples will be timestamped with the given clock.
    // If unset, the clock is chosen by the implementation.
    // For software events, prefer PERF_CLOCK_BOOTTIME. However it cannot be
    // used for hardware events (due to interrupt safety), for which the
    // recommendation is to use one of the monotonic clocks.
    optional PerfClock timestamp_clock = 11;

    // Optional arbitrary name for the event, to identify it in the parsed
    // trace. Does *not* affect the profiling itself. If unset, the trace
    // parser will choose a suitable name.
    optional string name = 10;
  }

  // Builtin counter names from the uapi header. Commented with their perf tool
  // aliases.
  // TODO(rsavitski): consider generating enums for cache events (should be
  // finite), and generally make this list as extensive as possible. Excluding
  // things like dynamic PMUs since those don't fit into a static enum.
  // Next id: 21
  enum Counter {
    UNKNOWN_COUNTER = 0;

    // cpu-clock
    SW_CPU_CLOCK = 1;
    // page-faults, faults
    SW_PAGE_FAULTS = 2;
    // task-clock
    SW_TASK_CLOCK = 3;
    // context-switches, cs
    SW_CONTEXT_SWITCHES = 4;
    // cpu-migrations, migrations
    SW_CPU_MIGRATIONS = 5;
    // minor-faults
    SW_PAGE_FAULTS_MIN = 6;
    // major-faults
    SW_PAGE_FAULTS_MAJ = 7;
    // alignment-faults
    SW_ALIGNMENT_FAULTS = 8;
    // emulation-faults
    SW_EMULATION_FAULTS = 9;
    // dummy
    SW_DUMMY = 20;

    // cpu-cycles, cycles
    HW_CPU_CYCLES = 10;
    // instructions
    HW_INSTRUCTIONS = 11;
    // cache-references
    HW_CACHE_REFERENCES = 12;
    // cache-misses
    HW_CACHE_MISSES = 13;
    // branch-instructions, branches
    HW_BRANCH_INSTRUCTIONS = 14;
    // branch-misses
    HW_BRANCH_MISSES = 15;
    // bus-cycles
    HW_BUS_CYCLES = 16;
    // stalled-cycles-frontend, idle-cycles-frontend
    HW_STALLED_CYCLES_FRONTEND = 17;
    // stalled-cycles-backend, idle-cycles-backend
    HW_STALLED_CYCLES_BACKEND = 18;
    // ref-cycles
    HW_REF_CPU_CYCLES = 19;
  }

  message Tracepoint {
    // Group and name for the tracepoint, acceptable forms:
    // * "sched/sched_switch"
    // * "sched:sched_switch"
    optional string name = 1;

    // Optional field-level filter for the tracepoint. Only events matching this
    // filter will be counted (and therefore contribute to the sampling period).
    // Example: "prev_pid >= 42 && next_pid == 0".
    // For full syntax, see kernel documentation on "Event filtering":
    // https://www.kernel.org/doc/Documentation/trace/events.txt
    optional string filter = 2;
  }

  // Syscall-level description of the event, propagated to the perf_event_attr
  // struct. Primarily for local use-cases, since the event availability and
  // encoding is hardware-specific.
  message RawEvent {
    optional uint32 type = 1;
    optional uint64 config = 2;
    optional uint64 config1 = 3;
    optional uint64 config2 = 4;
  }

  // Subset of clocks that is supported by perf timestamping.
  // CLOCK_TAI is excluded since it's not expected to be used in practice, but
  // would require additions to the trace clock synchronisation logic.
  enum PerfClock {
    UNKNOWN_PERF_CLOCK = 0;
    PERF_CLOCK_REALTIME = 1;
    PERF_CLOCK_MONOTONIC = 2;
    PERF_CLOCK_MONOTONIC_RAW = 3;
    PERF_CLOCK_BOOTTIME = 4;
  }
}
