Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39ec8d62 authored by Eric Tan's avatar Eric Tan
Browse files

audioflinger Threads.cpp: size() == 0 -> isEmpty().

Clean up PerformanceAnalysis.cpp reportPerformance code.

Test: build, dumpsys media.audio_flinger
Change-Id: I1e89b16872384e589b2060272daa3116184ec4d8
parent a2a19382
Loading
Loading
Loading
Loading
+3 −80
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <sys/prctl.h>
#include <time.h>
#include <new>
#include <audio_utils/LogPlot.h>
#include <audio_utils/roundup.h>
#include <media/nblog/NBLog.h>
#include <media/nblog/PerformanceAnalysis.h>
@@ -208,27 +209,6 @@ bool PerformanceAnalysis::detectAndStoreOutlier(const msInterval diffMs) {
    return isOutlier;
}

static int widthOf(int x) {
    int width = 0;
    if (x < 0) {
        width++;
        x = x == INT_MIN ? INT_MAX : -x;
    }
    // assert (x >= 0)
    do {
        ++width;
        x /= 10;
    } while (x > 0);
    return width;
}

// computes the column width required for a specific histogram value
inline int numberWidth(double number, int leftPadding) {
    // Added values account for whitespaces needed around numbers, and for the
    // dot and decimal digit not accounted for by widthOf
    return std::max(std::max(widthOf(static_cast<int>(number)) + 3, 2), leftPadding + 1);
}

// rounds value to precision based on log-distance from mean
__attribute__((no_sanitize("signed-integer-overflow")))
inline double logRound(double x, double mean) {
@@ -281,65 +261,8 @@ void PerformanceAnalysis::reportPerformance(String8 *body, int author, log_hash_
            static_cast<long long>(hash), static_cast<long long>(startingTs));
    static const char * const kLabel = "ms";

    auto it = buckets.begin();
    double maxDelta = it->first;
    int maxCount = it->second;
    // Compute maximum values
    while (++it != buckets.end()) {
        if (it->first > maxDelta) {
            maxDelta = it->first;
        }
        if (it->second > maxCount) {
            maxCount = it->second;
        }
    }
    int height = log2(maxCount) + 1; // maxCount > 0, safe to call log2
    const int leftPadding = widthOf(1 << height);
    const int bucketWidth = numberWidth(maxDelta, leftPadding);
    int scalingFactor = 1;
    // scale data if it exceeds maximum height
    if (height > maxHeight) {
        scalingFactor = (height + maxHeight) / maxHeight;
        height /= scalingFactor;
    }
    body->appendFormat("%s", title);
    // write histogram label line with bucket values
    body->appendFormat("\n%s", " ");
    body->appendFormat("%*s", leftPadding, " ");
    for (auto const &x : buckets) {
        const int colWidth = numberWidth(x.first, leftPadding);
        body->appendFormat("%*d", colWidth, x.second);
    }
    // write histogram ascii art
    // underscores and spaces length corresponds to maximum width of histogram
    static const int kLen = 200;
    static const std::string underscores(kLen, '_');
    static const std::string spaces(kLen, ' ');

    body->appendFormat("\n%s", " ");
    for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
        const int value = 1 << row;
        body->appendFormat("%.*s", leftPadding, spaces.c_str());
        for (auto const &x : buckets) {
            const int colWidth = numberWidth(x.first, leftPadding);
            body->appendFormat("%.*s%s", colWidth - 1,
                               spaces.c_str(), x.second < value ? " " : "|");
        }
        body->appendFormat("\n%s", " ");
    }
    // print x-axis
    const int columns = static_cast<int>(buckets.size());
    body->appendFormat("%*c", leftPadding, ' ');
    body->appendFormat("%.*s", (columns + 1) * bucketWidth, underscores.c_str());
    body->appendFormat("\n%s", " ");

    // write footer with bucket labels
    body->appendFormat("%*s", leftPadding, " ");
    for (auto const &x : buckets) {
        const int colWidth = numberWidth(x.first, leftPadding);
        body->appendFormat("%*.*f", colWidth, 1, x.first);
    }
    body->appendFormat("%.*s%s\n", bucketWidth, spaces.c_str(), kLabel);
    body->appendFormat("%s",
            audio_utils_plot_histogram(buckets, title, kLabel, maxHeight).c_str());

    // Now report glitches
    body->appendFormat("\ntime elapsed between glitches and glitch timestamps:\n");
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@

