// Copyright 2017 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.

// Notes on buffering modes
// ------------------------
//
// Threads and strings are cached to improve performance and reduce buffer
// usage. The caching involves emitting separate records that identify
// threads/strings and then referring to them by a numeric id. For performance
// each thread in the application maintains its own cache.
//
// Oneshot: The trace buffer is just one large buffer, and records are written
// until the buffer is full after which all further records are dropped.
//
// Circular:
// The trace buffer is effectively divided into two pieces, and tracing begins
// by writing to the first piece. Once one buffer fills we start writing to the
// other one. This results in half the buffer being dropped at every switch,
// but simplifies things because we don't have to worry about varying record
// lengths.
//
// Streaming:
// The trace buffer is effectively divided into two pieces, and tracing begins
// by writing to the first piece. Once one buffer fills we start writing to the
// other buffer, if it is available, and notify the handler that the buffer is
// full. If the other buffer is not available, then records are dropped until
// it becomes available. The other buffer is unavailable between the point when
// it filled and when the handler reports back that the buffer's contents have
// been saved.
//
// There are two important properties we wish to preserve in circular and
// streaming modes:
// 1) We don't want records describing threads and strings to be dropped:
// otherwise records referring to them will have nothing to refer to.
// 2) We don't want thread records to be dropped at all: Fidelity of recording
// of all traced threads is important, even if some of their records are
// dropped.
// To implement both (1) and (2) we introduce a third buffer that holds
// records we don't want to drop called the "durable buffer". Threads and
// small strings are recorded there. The two buffers holding normal trace
// output are called "rolling buffers", as they fill we roll from one to the
// next. Thread and string records typically aren't very large, the durable
// buffer can hold a lot of records. To keep things simple, until there's a
// compelling reason to do something more, once the durable buffer fills
// tracing effectively stops, and all further records are dropped.
// Note: The term "rolling buffer" is intended to be internal to the trace
// engine/reader/manager and is not intended to appear in public APIs
// (at least not today). Externally, the two rolling buffers comprise the
// "nondurable" buffer.
//
// The protocol between the trace engine and the handler for saving buffers in
// streaming mode is as follows:
// 1) Buffer fills -> handler gets notified via
//    |trace_handler_ops::notify_buffer_full()|. Two arguments are passed
//    along with this request:
//    |wrapped_count| - records how many times tracing has wrapped from one
//    buffer to the next, and also records the current buffer which is the one
//    needing saving. Since there are two rolling buffers, the buffer to save
//    is |wrapped_count & 1|.
//    |durable_data_end| - records how much data has been written to the
//    durable buffer thus far. This data needs to be written before data from
//    the rolling buffers is written so string and thread references work.
// 2) The handler receives the "notify_buffer_full" request.
// 3) The handler saves new durable data since the last time, saves the
//    rolling buffer, and replies back to the engine via
//    |trace_engine_mark_buffer_saved()|.
// 4) The engine receives this notification and marks the buffer as now empty.
//    The next time the engine tries to allocate space from this buffer it will
//    succeed.
// Note that the handler is free to save buffers at whatever rate it can
// manage. The protocol allows for records to be dropped if buffers can't be
// saved fast enough.

#include <assert.h>
#include <inttypes.h>
#include <lib/trace-engine/fields.h>
#include <lib/trace-engine/handler.h>

#include <atomic>
#include <mutex>

#include "context_impl.h"

namespace trace {
namespace {

// The next context generation number.
std::atomic<uint32_t> g_next_generation{1u};

}  // namespace
}  // namespace trace

trace_context::trace_context(void* buffer, size_t buffer_num_bytes,
                             trace_buffering_mode_t buffering_mode, trace_handler_t* handler)
    : generation_(trace::g_next_generation.fetch_add(1u, std::memory_order_relaxed) + 1u),
      buffering_mode_(buffering_mode),
      buffer_start_(reinterpret_cast<uint8_t*>(buffer)),
      buffer_end_(buffer_start_ + buffer_num_bytes),
      header_(reinterpret_cast<trace_buffer_header*>(buffer)),
      handler_(handler) {
  ZX_DEBUG_ASSERT(buffer_num_bytes >= kMinPhysicalBufferSize);
  ZX_DEBUG_ASSERT(buffer_num_bytes <= kMaxPhysicalBufferSize);
  ZX_DEBUG_ASSERT(generation_ != 0u);
  ComputeBufferSizes();
  ResetBufferPointers();
}

trace_context::~trace_context() = default;

