Support the -raw_data option used to dump raw_data
Dump the raw data required by the VTS-web dashboard to draw the
distribution diagram
Bug: 38252294
Test: Pixel phone, oc-dev, with
libhwbinder_latency -i 1000 -raw_data -pair 2
Change-Id: I3950635f46bf7be91a52e8a90e0959e11a90ab2b
diff --git a/vts/performance/Latency.cpp b/vts/performance/Latency.cpp
index 8104d06..d861e31 100644
--- a/vts/performance/Latency.cpp
+++ b/vts/performance/Latency.cpp
@@ -20,6 +20,7 @@
#include <fstream>
#include <iomanip>
#include <iostream>
+#include <list>
#include <string>
#include <tuple>
#include <vector>
@@ -53,7 +54,8 @@
string trace_path = "/sys/kernel/debug/tracing";
-// the default value
+// default arguments
+bool dump_raw_data = false;
int no_pair = 1;
int iterations = 100;
int verbose = 0;
@@ -179,8 +181,10 @@
uint64_t m_transactions = 0;
uint64_t m_total_time = 0;
uint64_t m_miss = 0;
- uint32_t m_buckets[num_buckets] = {0};
- bool tracing = false;
+ uint32_t m_buckets[num_buckets] = {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
public:
void setTrace(bool _tracing) { tracing = _tracing; }
@@ -199,10 +203,14 @@
ret.m_total_time = a.m_total_time + b.m_total_time;
return ret;
}
+ // add a new transaction latency record
void addTime(uint64_t nano) {
m_buckets[min(nano, max_time_bucket - 1) / time_per_bucket] += 1;
m_best = min(nano, m_best);
m_worst = max(nano, m_worst);
+ if (raw_dump) {
+ raw_data->push_back(nano);
+ }
m_transactions += 1;
m_total_time += nano;
if (missDeadline(nano)) m_miss++;
@@ -218,6 +226,28 @@
exit(1);
}
}
+ // setup raw dump
+ void setupRawData() {
+ raw_dump = true;
+ if (raw_data == nullptr)
+ raw_data = new list<uint64_t>;
+ else
+ raw_data->clear();
+ }
+ // dump and flush the raw data
+ void 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;
+ }
+ }
// dump average, best, worst latency in json
void dump() {
double best = (double)m_best / 1.0E6;
@@ -261,11 +291,6 @@
// statistics of a process pair
class PResults {
public:
- int no_inherent = 0;
- int no_sync = 0;
- class Results other, fifo;
- PResults() { fifo.setTrace(is_tracing); }
-
static PResults combine(const PResults& a, const PResults& b) {
PResults ret;
ret.no_inherent = a.no_inherent + b.no_inherent;
@@ -275,11 +300,22 @@
return ret;
}
- void dump(string name) {
+ int no_inherent = 0; ///< #transactions that does not inherit priority
+ int no_sync = 0; ///< #transactions that are not synced
+ Results other; ///< statistics of CFS-other transactions
+ Results fifo; ///< statistics of RT-fifo transactions
+ PResults() {
+ fifo.setTrace(is_tracing);
+ if (dump_raw_data) fifo.setupRawData();
+ }
+
+ // dump and flush the raw data
+ void flushRawData() { fifo.flushRawData(); }
+
+ void dump() {
int no_trans = other.getTransactions() + fifo.getTransactions();
double sync_ratio = (1.0 - (double)(no_sync) / no_trans);
- cout << "\"" << name << "\":{\"SYNC\":\""
- << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
+ cout << "{\"SYNC\":\"" << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
<< "\"S\":" << (no_trans - no_sync) << ",\"I\":" << no_trans << ","
<< "\"R\":" << sync_ratio << "," << endl;
cout << " \"other_ms\":";
@@ -418,6 +454,11 @@
// wait to send result
p.wait();
+ if (dump_raw_data) {
+ cout << "\"fifo_" + to_string(num) + "_data\": ";
+ presults.flushRawData();
+ }
+ cout.flush();
p.send(presults);
// wait for kill
@@ -459,6 +500,7 @@
cout << "-pair 4 # number of process pairs" << endl;
cout << "-deadline_us 2500 # deadline in us" << endl;
cout << "-v # debug" << endl;
+ cout << "-raw_data # dump raw data" << endl;
cout << "-trace # halt the trace on a dealine hit" << endl;
exit(0);
}
@@ -506,6 +548,9 @@
if (string(argv[i]) == "-v") {
verbose = 1;
}
+ if (string(argv[i]) == "-raw_data") {
+ dump_raw_data = true;
+ }
// The -trace argument is used like that:
//
// First start trace with atrace command as usual
@@ -558,15 +603,17 @@
waitAll(client_pipes);
// collect all results
- signalAll(client_pipes);
PResults total, presults[no_pair];
for (int i = 0; i < no_pair; i++) {
+ client_pipes[i].signal();
client_pipes[i].recv(presults[i]);
total = PResults::combine(total, presults[i]);
}
- total.dump("ALL");
+ cout << "\"ALL\":";
+ total.dump();
for (int i = 0; i < no_pair; i++) {
- presults[i].dump("P" + to_string(i));
+ cout << "\"P" << i << "\":";
+ presults[i].dump();
}
if (!pass_through) {