namespace android {

class String8;

namespace ReportPerformance {

class PerformanceAnalysis;
+0 −3
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@

namespace android {

// The String8 class is used by reportPerformance function
class String8;

namespace ReportPerformance {

constexpr int kMsPerSec = 1000;
+8 −8
Original line number Diff line number Diff line
@@ -3354,7 +3354,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()

                continue;
            }
            if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
            if ((mActiveTracks.isEmpty() && systemTime() > mStandbyTimeNs) ||
                                   isSuspended()) {
                // put audio hardware into standby after short delay
                if (shouldStandby_l()) {
@@ -3368,7 +3368,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                    mStandby = true;
                }

                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
                if (mActiveTracks.isEmpty() && mConfigEvents.isEmpty()) {
                    // we're about to wait, flush the binder command buffer
                    IPCThreadState::self()->flushCommands();

@@ -6649,7 +6649,7 @@ reacquire_wakelock:
            }

            // sleep if there are no active tracks to process
            if (activeTracks.size() == 0) {
            if (activeTracks.isEmpty()) {
                if (sleepUs == 0) {
                    sleepUs = kRecordThreadSleepUs;
                }
@@ -7443,7 +7443,7 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
    audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE;
    dprintf(fd, "  AudioStreamIn: %p flags %#x (%s)\n",
            input, flags, inputFlagsToString(flags).c_str());
    if (mActiveTracks.size() == 0) {
    if (mActiveTracks.isEmpty()) {
        dprintf(fd, "  No active record clients\n");
    }

@@ -7909,7 +7909,7 @@ sp<StreamHalInterface> AudioFlinger::RecordThread::stream() const
status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
{
    // only one chain per input thread
    if (mEffectChains.size() != 0) {
    if (!mEffectChains.isEmpty()) {
        ALOGW("addEffectChain_l() already one chain %p on thread %p", chain.get(), this);
        return INVALID_OPERATION;
    }
@@ -8245,7 +8245,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
    // abort if start is rejected by audio policy manager
    if (ret != NO_ERROR) {
        ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
        if (mActiveTracks.size() != 0) {
        if (!mActiveTracks.isEmpty()) {
            mLock.unlock();
            if (isOutput()) {
                AudioSystem::releaseOutput(portId);
@@ -8346,7 +8346,7 @@ status_t AudioFlinger::MmapThread::standby()
    if (mHalStream == 0) {
        return NO_INIT;
    }
    if (mActiveTracks.size() != 0) {
    if (!mActiveTracks.isEmpty()) {
        return INVALID_OPERATION;
    }
    mHalStream->standby();
@@ -8784,7 +8784,7 @@ void AudioFlinger::MmapThread::dumpInternals(int fd, const Vector<String16>& arg
    dprintf(fd, "  Attributes: content type %d usage %d source %d\n",
            mAttr.content_type, mAttr.usage, mAttr.source);
    dprintf(fd, "  Session: %d port Id: %d\n", mSessionId, mPortId);
    if (mActiveTracks.size() == 0) {
    if (mActiveTracks.isEmpty()) {
        dprintf(fd, "  No active clients\n");
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -555,6 +555,9 @@ protected:
                    size_t          size() const {
                        return mActiveTracks.size();
                    }
                    bool            isEmpty() const {
                        return mActiveTracks.isEmpty();
                    }
                    ssize_t         indexOf(const sp<T>& item) {
                        return mActiveTracks.indexOf(item);
                    }