upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
213
android/system/libhwbinder/vts/performance/PerfTest.cpp
Normal file
213
android/system/libhwbinder/vts/performance/PerfTest.cpp
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "PerfTest.h"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifdef ASSERT
|
||||
#undef ASSERT
|
||||
#endif
|
||||
#define ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
cerr << __func__ << ":" << __LINE__ << " condition:" << #cond << " failed\n" << endl; \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// the ratio that the service is synced on the same cpu beyond
|
||||
// GOOD_SYNC_MIN is considered as good
|
||||
#define GOOD_SYNC_MIN (0.6)
|
||||
|
||||
// the precision used for cout to dump float
|
||||
#define DUMP_PRICISION 2
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::left;
|
||||
using std::ios;
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::to_string;
|
||||
using std::setprecision;
|
||||
using std::setw;
|
||||
using std::ofstream;
|
||||
using std::make_tuple;
|
||||
|
||||
tuple<Pipe, Pipe> Pipe::createPipePair() {
|
||||
int a[2];
|
||||
int b[2];
|
||||
|
||||
int error1 = pipe(a);
|
||||
int error2 = pipe(b);
|
||||
ASSERT(error1 >= 0);
|
||||
ASSERT(error2 >= 0);
|
||||
|
||||
return make_tuple(Pipe(a[0], b[1]), Pipe(b[0], a[1]));
|
||||
}
|
||||
|
||||
Pipe::Pipe(Pipe&& rval) noexcept {
|
||||
fd_read_ = rval.fd_read_;
|
||||
fd_write_ = rval.fd_write_;
|
||||
rval.fd_read_ = 0;
|
||||
rval.fd_write_ = 0;
|
||||
}
|
||||
|
||||
Pipe::~Pipe() {
|
||||
if (fd_read_) {
|
||||
close(fd_read_);
|
||||
}
|
||||
if (fd_write_) {
|
||||
close(fd_write_);
|
||||
}
|
||||
}
|
||||
|
||||
Results Results::combine(const Results& a, const Results& b) {
|
||||
Results ret;
|
||||
for (uint32_t i = 0; i < kNumBuckets; i++) {
|
||||
ret.buckets_[i] = a.buckets_[i] + b.buckets_[i];
|
||||
}
|
||||
ret.worst_ = max(a.worst_, b.worst_);
|
||||
ret.best_ = min(a.best_, b.best_);
|
||||
ret.transactions_ = a.transactions_ + b.transactions_;
|
||||
ret.miss_ = a.miss_ + b.miss_;
|
||||
ret.total_time_ = a.total_time_ + b.total_time_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void traceStop() {
|
||||
ofstream file;
|
||||
file.open(TRACE_PATH "/tracing_on", ios::out | ios::trunc);
|
||||
file << '0' << endl;
|
||||
file.close();
|
||||
}
|
||||
|
||||
void Results::addTime(uint64_t nano) {
|
||||
buckets_[min(nano, kMaxTimeBucket - 1) / kTimePerBucket] += 1;
|
||||
best_ = min(nano, best_);
|
||||
worst_ = max(nano, worst_);
|
||||
if (raw_dump_) {
|
||||
raw_data_->push_back(nano);
|
||||
}
|
||||
transactions_ += 1;
|
||||
total_time_ += nano;
|
||||
if (missDeadline(nano)) {
|
||||
miss_++;
|
||||
if (tracing_) {
|
||||
// There might be multiple process pair running the test concurrently
|
||||
// each may execute following statements and only the first one actually
|
||||
// stop the trace and any traceStop() after then has no effect.
|
||||
traceStop();
|
||||
cerr << endl;
|
||||
cerr << "deadline triggered: halt & stop trace" << endl;
|
||||
cerr << "log:" TRACE_PATH "/trace" << endl;
|
||||
cerr << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Results::setupRawData() {
|
||||
raw_dump_ = true;
|
||||
if (raw_data_ == nullptr) {
|
||||
raw_data_ = new list<uint64_t>;
|
||||
} else {
|
||||
raw_data_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Results::flushRawData() {
|
||||
if (raw_dump_) {
|
||||
bool first = true;
|
||||
cout << "[";
|
||||
for (auto nano : *raw_data_) {
|
||||
cout << (first ? "" : ",") << to_string(nano);
|
||||
first = false;
|
||||
}
|
||||
cout << "]," << endl;
|
||||
delete raw_data_;
|
||||
raw_data_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Results::dump() const {
|
||||
double best = (double)best_ / 1.0E6;
|
||||
double worst = (double)worst_ / 1.0E6;
|
||||
double average = (double)total_time_ / transactions_ / 1.0E6;
|
||||
int W = DUMP_PRICISION + 2;
|
||||
cout << std::setprecision(DUMP_PRICISION) << "{ \"avg\":" << setw(W) << left << average
|
||||
<< ", \"wst\":" << setw(W) << left << worst << ", \"bst\":" << setw(W) << left << best
|
||||
<< ", \"miss\":" << left << miss_ << ", \"meetR\":" << setprecision(DUMP_PRICISION + 3)
|
||||
<< left << (1.0 - (double)miss_ / transactions_) << "}";
|
||||
}
|
||||
|
||||
void Results::dumpDistribution() const {
|
||||
uint64_t cur_total = 0;
|
||||
cout << "{ ";
|
||||
cout << std::setprecision(DUMP_PRICISION + 3);
|
||||
for (uint32_t i = 0; i < kNumBuckets; i++) {
|
||||
float cur_time = kTimePerBucketMS * i + 0.5f * kTimePerBucketMS;
|
||||
float accumulation = cur_total + buckets_[i];
|
||||
if ((cur_total < 0.5f * transactions_) && (accumulation >= 0.5f * transactions_)) {
|
||||
cout << "\"p50\":" << cur_time << ", ";
|
||||
}
|
||||
if ((cur_total < 0.9f * transactions_) && (accumulation >= 0.9f * transactions_)) {
|
||||
cout << "\"p90\":" << cur_time << ", ";
|
||||
}
|
||||
if ((cur_total < 0.95f * transactions_) && (accumulation >= 0.95f * transactions_)) {
|
||||
cout << "\"p95\":" << cur_time << ", ";
|
||||
}
|
||||
if ((cur_total < 0.99f * transactions_) && (accumulation >= 0.99f * transactions_)) {
|
||||
cout << "\"p99\": " << cur_time;
|
||||
}
|
||||
cur_total += buckets_[i];
|
||||
}
|
||||
cout << "}";
|
||||
}
|
||||
|
||||
PResults PResults::combine(const PResults& a, const PResults& b) {
|
||||
PResults ret;
|
||||
ret.nNotInherent = a.nNotInherent + b.nNotInherent;
|
||||
ret.nNotSync = a.nNotSync + b.nNotSync;
|
||||
ret.other = Results::combine(a.other, b.other);
|
||||
ret.fifo = Results::combine(a.fifo, b.fifo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PResults::dump() const {
|
||||
int no_trans = other.getTransactions() + fifo.getTransactions();
|
||||
double sync_ratio = (1.0 - (double)nNotSync / no_trans);
|
||||
cout << "{\"SYNC\":\"" << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
|
||||
<< "\"S\":" << (no_trans - nNotSync) << ",\"I\":" << no_trans << ","
|
||||
<< "\"R\":" << sync_ratio << "," << endl;
|
||||
cout << " \"other_ms\":";
|
||||
other.dump();
|
||||
cout << "," << endl;
|
||||
cout << " \"fifo_ms\": ";
|
||||
fifo.dump();
|
||||
cout << "," << endl;
|
||||
cout << " \"otherdis\":";
|
||||
other.dumpDistribution();
|
||||
cout << "," << endl;
|
||||
cout << " \"fifodis\": ";
|
||||
fifo.dumpDistribution();
|
||||
cout << endl;
|
||||
cout << "}," << endl;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue