158 lines
5.2 KiB
C++
158 lines
5.2 KiB
C++
/*
|
|
* Copyright (C) 2018 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 ANDROID_MEDIA_NBLOG_MERGER_H
|
|
#define ANDROID_MEDIA_NBLOG_MERGER_H
|
|
|
|
#include <memory>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <vector>
|
|
|
|
#include <audio_utils/fifo.h>
|
|
#include <media/nblog/PerformanceAnalysis.h>
|
|
#include <media/nblog/Reader.h>
|
|
#include <utils/Condition.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/RefBase.h>
|
|
#include <utils/Thread.h>
|
|
#include <utils/Timers.h>
|
|
#include <utils/Vector.h>
|
|
|
|
namespace android {
|
|
|
|
class String16;
|
|
class String8;
|
|
|
|
namespace NBLog {
|
|
|
|
struct Shared;
|
|
|
|
// TODO update comments to reflect current functionalities
|
|
|
|
// This class is used to read data from each thread's individual FIFO in shared memory
|
|
// and write it to a single FIFO in local memory.
|
|
class Merger : public RefBase {
|
|
public:
|
|
Merger(const void *shared, size_t size);
|
|
|
|
~Merger() override = default;
|
|
|
|
void addReader(const sp<NBLog::Reader> &reader);
|
|
// TODO add removeReader
|
|
void merge();
|
|
|
|
// FIXME This is returning a reference to a shared variable that needs a lock
|
|
const std::vector<sp<Reader>>& getReaders() const;
|
|
|
|
private:
|
|
// vector of the readers the merger is supposed to merge from.
|
|
// every reader reads from a writer's buffer
|
|
// FIXME Needs to be protected by a lock
|
|
std::vector<sp<Reader>> mReaders;
|
|
|
|
Shared * const mShared; // raw pointer to shared memory
|
|
std::unique_ptr<audio_utils_fifo> mFifo; // FIFO itself
|
|
std::unique_ptr<audio_utils_fifo_writer> mFifoWriter; // used to write to FIFO
|
|
};
|
|
|
|
// This class has a pointer to the FIFO in local memory which stores the merged
|
|
// data collected by NBLog::Merger from all Readers. It is used to process
|
|
// this data and write the result to PerformanceAnalysis.
|
|
class MergeReader : public Reader {
|
|
public:
|
|
MergeReader(const void *shared, size_t size, Merger &merger);
|
|
|
|
// process a particular snapshot of the reader
|
|
void processSnapshot(Snapshot &snap, int author);
|
|
|
|
// call getSnapshot of the content of the reader's buffer and process the data
|
|
void getAndProcessSnapshot();
|
|
|
|
// check for periodic push of performance data to media metrics, and perform
|
|
// the send if it is time to do so.
|
|
void checkPushToMediaMetrics();
|
|
|
|
void dump(int fd, const Vector<String16>& args);
|
|
|
|
private:
|
|
// FIXME Needs to be protected by a lock,
|
|
// because even though our use of it is read-only there may be asynchronous updates
|
|
// The object is owned by the Merger class.
|
|
const std::vector<sp<Reader>>& mReaders;
|
|
|
|
// analyzes, compresses and stores the merged data
|
|
// contains a separate instance for every author (thread), and for every source file
|
|
// location within each author
|
|
ReportPerformance::PerformanceAnalysisMap mThreadPerformanceAnalysis;
|
|
|
|
// compresses and stores audio performance data from each thread's buffers.
|
|
// first parameter is author, i.e. thread index.
|
|
std::map<int, ReportPerformance::PerformanceData> mThreadPerformanceData;
|
|
|
|
// how often to push data to Media Metrics
|
|
static constexpr nsecs_t kPeriodicMediaMetricsPush = s2ns((nsecs_t)2 * 60 * 60); // 2 hours
|
|
|
|
// handle author entry by looking up the author's name and appending it to the body
|
|
// returns number of bytes read from fmtEntry
|
|
void handleAuthor(const AbstractEntry &fmtEntry, String8 *body);
|
|
};
|
|
|
|
// MergeThread is a thread that contains a Merger. It works as a retriggerable one-shot:
|
|
// when triggered, it awakes for a lapse of time, during which it periodically merges; if
|
|
// retriggered, the timeout is reset.
|
|
// The thread is triggered on AudioFlinger binder activity.
|
|
class MergeThread : public Thread {
|
|
public:
|
|
MergeThread(Merger &merger, MergeReader &mergeReader);
|
|
~MergeThread() override;
|
|
|
|
// Reset timeout and activate thread to merge periodically if it's idle
|
|
void wakeup();
|
|
|
|
// Set timeout period until the merging thread goes idle again
|
|
void setTimeoutUs(int time);
|
|
|
|
private:
|
|
bool threadLoop() override;
|
|
|
|
// the merger who actually does the work of merging the logs
|
|
Merger& mMerger;
|
|
|
|
// the mergereader used to process data merged by mMerger
|
|
MergeReader& mMergeReader;
|
|
|
|
// mutex for the condition variable
|
|
Mutex mMutex;
|
|
|
|
// condition variable to activate merging on timeout >= 0
|
|
Condition mCond;
|
|
|
|
// time left until the thread blocks again (in microseconds)
|
|
int mTimeoutUs;
|
|
|
|
// merging period when the thread is awake
|
|
static const int kThreadSleepPeriodUs = 1000000 /*1s*/;
|
|
|
|
// initial timeout value when triggered
|
|
static const int kThreadWakeupPeriodUs = 3000000 /*3s*/;
|
|
};
|
|
|
|
} // namespace NBLog
|
|
} // namespace android
|
|
|
|
#endif // ANDROID_MEDIA_NBLOG_MERGER_H
|