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

#include "src/libplatform/tracing/trace-buffer.h"

namespace v8 {
namespace platform {
namespace tracing {

TraceBufferRingBuffer::TraceBufferRingBuffer(size_t max_chunks,
                                             TraceWriter* trace_writer)
    : max_chunks_(max_chunks) {
  trace_writer_.reset(trace_writer);
  chunks_.resize(max_chunks);
}

TraceObject* TraceBufferRingBuffer::AddTraceEvent(uint64_t* handle) {
  base::MutexGuard guard(&mutex_);
  if (is_empty_ || chunks_[chunk_index_]->IsFull()) {
    chunk_index_ = is_empty_ ? 0 : NextChunkIndex(chunk_index_);
    is_empty_ = false;
    auto& chunk = chunks_[chunk_index_];
    if (chunk) {
      chunk->Reset(current_chunk_seq_++);
    } else {
      chunk.reset(new TraceBufferChunk(current_chunk_seq_++));
    }
  }
  auto& chunk = chunks_[chunk_index_];
  size_t event_index;
  TraceObject* trace_object = chunk->AddTraceEvent(&event_index);
  *handle = MakeHandle(chunk_index_, chunk->seq(), event_index);
  return trace_object;
}

TraceObject* TraceBufferRingBuffer::GetEventByHandle(uint64_t handle) {
  base::MutexGuard guard(&mutex_);
  size_t chunk_index, event_index;
  uint32_t chunk_seq;
  ExtractHandle(handle, &chunk_index, &chunk_seq, &event_index);
  if (chunk_index >= chunks_.size()) return nullptr;
  auto& chunk = chunks_[chunk_index];
  if (!chunk || chunk->seq() != chunk_seq) return nullptr;
  return chunk->GetEventAt(event_index);
}

bool TraceBufferRingBuffer::Flush() {
  base::MutexGuard guard(&mutex_);
  // This flushes all the traces stored in the buffer.
  if (!is_empty_) {
    for (size_t i = NextChunkIndex(chunk_index_);; i = NextChunkIndex(i)) {
      if (auto& chunk = chunks_[i]) {
        for (size_t j = 0; j < chunk->size(); ++j) {
          trace_writer_->AppendTraceEvent(chunk->GetEventAt(j));
        }
      }
      if (i == chunk_index_) break;
    }
  }
  trace_writer_->Flush();
  // This resets the trace buffer.
  is_empty_ = true;
  return true;
}

uint64_t TraceBufferRingBuffer::MakeHandle(size_t chunk_index,
                                           uint32_t chunk_seq,
                                           size_t event_index) const {
  return static_cast<uint64_t>(chunk_seq) * Capacity() +
         chunk_index * TraceBufferChunk::kChunkSize + event_index;
}

void TraceBufferRingBuffer::ExtractHandle(uint64_t handle, size_t* chunk_index,
                                          uint32_t* chunk_seq,
                                          size_t* event_index) const {
  *chunk_seq = static_cast<uint32_t>(handle / Capacity());
  size_t indices = handle % Capacity();
  *chunk_index = indices / TraceBufferChunk::kChunkSize;
  *event_index = indices % TraceBufferChunk::kChunkSize;
}

size_t TraceBufferRingBuffer::NextChunkIndex(size_t index) const {
  if (++index >= max_chunks_) index = 0;
  return index;
}

TraceBufferChunk::TraceBufferChunk(uint32_t seq) : seq_(seq) {}

void TraceBufferChunk::Reset(uint32_t new_seq) {
  next_free_ = 0;
  seq_ = new_seq;
}

TraceObject* TraceBufferChunk::AddTraceEvent(size_t* event_index) {
  *event_index = next_free_++;
  return &chunk_[*event_index];
}

TraceBuffer* TraceBuffer::CreateTraceBufferRingBuffer(
    size_t max_chunks, TraceWriter* trace_writer) {
  return new TraceBufferRingBuffer(max_chunks, trace_writer);
}

}  // namespace tracing
}  // namespace platform
}  // namespace v8
