blob: 5aa0028aebcc176fcef8e99caca55bc9830aa936 [file] [log] [blame]
/*
* Copyright (C) 2019 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 INCLUDE_PERFETTO_TRACING_TRACING_H_
#define INCLUDE_PERFETTO_TRACING_TRACING_H_
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include "perfetto/base/export.h"
#include "perfetto/base/logging.h"
namespace perfetto {
class TracingBackend;
class Platform;
class TraceConfig;
class TracingSession; // Declared below.
enum BackendType : uint32_t {
kUnspecifiedBackend = 0,
// Connects to a previously-initialized perfetto tracing backend for
// in-process. If the in-process backend has not been previously initialized
// it will do so and create the tracing service on a dedicated thread.
kInProcessBackend = 1 << 0,
// Connects to the system tracing service (e.g. on Linux/Android/Mac uses a
// named UNIX socket).
kSystemBackend = 1 << 1,
// Used to provide a custom IPC transport to connect to the service.
// TracingInitArgs::custom_backend must be non-null and point to an
// indefinitely lived instance.
kCustomBackend = 1 << 2,
};
struct TracingInitArgs {
uint32_t backends = 0; // One or more BackendFlags.
TracingBackend* custom_backend = nullptr; // [Optional].
// [Optional] Platform implementation. It allows the embedder to take control
// of platform-specific bits like thread creation and TLS slot handling. If
// not set it will use Platform::GetDefaultPlatform().
Platform* platform = nullptr;
// [Optional] Tune the size of the shared memory buffer between the current
// process and the service backend(s). This is a trade-off between memory
// footprint and the ability to sustain bursts of trace writes (see comments
// in shared_memory_abi.h).
// If set, the value must be a multiple of 4KB. The value can be ignored if
// larger than kMaxShmSize (32MB) or not a multiple of 4KB.
uint32_t shmem_size_hint_kb = 0;
// [Optional] Specifies the preferred size of each page in the shmem buffer.
// This is a trade-off between IPC overhead and fragmentation/efficiency of
// the shmem buffer in presence of multiple writer threads.
// Must be one of [4, 8, 16, 32].
uint32_t shmem_page_size_hint_kb = 0;
protected:
friend class Tracing;
bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
};
// The entry-point for using perfetto.
class PERFETTO_EXPORT Tracing {
public:
// Initializes Perfetto with the given backends in the calling process and/or
// with a user-provided backend. Can only be called once.
static void Initialize(const TracingInitArgs&);
// Start a new tracing session using the given tracing backend. Use
// |kUnspecifiedBackend| to select an available backend automatically.
// For the moment this can be used only when initializing tracing in
// kInProcess mode. For the system mode use the 'bin/perfetto' cmdline client.
static std::unique_ptr<TracingSession> NewTrace(
BackendType = kUnspecifiedBackend);
private:
Tracing() = delete;
};
class PERFETTO_EXPORT TracingSession {
public:
virtual ~TracingSession();
// Configure the session passing the trace config.
// If a writable file handle is given through |fd|, the trace will
// automatically written to that file. Otherwise you should call ReadTrace()
// to retrieve the trace data. This call does not take ownership of |fd|.
// TODO(primiano): add an error callback.
virtual void Setup(const TraceConfig&, int fd = -1) = 0;
// Enable tracing asynchronously.
virtual void Start() = 0;
// Enable tracing and block until tracing has started. Note that if data
// sources are registered after this call was initiated, the call may return
// before the additional data sources have started. Also, if other producers
// (e.g., with system-wide tracing) have registered data sources without start
// notification support, this call may return before those data sources have
// started.
virtual void StartBlocking() = 0;
// Disable tracing asynchronously.
// Use SetOnStopCallback() to get a notification when the tracing session is
// fully stopped and all data sources have acked.
virtual void Stop() = 0;
// Disable tracing and block until tracing has stopped.
virtual void StopBlocking() = 0;
// This callback will be invoked when tracing is disabled.
// This can happen either when explicitly calling TracingSession.Stop() or
// when the trace reaches its |duration_ms| time limit.
// This callback will be invoked on an internal perfetto thread.
virtual void SetOnStopCallback(std::function<void()>) = 0;
// Struct passed as argument to the callback passed to ReadTrace().
// [data, size] is guaranteed to contain 1 or more full trace packets, which
// can be decoded using trace.proto. No partial or truncated packets are
// exposed. If the trace is empty this returns a zero-sized nullptr with
// |has_more| == true to signal EOF.
// This callback will be invoked on an internal perfetto thread.
struct ReadTraceCallbackArgs {
const char* data = nullptr;
size_t size = 0;
// When false, this will be the last invocation of the callback for this
// read cycle.
bool has_more = false;
};
// Reads back the trace data (raw protobuf-encoded bytes) asynchronously.
// Can be called at any point during the trace, typically but not necessarily,
// after stopping. Reading the trace data is a destructive operation w.r.t.
// contents of the trace buffer and is not idempotent.
// A single ReadTrace() call can yield >1 callback invocations, until
// |has_more| is true.
using ReadTraceCallback = std::function<void(ReadTraceCallbackArgs)>;
virtual void ReadTrace(ReadTraceCallback) = 0;
// Synchronous version of ReadTrace(). It blocks the calling thread until all
// the trace contents are read. This is slow and inefficient (involves more
// copies) and is mainly intended for testing.
std::vector<char> ReadTraceBlocking();
};
} // namespace perfetto
#endif // INCLUDE_PERFETTO_TRACING_TRACING_H_