// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef VM_TIMER_H_
#define VM_TIMER_H_

#include "platform/utils.h"
#include "vm/allocation.h"
#include "vm/atomic.h"
#include "vm/flags.h"
#include "vm/os.h"

namespace dart {

// Timer class allows timing of specific operations in the VM.
class Timer : public ValueObject {
 public:
  Timer(bool report, const char* message)
      : report_(report), message_(message) {
    Reset();
  }
  ~Timer() {}

  // Start timer.
  void Start() {
    start_ = OS::GetCurrentTimeMicros();
    running_ = true;
  }

  // Stop timer.
  void Stop() {
    ASSERT(start_ != 0);
    ASSERT(running());
    stop_ = OS::GetCurrentTimeMicros();
    int64_t elapsed = ElapsedMicros();
    max_contiguous_ = Utils::Maximum(max_contiguous_, elapsed);
    // Make increment atomic in case it occurs in parallel with aggregation.
    AtomicOperations::IncrementInt64By(&total_, elapsed);
    running_ = false;
  }

  // Get total cummulative elapsed time in micros.
  int64_t TotalElapsedTime() const {
    int64_t result = total_;
    if (running_) {
      int64_t now = OS::GetCurrentTimeMicros();
      result += (now - start_);
    }
    return result;
  }

  int64_t MaxContiguous() const {
    int64_t result = max_contiguous_;
    if (running_) {
      int64_t now = OS::GetCurrentTimeMicros();
      result = Utils::Maximum(result, now - start_);
    }
    return result;
  }

  void Reset() {
    start_ = 0;
    stop_ = 0;
    total_ = 0;
    max_contiguous_ = 0;
    running_ = false;
  }

  bool IsReset() const {
    return (start_ == 0) && (stop_ == 0) && (total_ == 0) &&
        (max_contiguous_ == 0) && !running_;
  }

  void AddTotal(const Timer& other) {
    AtomicOperations::IncrementInt64By(&total_, other.total_);
  }

  // Accessors.
  bool report() const { return report_; }
  bool running() const { return running_; }
  const char* message() const { return message_; }

 private:
  int64_t ElapsedMicros() const {
    ASSERT(start_ != 0);
    ASSERT(stop_ != 0);
    return stop_ - start_;
  }

  int64_t start_;
  int64_t stop_;
  int64_t total_;
  int64_t max_contiguous_;
  bool report_;
  bool running_;
  const char* message_;

  DISALLOW_COPY_AND_ASSIGN(Timer);
};


// The class TimerScope is used to start and stop a timer within a scope.
// It is used as follows:
// {
//   TimerScope timer(FLAG_name_of_flag, timer, isolate);
//   .....
//   code that needs to be timed.
//   ....
// }
class TimerScope : public StackResource {
 public:
  TimerScope(bool flag, Timer* timer, Thread* thread = NULL)
      : StackResource(thread),
        nested_(false),
        timer_(flag ? timer : NULL) {
    Init();
  }

  void Init() {
    if (timer_ != NULL) {
      if (!timer_->running()) {
        timer_->Start();
      } else {
        nested_ = true;
      }
    }
  }
  ~TimerScope() {
    if (timer_ != NULL) {
      if (!nested_) {
        timer_->Stop();
      }
    }
  }

 private:
  bool nested_;
  Timer* const timer_;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(TimerScope);
};


class PauseTimerScope : public StackResource {
 public:
  PauseTimerScope(bool flag, Timer* timer, Thread* thread = NULL)
      : StackResource(thread),
        nested_(false),
        timer_(flag ? timer : NULL) {
    if (timer_) {
      if (timer_->running()) {
        timer_->Stop();
      } else {
        nested_ = true;
      }
    }
  }
  ~PauseTimerScope() {
    if (timer_) {
      if (!nested_) {
        timer_->Start();
      }
    }
  }

 private:
  bool nested_;
  Timer* const timer_;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(PauseTimerScope);
};



}  // namespace dart

#endif  // VM_TIMER_H_