uint64_t* trace_context::AllocRecord(size_t num_bytes) {
  ZX_DEBUG_ASSERT((num_bytes & 7) == 0);
  if (unlikely(num_bytes > TRACE_ENCODED_INLINE_LARGE_RECORD_MAX_SIZE))
    return nullptr;
  static_assert(TRACE_ENCODED_INLINE_LARGE_RECORD_MAX_SIZE < kMaxRollingBufferSize, "");

  // For the circular and streaming cases, try at most once for each buffer.
  // Note: Keep the normal case of one successful pass the fast path.
  // E.g., We don't do a mode comparison unless we have to.

  for (int iter = 0; iter < 2; ++iter) {
    // TODO(dje): This can be optimized a bit. Later.
    uint64_t offset_plus_counter =
        rolling_buffer_current_.fetch_add(num_bytes, std::memory_order_relaxed);
    uint32_t wrapped_count = GetWrappedCount(offset_plus_counter);
    int buffer_number = GetBufferNumber(wrapped_count);
    uint64_t buffer_offset = GetBufferOffset(offset_plus_counter);
    // Note: There's no worry of an overflow in the calcs here.
    if (likely(buffer_offset + num_bytes <= rolling_buffer_size_)) {
      uint8_t* ptr = rolling_buffer_start_[buffer_number] + buffer_offset;
      return reinterpret_cast<uint64_t*>(ptr);  // success!
    }

    // Buffer is full!

    switch (buffering_mode_) {
      case TRACE_BUFFERING_MODE_ONESHOT:
        ZX_DEBUG_ASSERT(iter == 0);
        ZX_DEBUG_ASSERT(wrapped_count == 0);
        ZX_DEBUG_ASSERT(buffer_number == 0);
        MarkOneshotBufferFull(buffer_offset);
        return nullptr;
      case TRACE_BUFFERING_MODE_STREAMING: {
        MarkRollingBufferFull(wrapped_count, buffer_offset);
        // If the TraceManager is slow in saving buffers we could get
        // here a lot. Do a quick check and early exit for this case.
        if (unlikely(!IsOtherRollingBufferReady(buffer_number))) {
          MarkRecordDropped();
          StreamingBufferFullCheck(wrapped_count, buffer_offset);
          return nullptr;
        }
        break;
      }
      case TRACE_BUFFERING_MODE_CIRCULAR:
        MarkRollingBufferFull(wrapped_count, buffer_offset);
        break;
      default:
        __UNREACHABLE;
    }

    if (iter == 1) {
      // Second time through. We tried one buffer, it was full.
      // We then switched to the other buffer, which was empty at
      // the time, and now it is full too. This is technically
      // possible in either circular or streaming modes, but rare.
      // There are two possibilities here:
      // 1) Keep trying (gated by some means).
      // 2) Drop the record.
      // In order to not introduce excessive latency into the app
      // we choose (2). To assist the developer we at least provide
      // a record that this happened, but since it's rare we keep
      // it simple and maintain just a global count and no time
      // information.
      num_records_dropped_after_buffer_switch_.fetch_add(1, std::memory_order_relaxed);
      return nullptr;
    }

    if (!SwitchRollingBuffer(wrapped_count, buffer_offset)) {
      MarkRecordDropped();
      return nullptr;
    }

    // Loop and try again.
  }

  __UNREACHABLE;
}

void trace_context::StreamingBufferFullCheck(uint32_t wrapped_count, uint64_t buffer_offset) {
  // We allow the current offset to grow and grow as each
  // new tracing request is made: It's a trade-off to not penalize
  // performance in this case. The number of counter bits is enough
  // to not make this a concern: See the comments for
  // |kUsableBufferOffsetBits|.
  //
  // As an absolute paranoia check, if the current buffer offset
  // approaches overflow, grab the lock and snap the offset back
  // to the end of the buffer. We grab the lock so that the
  // buffer can't change while we're doing this.
  if (unlikely(buffer_offset > MaxUsableBufferOffset())) {
    std::lock_guard<std::mutex> lock(buffer_switch_mutex_);
    uint32_t current_wrapped_count = CurrentWrappedCount();
    if (GetBufferNumber(current_wrapped_count) == GetBufferNumber(wrapped_count)) {
      SnapToEnd(wrapped_count);
    }
  }
}

// Returns false if there's some reason to not record this record.

