// Copyright 2015 The Chromium 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 "base/profiler/stack_sampling_profiler.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/profiler/native_stack_sampler.h"
#include "base/synchronization/lock.h"
#include "base/thread_task_runner_handle.h"
#include "base/timer/elapsed_timer.h"

namespace base {

namespace {

// Used to ensure only one profiler is running at a time.
LazyInstance<Lock> concurrent_profiling_lock = LAZY_INSTANCE_INITIALIZER;

// AsyncRunner ----------------------------------------------------------------

// Helper class to allow a profiler to be run completely asynchronously from the
// initiator, without being concerned with the profiler's lifetime.
class AsyncRunner {
 public:
  // Sets up a profiler and arranges for it to be deleted on its completed
  // callback.
  static void Run(PlatformThreadId thread_id,
                  const StackSamplingProfiler::SamplingParams& params,
                  const StackSamplingProfiler::CompletedCallback& callback);

 private:
  AsyncRunner();

  // Runs the callback and deletes the AsyncRunner instance.
  static void RunCallbackAndDeleteInstance(
      scoped_ptr<AsyncRunner> object_to_be_deleted,
      const StackSamplingProfiler::CompletedCallback& callback,
      scoped_refptr<SingleThreadTaskRunner> task_runner,
      const StackSamplingProfiler::CallStackProfiles& profiles);

  scoped_ptr<StackSamplingProfiler> profiler_;

  DISALLOW_COPY_AND_ASSIGN(AsyncRunner);
};

// static
void AsyncRunner::Run(
    PlatformThreadId thread_id,
    const StackSamplingProfiler::SamplingParams& params,
    const StackSamplingProfiler::CompletedCallback &callback) {
  scoped_ptr<AsyncRunner> runner(new AsyncRunner);
  AsyncRunner* temp_ptr = runner.get();
  temp_ptr->profiler_.reset(
      new StackSamplingProfiler(thread_id, params,
                                Bind(&AsyncRunner::RunCallbackAndDeleteInstance,
                                     Passed(&runner), callback,
                                     ThreadTaskRunnerHandle::Get())));
  // The callback won't be called until after Start(), so temp_ptr will still
  // be valid here.
  temp_ptr->profiler_->Start();
}

AsyncRunner::AsyncRunner() {}

void AsyncRunner::RunCallbackAndDeleteInstance(
    scoped_ptr<AsyncRunner> object_to_be_deleted,
    const StackSamplingProfiler::CompletedCallback& callback,
    scoped_refptr<SingleThreadTaskRunner> task_runner,
    const StackSamplingProfiler::CallStackProfiles& profiles) {
  callback.Run(profiles);
  // Delete the instance on the original calling thread.
  task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release());
}

}  // namespace

// StackSamplingProfiler::Module ----------------------------------------------

StackSamplingProfiler::Module::Module() : base_address(0u) {}
StackSamplingProfiler::Module::Module(uintptr_t base_address,
                                      const std::string& id,
                                      const FilePath& filename)
    : base_address(base_address), id(id), filename(filename) {}

StackSamplingProfiler::Module::~Module() {}

// StackSamplingProfiler::Frame -----------------------------------------------

StackSamplingProfiler::Frame::Frame(uintptr_t instruction_pointer,
                                    size_t module_index)
    : instruction_pointer(instruction_pointer), module_index(module_index) {}

StackSamplingProfiler::Frame::~Frame() {}

StackSamplingProfiler::Frame::Frame() {}

// StackSamplingProfiler::CallStackProfile ------------------------------------

StackSamplingProfiler::CallStackProfile::CallStackProfile() {}

StackSamplingProfiler::CallStackProfile::~CallStackProfile() {}

// StackSamplingProfiler::SamplingThread --------------------------------------

StackSamplingProfiler::SamplingThread::SamplingThread(
    scoped_ptr<NativeStackSampler> native_sampler,
    const SamplingParams& params,
    const CompletedCallback& completed_callback)
    : native_sampler_(std::move(native_sampler)),
      params_(params),
      stop_event_(false, false),
      completed_callback_(completed_callback) {}

StackSamplingProfiler::SamplingThread::~SamplingThread() {}

void StackSamplingProfiler::SamplingThread::ThreadMain() {
  PlatformThread::SetName("Chrome_SamplingProfilerThread");

  // For now, just ignore any requests to profile while another profiler is
  // working.
  if (!concurrent_profiling_lock.Get().Try())
    return;

  CallStackProfiles profiles;
  CollectProfiles(&profiles);
  concurrent_profiling_lock.Get().Release();
  completed_callback_.Run(profiles);
}

