1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_TIMER_H_
6#define RUNTIME_VM_TIMER_H_
7
8#include "platform/atomic.h"
9#include "platform/utils.h"
10#include "vm/allocation.h"
11#include "vm/flags.h"
12#include "vm/os.h"
13
14namespace dart {
15
16// Timer class allows timing of specific operations in the VM.
17class Timer : public ValueObject {
18 public:
19 Timer(bool report, const char* message) : report_(report), message_(message) {
20 Reset();
21 }
22 ~Timer() {}
23
24 // Start timer.
25 void Start() {
26 start_ = OS::GetCurrentMonotonicMicros();
27 running_ = true;
28 }
29
30 // Stop timer.
31 void Stop() {
32 ASSERT(start_ != 0);
33 ASSERT(running());
34 stop_ = OS::GetCurrentMonotonicMicros();
35 int64_t elapsed = ElapsedMicros();
36 max_contiguous_ = Utils::Maximum(max_contiguous_.load(), elapsed);
37 // Make increment atomic in case it occurs in parallel with aggregation.
38 total_.fetch_add(elapsed);
39 running_ = false;
40 }
41
42 // Get total cumulative elapsed time in micros.
43 int64_t TotalElapsedTime() const {
44 int64_t result = total_;
45 if (running_) {
46 int64_t now = OS::GetCurrentMonotonicMicros();
47 result += (now - start_);
48 }
49 return result;
50 }
51
52 int64_t MaxContiguous() const {
53 int64_t result = max_contiguous_;
54 if (running_) {
55 int64_t now = OS::GetCurrentMonotonicMicros();
56 result = Utils::Maximum(result, now - start_);
57 }
58 return result;
59 }
60
61 void Reset() {
62 start_ = 0;
63 stop_ = 0;
64 total_ = 0;
65 max_contiguous_ = 0;
66 running_ = false;
67 }
68
69 bool IsReset() const {
70 return (start_ == 0) && (stop_ == 0) && (total_ == 0) &&
71 (max_contiguous_ == 0) && !running_;
72 }
73
74 void AddTotal(const Timer& other) { total_.fetch_add(other.total_); }
75
76 // Accessors.
77 bool report() const { return report_; }
78 bool running() const { return running_; }
79 const char* message() const { return message_; }
80
81 private:
82 int64_t ElapsedMicros() const {
83 ASSERT(start_ != 0);
84 ASSERT(stop_ != 0);
85 return stop_ - start_;
86 }
87
88 RelaxedAtomic<int64_t> start_;
89 RelaxedAtomic<int64_t> stop_;
90 RelaxedAtomic<int64_t> total_;
91 RelaxedAtomic<int64_t> max_contiguous_;
92 bool report_;
93 bool running_;
94 const char* message_;
95
96 DISALLOW_COPY_AND_ASSIGN(Timer);
97};
98
99} // namespace dart
100
101#endif // RUNTIME_VM_TIMER_H_
102