bool trace_context::SwitchRollingBuffer(uint32_t wrapped_count, uint64_t buffer_offset) {
  // While atomic variables are used to track things, we switch
  // buffers under the lock due to multiple pieces of state being
  // changed.
  std::lock_guard<std::mutex> lock(buffer_switch_mutex_);

  // If the durable buffer happened to fill while we were waiting for
  // the lock we're done.
  if (unlikely(tracing_artificially_stopped_)) {
    return false;
  }

  uint32_t current_wrapped_count = CurrentWrappedCount();
  // Anything allocated to the durable buffer after this point
  // won't be for this buffer. This is racy, but all we need is
  // some usable value for where the durable pointer is.
  uint64_t durable_data_end = DurableBytesAllocated();

  ZX_DEBUG_ASSERT(wrapped_count <= current_wrapped_count);
  if (likely(wrapped_count == current_wrapped_count)) {
    // Haven't switched buffers yet.
    if (buffering_mode_ == TRACE_BUFFERING_MODE_STREAMING) {
      // Is the other buffer ready?
      if (!IsOtherRollingBufferReady(GetBufferNumber(wrapped_count))) {
        // Nope. There are two possibilities here:
        // 1) Wait for the other buffer to be saved.
        // 2) Start dropping records until the other buffer is
        //    saved.
        // In order to not introduce excessive latency into the
        // app we choose (2). To assist the developer we at
        // least provide a record that indicates the window
        // during which we dropped records.
        // TODO(dje): Maybe have a future mode where we block
        // until there's space. This is useful during some
        // kinds of debugging: Something is going wrong and we
        // care less about performance and more about keeping
        // data, and the dropped data may be the clue to find
        // the bug.
        return false;
      }

      SwitchRollingBufferLocked(wrapped_count, buffer_offset);

      // Notify the handler so it starts saving the buffer if
      // we're in streaming mode.
      // Note: The actual notification must be done *after*
      // updating the buffer header: we need trace_manager to
      // see the updates. The handler will get notified on the
      // engine's async loop (and thus can't call back into us
      // while we still have the lock).
      NotifyRollingBufferFullLocked(wrapped_count, durable_data_end);
    } else {
      SwitchRollingBufferLocked(wrapped_count, buffer_offset);
    }
  } else {
    // Someone else switched buffers while we were trying to obtain
    // the lock. Nothing to do here.
  }

  return true;
}

uint64_t* trace_context::AllocDurableRecord(size_t num_bytes) {
  ZX_DEBUG_ASSERT(UsingDurableBuffer());
  ZX_DEBUG_ASSERT((num_bytes & 7) == 0);

  uint64_t buffer_offset = durable_buffer_current_.fetch_add(num_bytes, std::memory_order_relaxed);
  if (likely(buffer_offset + num_bytes <= durable_buffer_size_)) {
    uint8_t* ptr = durable_buffer_start_ + buffer_offset;
    return reinterpret_cast<uint64_t*>(ptr);  // success!
  }

  // Buffer is full!
  MarkDurableBufferFull(buffer_offset);

  return nullptr;
}

bool trace_context::AllocThreadIndex(trace_thread_index_t* out_index) {
  trace_thread_index_t index = next_thread_index_.fetch_add(1u, std::memory_order_relaxed);
  if (unlikely(index > TRACE_ENCODED_THREAD_REF_MAX_INDEX)) {
    // Guard again possible wrapping.
    next_thread_index_.store(TRACE_ENCODED_THREAD_REF_MAX_INDEX + 1u, std::memory_order_relaxed);
    return false;
  }
  *out_index = index;
  return true;
}

bool trace_context::AllocStringIndex(trace_string_index_t* out_index) {
  trace_string_index_t index = next_string_index_.fetch_add(1u, std::memory_order_relaxed);
  if (unlikely(index > TRACE_ENCODED_STRING_REF_MAX_INDEX)) {
    // Guard again possible wrapping.
    next_string_index_.store(TRACE_ENCODED_STRING_REF_MAX_INDEX + 1u, std::memory_order_relaxed);
    return false;
  }
  *out_index = index;
  return true;
}

