180448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager/*
280448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * Copyright (C) 2017 The Android Open Source Project
380448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager *
480448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * Licensed under the Apache License, Version 2.0 (the "License");
580448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * you may not use this file except in compliance with the License.
680448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * You may obtain a copy of the License at
780448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager *
880448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager *      http://www.apache.org/licenses/LICENSE-2.0
980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager *
1080448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * Unless required by applicable law or agreed to in writing, software
1180448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * distributed under the License is distributed on an "AS IS" BASIS,
1280448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1380448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * See the License for the specific language governing permissions and
1480448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager * limitations under the License.
1580448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager */
1680448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
1780448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#define LOG_TAG "ReportPerformance"
1880448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
1980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <fstream>
2080448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <iostream>
2180448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <queue>
2280448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <stdarg.h>
2380448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <stdint.h>
2480448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <stdio.h>
2580448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <string.h>
2623f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager#include <sstream>
2780448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <sys/prctl.h>
282a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager#include <sys/time.h>
2980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <utility>
308589ce7045fd4f5520aabbc773f00c7136925fd7Glenn Kasten#include <media/nblog/NBLog.h>
318589ce7045fd4f5520aabbc773f00c7136925fd7Glenn Kasten#include <media/nblog/PerformanceAnalysis.h>
328589ce7045fd4f5520aabbc773f00c7136925fd7Glenn Kasten#include <media/nblog/ReportPerformance.h>
3380448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <utils/Log.h>
3480448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager#include <utils/String8.h>
3580448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
3680448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wagernamespace android {
3780448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
3880448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wagernamespace ReportPerformance {
3980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
40847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager
41847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager// TODO: use a function like this to extract logic from writeToFile
42847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager// https://stackoverflow.com/a/9279620
43847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager
442a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager// Writes outlier intervals, timestamps, and histograms spanning long time intervals to file.
452a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager// TODO: write data in binary format
46f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wagervoid writeToFile(const std::deque<std::pair<timestamp, Histogram>> &hists,
476ad40ee051e75ed3d986327e9967cf493047148dSanna Catherine de Treville Wager                 const std::deque<std::pair<msInterval, timestamp>> &outlierData,
48f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager                 const std::deque<timestamp> &peakTimestamps,
49f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager                 const char * directory, bool append, int author, log_hash_t hash) {
502a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager
512a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // TODO: remove old files, implement rotating files as in AudioFlinger.cpp
522a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager
532a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    if (outlierData.empty() && hists.empty() && peakTimestamps.empty()) {
5423f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager        ALOGW("No data, returning.");
5580448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager        return;
5680448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager    }
5780448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
5823f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    std::stringstream outlierName;
5923f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    std::stringstream histogramName;
60f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    std::stringstream peakName;
6123f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager
622a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // get current time
632a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    char currTime[16]; //YYYYMMDDHHMMSS + '\0' + one unused
642a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    struct timeval tv;
652a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    gettimeofday(&tv, NULL);
662a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    struct tm tm;
672a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    localtime_r(&tv.tv_sec, &tm);
682a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    strftime(currTime, sizeof(currTime), "%Y%m%d%H%M%S", &tm);
692a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager
702a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // generate file names
712a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    std::stringstream common;
722a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    common << author << "_" << hash << "_" << currTime << ".csv";
732a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager
742a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    histogramName << directory << "histograms_" << common.str();
752a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    outlierName << directory << "outliers_" << common.str();
762a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    peakName << directory << "peaks_" << common.str();
7723f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager
7823f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    std::ofstream hfs;
79f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    hfs.open(histogramName.str(), append ? std::ios::app : std::ios::trunc);
8023f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    if (!hfs.is_open()) {
8123f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager        ALOGW("couldn't open file %s", histogramName.str().c_str());
8223f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager        return;
8323f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    }
842a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // each histogram is written as a line where the first value is the timestamp and
852a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // subsequent values are pairs of buckets and counts. Each value is separated
862a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // by a comma, and each histogram is separated by a newline.
87847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager    for (auto hist = hists.begin(); hist != hists.end(); ++hist) {
88847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        hfs << hist->first << ", ";
89847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        for (auto bucket = hist->second.begin(); bucket != hist->second.end(); ++bucket) {
90847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager            hfs << bucket->first / static_cast<double>(kJiffyPerMs)
91847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager                << ", " << bucket->second;
92847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager            if (std::next(bucket) != end(hist->second)) {
93847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager                hfs << ", ";
94847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager            }
95847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        }
96847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        if (std::next(hist) != end(hists)) {
97847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager            hfs << "\n";
9880448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager        }
9980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager    }
10023f89d3469e5f4de4072bbd305e9552483abe723Sanna Catherine de Treville Wager    hfs.close();
101f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager
102f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    std::ofstream ofs;
103f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    ofs.open(outlierName.str(), append ? std::ios::app : std::ios::trunc);
104f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    if (!ofs.is_open()) {
105f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager        ALOGW("couldn't open file %s", outlierName.str().c_str());
106f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager        return;
107f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    }
1082a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // outliers are written as pairs separated by newlines, where each
1092a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // pair's values are separated by a comma
110f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    for (const auto &outlier : outlierData) {
1112a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager        ofs << outlier.first << ", " << outlier.second << "\n";
112f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    }
113f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    ofs.close();
114f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager
115f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    std::ofstream pfs;
116f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    pfs.open(peakName.str(), append ? std::ios::app : std::ios::trunc);
117f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    if (!pfs.is_open()) {
118f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager        ALOGW("couldn't open file %s", peakName.str().c_str());
119f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager        return;
120f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    }
1212a6a945d65c986dcc779f70f18afde1d7a74397bSanna Catherine de Treville Wager    // peaks are simply timestamps separated by commas
122847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager    for (auto peak = peakTimestamps.begin(); peak != peakTimestamps.end(); ++peak) {
123847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        pfs << *peak;
124847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        if (std::next(peak) != end(peakTimestamps)) {
125847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager            pfs << ", ";
126847b6e619a673375e72df857478aabca7275c674Sanna Catherine de Treville Wager        }
127f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    }
128f8c34284fcc9b5d64af3199c33cc1cec70a460e2Sanna Catherine de Treville Wager    pfs.close();
12980448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager}
13080448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
13180448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager} // namespace ReportPerformance
13280448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager
13380448085b6fa0dd9a78c4d7ca378d7ea5201595dSanna Catherine de Treville Wager}   // namespace android
134