Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: counter.cc

Issue 2736008: Measure and report time between user-space process crashes. (Closed) Base URL: ssh://git@chromiumos-git/metrics.git
Patch Set: No need to start the back off again on crashes. Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « counter.h ('k') | counter_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "counter.h" 5 #include "counter.h"
6 6
7 #include <sys/file.h> 7 #include <sys/file.h>
8 8
9 #include <base/eintr_wrapper.h> 9 #include <base/eintr_wrapper.h>
10 #include <base/logging.h> 10 #include <base/logging.h>
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 false); // No flush. 51 false); // No flush.
52 } 52 }
53 53
54 void TaggedCounter::Flush() { 54 void TaggedCounter::Flush() {
55 UpdateInternal(0, // tag 55 UpdateInternal(0, // tag
56 0, // count 56 0, // count
57 true); // Do flush. 57 true); // Do flush.
58 } 58 }
59 59
60 void TaggedCounter::UpdateInternal(int tag, int count, bool flush) { 60 void TaggedCounter::UpdateInternal(int tag, int count, bool flush) {
61 // If there's no new data and the last record in the aggregation 61 if (flush) {
62 // file is with the same tag, there's nothing to do. 62 // Flushing but record is null, so nothing to do.
63 if (!flush && count <= 0 && 63 if (record_state_ == kRecordNull)
64 record_state_ == kRecordValid && record_.tag() == tag) 64 return;
65 return; 65 } else {
66 // If there's no new data and the last record in the aggregation
67 // file is with the same tag, there's nothing to do.
68 if (count <= 0 && record_state_ == kRecordValid && record_.tag() == tag)
69 return;
70 }
66 71
67 DLOG(INFO) << "tag: " << tag << " count: " << count << " flush: " << flush; 72 DLOG(INFO) << "tag: " << tag << " count: " << count << " flush: " << flush;
68 DCHECK(filename_); 73 DCHECK(filename_);
69 74
70 // NOTE: The assumption is that this TaggedCounter object is the 75 // NOTE: The assumption is that this TaggedCounter object is the
71 // sole owner of the persistent storage file so no locking is 76 // sole owner of the persistent storage file so no locking is
72 // necessary. 77 // necessary.
73 int fd = HANDLE_EINTR(open(filename_, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)); 78 int fd = HANDLE_EINTR(open(filename_, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR));
74 if (fd < 0) { 79 if (fd < 0) {
75 PLOG(WARNING) << "Unable to open the persistent counter file"; 80 PLOG(WARNING) << "Unable to open the persistent counter file";
76 return; 81 return;
77 } 82 }
78 83
79 ReadRecord(fd); 84 ReadRecord(fd);
80 ReportRecord(tag, flush); 85 ReportRecord(tag, flush);
81 UpdateRecord(tag, count); 86 UpdateRecord(tag, count, flush);
82 WriteRecord(fd); 87 WriteRecord(fd);
83 88
84 HANDLE_EINTR(close(fd)); 89 HANDLE_EINTR(close(fd));
85 } 90 }
86 91
87 void TaggedCounter::ReadRecord(int fd) { 92 void TaggedCounter::ReadRecord(int fd) {
88 if (record_state_ != kRecordInvalid) 93 if (record_state_ != kRecordInvalid)
89 return; 94 return;
90 95
91 if (HANDLE_EINTR(read(fd, &record_, sizeof(record_))) == sizeof(record_)) { 96 if (HANDLE_EINTR(read(fd, &record_, sizeof(record_))) == sizeof(record_)) {
92 if (record_.count() > 0) { 97 if (record_.count() >= 0) {
93 record_state_ = kRecordValid; 98 record_state_ = kRecordValid;
94 return; 99 return;
95 } 100 }
96 // This shouldn't happen normally unless somebody messed with the 101 // This shouldn't happen normally unless somebody messed with the
97 // persistent storage file. 102 // persistent storage file.
98 NOTREACHED(); 103 NOTREACHED();
99 record_state_ = kRecordNullDirty; 104 record_state_ = kRecordNullDirty;
100 return; 105 return;
101 } 106 }
102 107
103 record_state_ = kRecordNull; 108 record_state_ = kRecordNull;
104 } 109 }
105 110
106 void TaggedCounter::ReportRecord(int tag, bool flush) { 111 void TaggedCounter::ReportRecord(int tag, bool flush) {
107 // If no valid record, there's nothing to report. 112 // If no valid record, there's nothing to report.
108 if (record_state_ != kRecordValid) { 113 if (record_state_ != kRecordValid) {
109 DCHECK(record_state_ == kRecordNull); 114 DCHECK_EQ(record_state_, kRecordNull);
110 return; 115 return;
111 } 116 }
112 117
113 // If the current record has the same tag as the new tag, it's not 118 // If the current record has the same tag as the new tag, it's not
114 // ready to be reported yet. 119 // ready to be reported yet.
115 if (!flush && record_.tag() == tag) 120 if (!flush && record_.tag() == tag)
116 return; 121 return;
117 122
118 if (reporter_) { 123 if (reporter_) {
119 reporter_(reporter_handle_, record_.tag(), record_.count()); 124 reporter_(reporter_handle_, record_.tag(), record_.count());
120 } 125 }
121 record_state_ = kRecordNullDirty; 126 record_state_ = kRecordNullDirty;
122 } 127 }
123 128
124 void TaggedCounter::UpdateRecord(int tag, int count) { 129 void TaggedCounter::UpdateRecord(int tag, int count, bool flush) {
125 if (count <= 0) 130 if (flush) {
131 DCHECK(record_state_ == kRecordNull || record_state_ == kRecordNullDirty);
126 return; 132 return;
133 }
127 134
128 switch (record_state_) { 135 switch (record_state_) {
129 case kRecordNull: 136 case kRecordNull:
130 case kRecordNullDirty: 137 case kRecordNullDirty:
131 // Current record is null, starting a new record. 138 // Current record is null, starting a new record.
132 record_.Init(tag, count); 139 record_.Init(tag, count);
133 record_state_ = kRecordValidDirty; 140 record_state_ = kRecordValidDirty;
134 break; 141 break;
135 142
136 case kRecordValid: 143 case kRecordValid:
137 // If there's an existing record for the current tag, 144 // If there's an existing record for the current tag,
138 // accumulates the counts. 145 // accumulates the counts.
139 DCHECK_EQ(record_.tag(), tag); 146 DCHECK_EQ(record_.tag(), tag);
140 record_.Add(count); 147 if (count > 0) {
141 record_state_ = kRecordValidDirty; 148 record_.Add(count);
149 record_state_ = kRecordValidDirty;
150 }
142 break; 151 break;
143 152
144 default: 153 default:
145 NOTREACHED(); 154 NOTREACHED();
146 } 155 }
147 } 156 }
148 157
149 void TaggedCounter::WriteRecord(int fd) { 158 void TaggedCounter::WriteRecord(int fd) {
150 switch (record_state_) { 159 switch (record_state_) {
151 case kRecordNullDirty: 160 case kRecordNullDirty:
(...skipping 15 matching lines...) Expand all
167 case kRecordValid: 176 case kRecordValid:
168 // Nothing to do. 177 // Nothing to do.
169 break; 178 break;
170 179
171 default: 180 default:
172 NOTREACHED(); 181 NOTREACHED();
173 } 182 }
174 } 183 }
175 184
176 } // namespace chromeos_metrics 185 } // namespace chromeos_metrics
OLDNEW
« no previous file with comments | « counter.h ('k') | counter_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698