blob: ae871f11cb1ab9cfd07477a003a93584427a420a [file] [log] [blame]
/*
* Copyright 2020 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.
*/
#pragma once
#include <perfetto/tracing.h>
#include <mutex>
namespace perfetto::protos {
class TracePacket;
}
namespace android {
class GpuMem;
class GpuMemTracer {
public:
class GpuMemDataSource : public perfetto::DataSource<GpuMemDataSource> {
virtual void OnSetup(const SetupArgs&) override{};
virtual void OnStart(const StartArgs&) override {
std::unique_lock<std::mutex> lock(GpuMemTracer::sTraceMutex);
sTraceStarted = true;
sCondition.notify_all();
}
virtual void OnStop(const StopArgs&) override{};
};
~GpuMemTracer() = default;
// Sets up the perfetto tracing backend and data source.
void initialize(std::shared_ptr<GpuMem>);
// Registers the data source with the perfetto backend. Called as part of initialize()
// and should not be called manually outside of tests. Public to allow for substituting a
// perfetto::kInProcessBackend in tests.
void registerDataSource();
// TODO(b/175904796): Refactor gpuservice lib to include perfetto lib and move the test
// functions into the unittests.
// Functions only used for testing with in-process backend. These functions require the static
// perfetto lib to be linked. If the tests have a perfetto linked, while libgpumemtracer.so also
// has one linked, they will both use different static states maintained in perfetto. Since the
// static perfetto states are not shared, tracing sessions created in the unit test are not
// recognized by GpuMemTracer. As a result, we cannot use any of the perfetto functions from
// this class, which defeats the purpose of the unit test. To solve this, we restrict all
// tracing functionality to this class, while the unit test validates the data.
// Sets up the perfetto in-process backend and calls into registerDataSource.
void initializeForTest(std::shared_ptr<GpuMem>);
// Creates a tracing session with in process backend, for testing.
std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest();
// Read and filter the gpu memory packets from the created trace.
std::vector<perfetto::protos::TracePacket> readGpuMemTotalPacketsForTestBlocking(
perfetto::TracingSession* tracingSession);
static constexpr char kGpuMemDataSource[] = "android.gpu.memory";
static std::condition_variable sCondition;
static std::mutex sTraceMutex;
static bool sTraceStarted;
private:
// Friend class for testing
friend class GpuMemTracerTest;
void threadLoop(bool infiniteLoop);
void traceInitialCounters();
std::shared_ptr<GpuMem> mGpuMem;
// Count of how many tracer threads are currently active. Useful for testing.
std::atomic<int32_t> tracerThreadCount = 0;
};
} // namespace android