10a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui/*
20a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * Copyright (C) 2017 The Android Open Source Project
30a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui *
40a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * Licensed under the Apache License, Version 2.0 (the "License");
50a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * you may not use this file except in compliance with the License.
60a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * You may obtain a copy of the License at
70a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui *
80a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui *      http://www.apache.org/licenses/LICENSE-2.0
90a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui *
100a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * Unless required by applicable law or agreed to in writing, software
110a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * distributed under the License is distributed on an "AS IS" BASIS,
120a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * See the License for the specific language governing permissions and
140a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui * limitations under the License.
150a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui */
160a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
170a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#ifndef _SIMPLEPERF_H
180a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#define _SIMPLEPERF_H
190a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
200a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#include <sys/types.h>
210a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
220a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#include <string>
230a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#include <vector>
240a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
250a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#ifndef SIMPLEPERF_EXPORT
260a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#define SIMPLEPERF_EXPORT
270a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#endif
280a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
290a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cuinamespace simpleperf {
300a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
310a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cuistd::vector<std::string> GetAllEvents() SIMPLEPERF_EXPORT;
320a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cuibool IsEventSupported(const std::string& name) SIMPLEPERF_EXPORT;
330a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
340a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cuistruct Counter {
350a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  std::string event;
360a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  uint64_t value;
370a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // If there is not enough hardware counters, kernel will share counters between events.
380a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // time_enabled_in_ns is the period when counting is enabled, and time_running_in_ns is
390a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // the period when counting really happens in hardware.
400a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  uint64_t time_enabled_in_ns;
410a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  uint64_t time_running_in_ns;
420a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui};
430a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
440a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui// PerfEventSet can be used to count perf events or record perf events in perf.data.
450a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui// To count perf events, you can do as follows:
460a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//  1. Create PerfEventSet instance.
470a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//  2. Select perf events to count. You can add more than one events.
480a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//  3. Set monitored targets.
490a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//  4. Start/stop/read counters when needed.
500a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui// An example is as below:
510a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    PerfEventSet* perf = PerfEventSet::CreateInstance(PerfEventSetType::kPerfForCounting);
520a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->AddEvent("cpu-cycles");
530a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->AddEvent("instructions");
540a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->MonitorCurrentProcess();
550a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->StartCounters();
560a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->StopCounters();
570a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//    perf->ReadCounters(&counters);
580a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui//
590a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui// PerfEventSet is not thread-safe. To access it from different threads, please protect
600a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui// it under locks.
610a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cuiclass SIMPLEPERF_EXPORT PerfEventSet {
620a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui public:
630a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  enum Type {
640a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui    kPerfForCounting,
650a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui    kPerfForRecording,
660a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  };
670a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
680a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  static PerfEventSet* CreateInstance(Type type);
690a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual ~PerfEventSet() {}
700a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
710a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Add event in the set. All valid events are returned by GetAllEvents().
720a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // To only monitor events happen in user space, add :u suffix, like cpu-cycles:u.
730a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool AddEvent(const std::string& name);
740a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
750a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Set monitored target. You can only monitor threads in current process.
760a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool MonitorCurrentProcess();
770a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool MonitorCurrentThread();
780a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool MonitorThreadsInCurrentProcess(const std::vector<pid_t>& threads);
790a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
800a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Counting interface:
810a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Start counters. When the PerfEventSet instance is created, the counters are stopped.
820a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool StartCounters();
830a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Stop counters. The values of the counters will not change until the next StartCounters().
840a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool StopCounters();
850a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // Read counter values. There is a value for each event. You don't need to stop counters before
860a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  // reading them. The counter values are the accumulated value from the first StartCounters().
870a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  virtual bool ReadCounters(std::vector<Counter>* counters);
880a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
890a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui protected:
900a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui  PerfEventSet() {}
910a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui};
920a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
930a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui}  // namespace simpleperf
940a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
950a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#undef SIMPLEPERF_EXPORT
960a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui
970a0d208795ac89a1c78bb921ea82a5d6d7919c88Yabin Cui#endif  // _SIMPLEPERF_H
98