void trace_context::ComputeBufferSizes() {
  size_t full_buffer_size = buffer_end_ - buffer_start_;
  ZX_DEBUG_ASSERT(full_buffer_size >= kMinPhysicalBufferSize);
  ZX_DEBUG_ASSERT(full_buffer_size <= kMaxPhysicalBufferSize);
  size_t header_size = sizeof(trace_buffer_header);
  switch (buffering_mode_) {
    case TRACE_BUFFERING_MODE_ONESHOT:
      // Create one big buffer, where durable and non-durable records share
      // the same buffer. There is no separate buffer for durable records.
      durable_buffer_start_ = nullptr;
      durable_buffer_size_ = 0;
      rolling_buffer_start_[0] = buffer_start_ + header_size;
      rolling_buffer_size_ = full_buffer_size - header_size;
      // The second rolling buffer is not used.
      rolling_buffer_start_[1] = nullptr;
      break;
    case TRACE_BUFFERING_MODE_CIRCULAR:
    case TRACE_BUFFERING_MODE_STREAMING: {
      // Rather than make things more complex on the user, at least for now,
      // we choose the sizes of the durable and rolling buffers.
      // Note: The durable buffer must have enough space for at least
      // the initialization record.
      // TODO(dje): The current choices are wip.
      uint64_t avail = full_buffer_size - header_size;
      uint64_t durable_buffer_size = GET_DURABLE_BUFFER_SIZE(avail);
      if (durable_buffer_size > kMaxDurableBufferSize)
        durable_buffer_size = kMaxDurableBufferSize;
      // Further adjust |durable_buffer_size| to ensure all buffers are a
      // multiple of 8. |full_buffer_size| is guaranteed by
      // |trace_start_engine()| to be a multiple of 4096. We only assume
      // header_size is a multiple of 8. In order for rolling_buffer_size
      // to be a multiple of 8 we need (avail - durable_buffer_size) to be a
      // multiple of 16. Round durable_buffer_size up as necessary.
      uint64_t off_by = (avail - durable_buffer_size) & 15;
      ZX_DEBUG_ASSERT(off_by == 0 || off_by == 8);
      durable_buffer_size += off_by;
      ZX_DEBUG_ASSERT((durable_buffer_size & 7) == 0);
      // The value of |kMinPhysicalBufferSize| ensures this:
      ZX_DEBUG_ASSERT(durable_buffer_size >= kMinDurableBufferSize);
      uint64_t rolling_buffer_size = (avail - durable_buffer_size) / 2;
      ZX_DEBUG_ASSERT((rolling_buffer_size & 7) == 0);
      // We need to maintain the invariant that the entire buffer is used.
      // This works if the buffer size is a multiple of
      // sizeof(trace_buffer_header), which is true since the buffer is a
      // vmo (some number of 4K pages).
      ZX_DEBUG_ASSERT(durable_buffer_size + 2 * rolling_buffer_size == avail);
      durable_buffer_start_ = buffer_start_ + header_size;
      durable_buffer_size_ = durable_buffer_size;
      rolling_buffer_start_[0] = durable_buffer_start_ + durable_buffer_size_;
      rolling_buffer_start_[1] = rolling_buffer_start_[0] + rolling_buffer_size;
      rolling_buffer_size_ = rolling_buffer_size;
      break;
    }
    default:
      __UNREACHABLE;
  }
}

void trace_context::ResetDurableBufferPointers() {
  durable_buffer_current_.store(0);
  durable_buffer_full_mark_.store(0);
}

void trace_context::ResetRollingBufferPointers() {
  rolling_buffer_current_.store(0);
  rolling_buffer_full_mark_[0].store(0);
  rolling_buffer_full_mark_[1].store(0);
}

void trace_context::ResetBufferPointers() {
  ResetDurableBufferPointers();
  ResetRollingBufferPointers();
}

void trace_context::InitBufferHeader() {
  memset(header_, 0, sizeof(*header_));

  header_->magic = TRACE_BUFFER_HEADER_MAGIC;
  header_->version = TRACE_BUFFER_HEADER_V0;
  header_->buffering_mode = static_cast<uint8_t>(buffering_mode_);
  header_->total_size = buffer_end_ - buffer_start_;
  header_->durable_buffer_size = durable_buffer_size_;
  header_->rolling_buffer_size = rolling_buffer_size_;
}

void trace_context::ClearEntireBuffer() {
  ResetBufferPointers();
  InitBufferHeader();
}

void trace_context::ClearRollingBuffers() { ResetRollingBufferPointers(); }

