// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.tracelink;

using zx;

// The provider interface which applications must implement and register
// with the |TraceRegistry| to participate in tracing.
//
// See //zircon/system/ulib/trace-provider/ for a C++ implementation of
// this interface which can easily be configured by an application.
protocol Provider {
    // Starts writing trace records for events in the specified |categories|
    // into |buffer| using |fifo| for signaling.
    //
    // |buffering_mode| specifies what happens when the buffer fills.
    // ONESHOT: The provider must stop tracing.
    // CIRCULAR: Continue tracing, dropping oldest records to make room
    //   for new ones.
    // STREAMING: As the buffer fills notify TraceManager that it needs to be
    //   saved so that tracing can continue without dropping records. Whether
    //   records get dropped depends on how fast TraceManager is able to save
    //   intermediate buffers. No guarantee is made that records won't be
    //   dropped. Coordination of the saving of buffers is done via |fifo|.
    //   See trace-provider/provider.h for details.
    //
    // When the trace provider observes |ZX_FIFO_PEER_CLOSED| on |fifo|, it must
    // assume the trace manager has terminated abnormally (since |Stop| was
    // not received as usual) and stop tracing automatically, discarding
    // any in-flight trace data.
    //
    // At most one trace can be running at a time.  If the trace provider
    // receives a request to start tracing while already tracing, it must
    // ignore the request.
    //
    // There is no result. If the provider successfully starts it must send a
    // TRACE_PROVIDER_STARTED packet on |fifo|.
    // #include <trace-provider/provider.h> to get |TRACE_PROVIDER_STARTED|.
    // To indicate failure to start close |fifo|.
    Start(BufferingMode buffering_mode,
          handle<vmo> buffer, handle<fifo> fifo,
          vector<string:100>:100 categories);

    // Stops tracing.
    //
    // Once the provider has finished writing any final events to the trace
    // buffer, it must close both |buffer| and |fifo| to indicate to the trace
    // manager that tracing is finished.
    Stop();
};

// The service which trace providers use to register themselves with
// the tracing system.
// Note that one property of this interface is that once registration is made
// the provider can drop this connection.
[Discoverable, Layout = "Simple"]
protocol Registry {
    // Registers the trace provider.
    // Note: Registration is asynchronous, it's only at some point after this
    // returns that the provider is actually registered.
    // To unregister, simply close the TraceProvider pipe.
    RegisterTraceProviderDeprecated(Provider provider);

    // Registers the trace provider.
    // Note: Registration is asynchronous, it's only at some point after this
    // returns that the provider is actually registered.
    // To unregister, simply close the TraceProvider pipe.
    RegisterTraceProvider(Provider provider, zx.koid pid, string:100 name);

    // Registers the trace provider synchronously. The call doesn't return
    // until the provider is registered.
    // On return |s| is ZX_OK if registration was successful.
    // |started| is true if tracing has already started, which is a hint to
    // the provider to wait for the Start() message before continuing if it
    // wishes to not drop trace records before Start() is received.
    // To unregister, simply close the TraceProvider pipe.
    RegisterTraceProviderSynchronously(Provider provider, zx.koid pid, string:100 name) -> (zx.status s, bool started);
};

// The trace buffering mode.
enum BufferingMode : uint8 {
    // In oneshot mode there is only one buffer that is not reused. When the
    // buffer fills the provider just keeps dropping records, keeping a count,
    // and then when tracing stops the header is updated to record final state.
    ONESHOT = 0;

    // In circular mode, the buffer is effectively split into two pieces.
    // When a buffer fills writing immediately continues with the other
    // buffer, and this continues until tracing stops.
    CIRCULAR = 1;

    // In streaming mode, the buffer is effectively split into two pieces.
    // When a buffer fills the provider:
    // - TODO(dje): Say more here.
    // and then, when the buffer is saved, the manager:
    // - TODO(dje): Say more here.
    // If the manager hasn't saved the buffer in time, and the other buffer
    // fills, then the provider is required to keep dropping records until
    // the buffer is ready.
    STREAMING = 2;
};