// Depending on how long the sampling takes and the length of the sampling
// interval, a burst of samples could take arbitrarily longer than
// samples_per_burst * sampling_interval. In this case, we (somewhat
// arbitrarily) honor the number of samples requested rather than strictly
// adhering to the sampling intervals. Once we have established users for the
// StackSamplingProfiler and the collected data to judge, we may go the other
// way or make this behavior configurable.
void StackSamplingProfiler::SamplingThread::CollectProfile(
    CallStackProfile* profile,
    TimeDelta* elapsed_time,
    bool* was_stopped) {
  ElapsedTimer profile_timer;
  native_sampler_->ProfileRecordingStarting(&profile->modules);
  profile->sampling_period = params_.sampling_interval;
  *was_stopped = false;
  TimeDelta previous_elapsed_sample_time;
  for (int i = 0; i < params_.samples_per_burst; ++i) {
    if (i != 0) {
      // Always wait, even if for 0 seconds, so we can observe a signal on
      // stop_event_.
      if (stop_event_.TimedWait(
              std::max(params_.sampling_interval - previous_elapsed_sample_time,
                       TimeDelta()))) {
        *was_stopped = true;
        break;
      }
    }
    ElapsedTimer sample_timer;
    profile->samples.push_back(Sample());
    native_sampler_->RecordStackSample(&profile->samples.back());
    previous_elapsed_sample_time = sample_timer.Elapsed();
  }

  *elapsed_time = profile_timer.Elapsed();
  profile->profile_duration = *elapsed_time;
  native_sampler_->ProfileRecordingStopped();
}

// In an analogous manner to CollectProfile() and samples exceeding the expected
// total sampling time, bursts may also exceed the burst_interval. We adopt the
// same wait-and-see approach here.
void StackSamplingProfiler::SamplingThread::CollectProfiles(
    CallStackProfiles* profiles) {
  if (stop_event_.TimedWait(params_.initial_delay))
    return;

  TimeDelta previous_elapsed_profile_time;
  for (int i = 0; i < params_.bursts; ++i) {
    if (i != 0) {
      // Always wait, even if for 0 seconds, so we can observe a signal on
      // stop_event_.
      if (stop_event_.TimedWait(
              std::max(params_.burst_interval - previous_elapsed_profile_time,
                       TimeDelta())))
        return;
    }

    CallStackProfile profile;
    bool was_stopped = false;
    CollectProfile(&profile, &previous_elapsed_profile_time, &was_stopped);
    if (!profile.samples.empty())
      profiles->push_back(profile);

    if (was_stopped)
      return;
  }
}

void StackSamplingProfiler::SamplingThread::Stop() {
  stop_event_.Signal();
}

// StackSamplingProfiler ------------------------------------------------------

StackSamplingProfiler::SamplingParams::SamplingParams()
    : initial_delay(TimeDelta::FromMilliseconds(0)),
      bursts(1),
      burst_interval(TimeDelta::FromMilliseconds(10000)),
      samples_per_burst(300),
      sampling_interval(TimeDelta::FromMilliseconds(100)) {
}

StackSamplingProfiler::StackSamplingProfiler(
    PlatformThreadId thread_id,
    const SamplingParams& params,
    const CompletedCallback& callback)
    : StackSamplingProfiler(thread_id, params, callback, nullptr) {}

StackSamplingProfiler::StackSamplingProfiler(
    PlatformThreadId thread_id,
    const SamplingParams& params,
    const CompletedCallback& callback,
    NativeStackSamplerTestDelegate* test_delegate)
    : thread_id_(thread_id), params_(params), completed_callback_(callback),
      test_delegate_(test_delegate) {
}

StackSamplingProfiler::~StackSamplingProfiler() {
  Stop();
  if (!sampling_thread_handle_.is_null())
    PlatformThread::Join(sampling_thread_handle_);
}

// static
void StackSamplingProfiler::StartAndRunAsync(
    PlatformThreadId thread_id,
    const SamplingParams& params,
    const CompletedCallback& callback) {
  CHECK(ThreadTaskRunnerHandle::Get());
  AsyncRunner::Run(thread_id, params, callback);
}

void StackSamplingProfiler::Start() {
  if (completed_callback_.is_null())
    return;

  scoped_ptr<NativeStackSampler> native_sampler =
      NativeStackSampler::Create(thread_id_, test_delegate_);
  if (!native_sampler)
    return;

  sampling_thread_.reset(new SamplingThread(std::move(native_sampler), params_,
                                            completed_callback_));
  if (!PlatformThread::Create(0, sampling_thread_.get(),
                              &sampling_thread_handle_))
    sampling_thread_.reset();
}

void StackSamplingProfiler::Stop() {
  if (sampling_thread_)
    sampling_thread_->Stop();
}

// StackSamplingProfiler::Frame global functions ------------------------------

bool operator==(const StackSamplingProfiler::Frame &a,
                const StackSamplingProfiler::Frame &b) {
  return a.instruction_pointer == b.instruction_pointer &&
      a.module_index == b.module_index;
}

bool operator<(const StackSamplingProfiler::Frame &a,
               const StackSamplingProfiler::Frame &b) {
  return (a.module_index < b.module_index) ||
      (a.module_index == b.module_index &&
       a.instruction_pointer < b.instruction_pointer);
}

}  // namespace base