void trace_context::UpdateBufferHeaderAfterStopped() {
  // If the buffer filled, then the current pointer is "snapped" to the end.
  // Therefore in that case we need to use the buffer_full_mark.
  uint64_t durable_last_offset = durable_buffer_current_.load(std::memory_order_relaxed);
  uint64_t durable_buffer_full_mark = durable_buffer_full_mark_.load(std::memory_order_relaxed);
  if (durable_buffer_full_mark != 0)
    durable_last_offset = durable_buffer_full_mark;
  header_->durable_data_end = durable_last_offset;

  uint64_t offset_plus_counter = rolling_buffer_current_.load(std::memory_order_relaxed);
  uint64_t last_offset = GetBufferOffset(offset_plus_counter);
  uint32_t wrapped_count = GetWrappedCount(offset_plus_counter);
  header_->wrapped_count = wrapped_count;
  int buffer_number = GetBufferNumber(wrapped_count);
  uint64_t buffer_full_mark =
      rolling_buffer_full_mark_[buffer_number].load(std::memory_order_relaxed);
  if (buffer_full_mark != 0)
    last_offset = buffer_full_mark;
  header_->rolling_data_end[buffer_number] = last_offset;

  header_->num_records_dropped = num_records_dropped();
}

size_t trace_context::RollingBytesAllocated() const {
  switch (buffering_mode_) {
    case TRACE_BUFFERING_MODE_ONESHOT: {
      // There is a window during the processing of buffer-full where
      // |rolling_buffer_current_| may point beyond the end of the buffer.
      // This is ok, we don't promise anything better.
      uint64_t full_bytes = rolling_buffer_full_mark_[0].load(std::memory_order_relaxed);
      if (full_bytes != 0)
        return full_bytes;
      return rolling_buffer_current_.load(std::memory_order_relaxed);
    }
    case TRACE_BUFFERING_MODE_CIRCULAR:
    case TRACE_BUFFERING_MODE_STREAMING: {
      // Obtain the lock so that the buffers aren't switched on us while
      // we're trying to compute the total.
      std::lock_guard<std::mutex> lock(buffer_switch_mutex_);
      uint64_t offset_plus_counter = rolling_buffer_current_.load(std::memory_order_relaxed);
      uint32_t wrapped_count = GetWrappedCount(offset_plus_counter);
      int buffer_number = GetBufferNumber(wrapped_count);
      // Note: If we catch things at the point where the buffer has
      // filled, but before we swap buffers, then |buffer_offset| can point
      // beyond the end. This is ok, we don't promise anything better.
      uint64_t buffer_offset = GetBufferOffset(offset_plus_counter);
      if (wrapped_count == 0)
        return buffer_offset;
      // We've wrapped at least once, so the other buffer's "full mark"
      // must be set. However, it may be zero if streaming and we happened
      // to stop at a point where the buffer was saved, and hasn't
      // subsequently been written to.
      uint64_t full_mark_other_buffer =
          rolling_buffer_full_mark_[!buffer_number].load(std::memory_order_relaxed);
      return full_mark_other_buffer + buffer_offset;
    }
    default:
      __UNREACHABLE;
  }
}

size_t trace_context::DurableBytesAllocated() const {
  // Note: This will return zero in oneshot mode (as it should).
  uint64_t offset = durable_buffer_full_mark_.load(std::memory_order_relaxed);
  if (offset == 0)
    offset = durable_buffer_current_.load(std::memory_order_relaxed);
  return offset;
}

void trace_context::MarkDurableBufferFull(uint64_t last_offset) {
  // Snap to the endpoint to reduce likelihood of pointer wrap-around.
  // Otherwise each new attempt fill continually increase the offset.
  durable_buffer_current_.store(reinterpret_cast<uint64_t>(durable_buffer_size_),
                                std::memory_order_relaxed);

  // Mark the end point if not already marked.
  uintptr_t expected_mark = 0u;
  if (durable_buffer_full_mark_.compare_exchange_strong(
          expected_mark, last_offset, std::memory_order_relaxed, std::memory_order_relaxed)) {
    fprintf(stderr, "TraceEngine: durable buffer full @offset %" PRIu64 "\n", last_offset);
    header_->durable_data_end = last_offset;

    // A record may be written that relies on this durable record.
    // To preserve data integrity, we disable all further tracing.
    // There is a small window where a non-durable record could get
    // emitted that depends on this durable record. It's rare
    // enough and inconsequential enough that we ignore it.
    // TODO(dje): Another possibility is we could let tracing
    // continue and start allocating future durable records in the
    // rolling buffers, and accept potentially lost durable
    // records. Another possibility is to remove the durable buffer,
    // and, say, have separate caches for each rolling buffer.
    MarkTracingArtificiallyStopped();
  }
}

void trace_context::MarkOneshotBufferFull(uint64_t last_offset) {
  SnapToEnd(0);

  // Mark the end point if not already marked.
  uintptr_t expected_mark = 0u;
  if (rolling_buffer_full_mark_[0].compare_exchange_strong(
          expected_mark, last_offset, std::memory_order_relaxed, std::memory_order_relaxed)) {
    header_->rolling_data_end[0] = last_offset;
  }

  MarkRecordDropped();
}

void trace_context::MarkRollingBufferFull(uint32_t wrapped_count, uint64_t last_offset) {
  // Mark the end point if not already marked.
  int buffer_number = GetBufferNumber(wrapped_count);
  uint64_t expected_mark = 0u;
  if (rolling_buffer_full_mark_[buffer_number].compare_exchange_strong(
          expected_mark, last_offset, std::memory_order_relaxed, std::memory_order_relaxed)) {
    header_->rolling_data_end[buffer_number] = last_offset;
  }
}

void trace_context::SwitchRollingBufferLocked(uint32_t prev_wrapped_count,
                                              uint64_t prev_last_offset) {
  // This has already done in streaming mode when the buffer was marked as
  // saved, but hasn't been done yet for circular mode. KISS and just do it
  // again. It's ok to do again as we don't resume allocating trace records
  // until we update |rolling_buffer_current_|.
  uint32_t new_wrapped_count = prev_wrapped_count + 1;
  int next_buffer = GetBufferNumber(new_wrapped_count);
  rolling_buffer_full_mark_[next_buffer].store(0, std::memory_order_relaxed);
  header_->rolling_data_end[next_buffer] = 0;

  // Do this last: After this tracing resumes in the new buffer.
  uint64_t new_offset_plus_counter = MakeOffsetPlusCounter(0, new_wrapped_count);
  rolling_buffer_current_.store(new_offset_plus_counter, std::memory_order_relaxed);
}

void trace_context::MarkTracingArtificiallyStopped() {
  // Grab the lock in part so that we don't switch buffers between
  // |CurrentWrappedCount()| and |SnapToEnd()|.
  std::lock_guard<std::mutex> lock(buffer_switch_mutex_);

  // Disable tracing by making it look like the current rolling
  // buffer is full. AllocRecord, on seeing the buffer is full, will
  // then check |tracing_artificially_stopped_|.
  tracing_artificially_stopped_ = true;
  SnapToEnd(CurrentWrappedCount());
}

void trace_context::NotifyRollingBufferFullLocked(uint32_t wrapped_count,
                                                  uint64_t durable_data_end) {
  // The notification is handled on the engine's event loop as
  // we need this done outside of the lock: Certain handlers
  // (e.g., trace-benchmark) just want to immediately call
  // |trace_engine_mark_buffer_saved()| which wants to reacquire
  // the lock. Secondly, if we choose to wait until the buffer context is
  // released before notifying the handler then we can't do so now as we
  // still have a reference to the buffer context.
  trace_engine_request_save_buffer(wrapped_count, durable_data_end);
}

void trace_context::HandleSaveRollingBufferRequest(uint32_t wrapped_count,
                                                   uint64_t durable_data_end) {
  // TODO(dje): An open issue is solving the problem of TraceManager
  // prematurely reading the buffer: We know the buffer is full, but
  // the only way we know existing writers have completed is when
  // they release their trace context. Fortunately we know when all
  // context acquisitions for the purpose of writing to the buffer
  // have been released. The question is how to use this info.
  // For now we punt the problem to the handler. Ultimately we could
  // provide callers with a way to wait, and have trace_release_context()
  // check for waiters and if any are present send a signal like it does
  // for SIGNAL_CONTEXT_RELEASED.
  handler_->ops->notify_buffer_full(handler_, wrapped_count, durable_data_end);
}

void trace_context::MarkRollingBufferSaved(uint32_t wrapped_count, uint64_t durable_data_end) {
  std::lock_guard<std::mutex> lock(buffer_switch_mutex_);

  int buffer_number = GetBufferNumber(wrapped_count);
  {
    // TODO(dje): Manage bad responses from TraceManager.
    int current_buffer_number =
        GetBufferNumber(GetWrappedCount(rolling_buffer_current_.load(std::memory_order_relaxed)));
    ZX_DEBUG_ASSERT(buffer_number != current_buffer_number);
  }
  rolling_buffer_full_mark_[buffer_number].store(0, std::memory_order_relaxed);
  header_->rolling_data_end[buffer_number] = 0;
  // Don't update |rolling_buffer_current_| here, that is done when we
  // successfully allocate the next record. Until then we want to keep
  // dropping records.
}
