upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
155
android/system/libhwbinder/vts/performance/PerfTest.h
Normal file
155
android/system/libhwbinder/vts/performance/PerfTest.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
#ifndef HWBINDER_PERF_TEST_H
|
||||
#define HWBINDER_PERF_TEST_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <chrono>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
|
||||
#define TRACE_PATH "/sys/kernel/debug/tracing"
|
||||
|
||||
using std::list;
|
||||
using std::tuple;
|
||||
|
||||
// Pipe is a object used for IPC between parent process and child process.
|
||||
// This IPC class is widely used in binder/hwbinder tests.
|
||||
// The common usage is the main process to create the Pipe and forks.
|
||||
// Both parent and child hold a object. Each recv() on one side requires
|
||||
// a send() on the other side to unblock.
|
||||
class Pipe {
|
||||
public:
|
||||
static tuple<Pipe, Pipe> createPipePair();
|
||||
Pipe(Pipe&& rval);
|
||||
~Pipe();
|
||||
inline void signal() {
|
||||
bool val = true;
|
||||
send(val);
|
||||
}
|
||||
inline void wait() {
|
||||
bool val = false;
|
||||
recv(val);
|
||||
}
|
||||
|
||||
// write a data struct
|
||||
template <typename T>
|
||||
int send(const T& v) {
|
||||
return write(fd_write_, &v, sizeof(T));
|
||||
}
|
||||
// read a data struct
|
||||
template <typename T>
|
||||
int recv(T& v) {
|
||||
return read(fd_read_, &v, sizeof(T));
|
||||
}
|
||||
|
||||
private:
|
||||
int fd_read_; // file descriptor to read
|
||||
int fd_write_; // file descriptor to write
|
||||
Pipe(int read_fd, int write_fd) : fd_read_{read_fd}, fd_write_{write_fd} {}
|
||||
Pipe(const Pipe&) = delete;
|
||||
Pipe& operator=(const Pipe&) = delete;
|
||||
Pipe& operator=(const Pipe&&) = delete;
|
||||
};
|
||||
|
||||
// statistics of latency
|
||||
// common usage:
|
||||
//
|
||||
// Results r;
|
||||
// Tick sta, end;
|
||||
// TICK_NOW(sta);
|
||||
// ... do something ...
|
||||
// TICK_NOW(end);
|
||||
// r.addTime(tickDiffNS(sta, end));
|
||||
//
|
||||
// r.dump();
|
||||
// r.dumpDistribution();
|
||||
//
|
||||
class Results {
|
||||
public:
|
||||
// enable the deadline miss detection which stops the trace recording after
|
||||
// a transaction latency > deadline_us_ is detected.
|
||||
void setTracingMode(bool tracing, uint64_t deadline_us) {
|
||||
tracing_ = tracing;
|
||||
deadline_us_ = deadline_us;
|
||||
}
|
||||
inline uint64_t getTransactions() const { return transactions_; }
|
||||
inline bool missDeadline(uint64_t nano) const { return nano > deadline_us_ * 1000; }
|
||||
// Combine two sets of latency data points and update the aggregation info.
|
||||
static Results combine(const Results& a, const Results& b);
|
||||
// add a new transaction latency record
|
||||
void addTime(uint64_t nano);
|
||||
// prepare for raw data recording, it may allocate resources which requires
|
||||
// a flushRawData() to release
|
||||
void setupRawData();
|
||||
// dump the raw data and release the resource
|
||||
void flushRawData();
|
||||
// dump average, best, worst latency in json
|
||||
void dump() const;
|
||||
// dump latency distribution in json
|
||||
void dumpDistribution() const;
|
||||
|
||||
private:
|
||||
static const uint32_t kNumBuckets = 128;
|
||||
static const uint64_t kMaxTimeBucket = 50ull * 1000000;
|
||||
static const uint64_t kTimePerBucket = kMaxTimeBucket / kNumBuckets;
|
||||
static constexpr float kTimePerBucketMS = kTimePerBucket / 1.0E6;
|
||||
uint64_t best_ = 0xffffffffffffffffULL; // best transaction latency in ns.
|
||||
uint64_t worst_ = 0; // worst transaction latency in ns.
|
||||
uint64_t transactions_ = 0; // number of transactions
|
||||
uint64_t total_time_ = 0; // total transaction time
|
||||
uint64_t miss_ = 0; // number of transactions whose latency > deadline
|
||||
uint32_t buckets_[kNumBuckets] = {0}; // statistics for the distribution
|
||||
list<uint64_t>* raw_data_ = nullptr; // list for raw-data
|
||||
bool tracing_ = false; // halt the trace log on a deadline miss
|
||||
bool raw_dump_ = false; // record the raw data for the dump after
|
||||
uint64_t deadline_us_ = 2500; // latency deadline in us.
|
||||
};
|
||||
|
||||
// statistics of a process pair
|
||||
class PResults {
|
||||
public:
|
||||
static PResults combine(const PResults& a, const PResults& b);
|
||||
int nNotInherent = 0; ///< #transactions that does not inherit priority
|
||||
int nNotSync = 0; ///< #transactions that are not synced
|
||||
Results other; ///< statistics of CFS-other transactions
|
||||
Results fifo; ///< statistics of RT-fifo transactions
|
||||
// dump and flush the raw data
|
||||
inline void flushRawData() { fifo.flushRawData(); }
|
||||
// dump in json
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
// Tick keeps timestamp
|
||||
typedef std::chrono::time_point<std::chrono::high_resolution_clock> Tick;
|
||||
|
||||
// get current timestamp as a Tick
|
||||
static inline Tick tickNow() {
|
||||
return std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
#define TICK_NOW(_tick) \
|
||||
do { \
|
||||
asm volatile("" ::: "memory"); \
|
||||
_tick = tickNow(); \
|
||||
asm volatile("" ::: "memory"); \
|
||||
} while (0)
|
||||
|
||||
// get nano seconds between sta & end
|
||||
static inline uint64_t tickDiffNS(Tick& sta, Tick& end) {
|
||||
return uint64_t(std::chrono::duration_cast<std::chrono::nanoseconds>(end - sta).count());
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue