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

Side by Side Diff: runtime/vm/thread_interrupter.cc

Issue 1412733008: Switch profiler from isolates to threads (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
« runtime/vm/profiler.cc ('K') | « runtime/vm/thread.cc ('k') | no next file » | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/thread_interrupter.h" 5 #include "vm/thread_interrupter.h"
6 6
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/lockers.h" 8 #include "vm/lockers.h"
9 #include "vm/os.h" 9 #include "vm/os.h"
10 #include "vm/simulator.h" 10 #include "vm/simulator.h"
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (shutdown_) { 117 if (shutdown_) {
118 return; 118 return;
119 } 119 }
120 ASSERT(initialized_); 120 ASSERT(initialized_);
121 ASSERT(period > 0); 121 ASSERT(period > 0);
122 interrupt_period_ = period; 122 interrupt_period_ = period;
123 } 123 }
124 124
125 125
126 void ThreadInterrupter::WakeUp() { 126 void ThreadInterrupter::WakeUp() {
127 if (!initialized_) {
128 // Early call.
129 return;
130 }
127 ASSERT(initialized_); 131 ASSERT(initialized_);
128 { 132 {
129 MonitorLocker ml(monitor_); 133 MonitorLocker ml(monitor_);
130 if (!InDeepSleep()) { 134 if (!InDeepSleep()) {
131 // No need to notify, regularly waking up. 135 // No need to notify, regularly waking up.
132 return; 136 return;
133 } 137 }
134 // Notify the interrupter to wake it from its deep sleep. 138 // Notify the interrupter to wake it from its deep sleep.
135 ml.Notify(); 139 ml.Notify();
136 } 140 }
137 } 141 }
138 142
139 143
140 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) { 144 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) {
141 // NoOp. 145 // NoOp.
142 } 146 }
143 147
144 148
145 class ThreadInterrupterVisitIsolates : public IsolateVisitor {
146 public:
147 ThreadInterrupterVisitIsolates() {
148 profiled_thread_count_ = 0;
149 }
150
151 void VisitIsolate(Isolate* isolate) {
152 ASSERT(isolate != NULL);
153 profiled_thread_count_ += isolate->ProfileInterrupt();
154 }
155
156 intptr_t profiled_thread_count() const {
157 return profiled_thread_count_;
158 }
159
160 void set_profiled_thread_count(intptr_t profiled_thread_count) {
161 profiled_thread_count_ = profiled_thread_count;
162 }
163
164 private:
165 intptr_t profiled_thread_count_;
166 };
167
168
169 void ThreadInterrupter::ThreadMain(uword parameters) { 149 void ThreadInterrupter::ThreadMain(uword parameters) {
170 ASSERT(initialized_); 150 ASSERT(initialized_);
171 InstallSignalHandler(); 151 InstallSignalHandler();
172 if (FLAG_trace_thread_interrupter) { 152 if (FLAG_trace_thread_interrupter) {
173 OS::Print("ThreadInterrupter thread running.\n"); 153 OS::Print("ThreadInterrupter thread running.\n");
174 } 154 }
175 { 155 {
176 // Signal to main thread we are ready. 156 // Signal to main thread we are ready.
177 MonitorLocker startup_ml(monitor_); 157 MonitorLocker startup_ml(monitor_);
178 interrupter_thread_id_ = OSThread::GetCurrentThreadJoinId(); 158 interrupter_thread_id_ = OSThread::GetCurrentThreadJoinId();
179 thread_running_ = true; 159 thread_running_ = true;
180 startup_ml.Notify(); 160 startup_ml.Notify();
181 } 161 }
182 { 162 {
183 ThreadInterrupterVisitIsolates visitor; 163 intptr_t interrupted_thread_count = 0;
184 current_wait_time_ = interrupt_period_; 164 current_wait_time_ = interrupt_period_;
185 MonitorLocker wait_ml(monitor_); 165 MonitorLocker wait_ml(monitor_);
186 while (!shutdown_) { 166 while (!shutdown_) {
187 intptr_t r = wait_ml.WaitMicros(current_wait_time_); 167 intptr_t r = wait_ml.WaitMicros(current_wait_time_);
188 168
189 if ((r == Monitor::kNotified) && shutdown_) { 169 if ((r == Monitor::kNotified) && shutdown_) {
190 break; 170 break;
191 } 171 }
192 172
193 if ((r == Monitor::kNotified) && InDeepSleep()) { 173 if ((r == Monitor::kNotified) && InDeepSleep()) {
194 // Woken up from deep sleep. 174 // Woken up from deep sleep.
195 ASSERT(visitor.profiled_thread_count() == 0); 175 ASSERT(interrupted_thread_count == 0);
196 // Return to regular interrupts. 176 // Return to regular interrupts.
197 current_wait_time_ = interrupt_period_; 177 current_wait_time_ = interrupt_period_;
198 } 178 }
199 179
200 // Reset count before visiting isolates. 180 // Reset count before interrupting any threads.
201 visitor.set_profiled_thread_count(0); 181 interrupted_thread_count = 0;
202 Isolate::VisitIsolates(&visitor);
203 182
siva 2015/10/26 23:45:26 Do we need to be holding the monitor_ lock here, w
Cutch 2015/10/27 22:36:24 Done.
204 if (visitor.profiled_thread_count() == 0) { 183 {
205 // No isolates were profiled. In order to reduce unnecessary CPU 184 ThreadIterator it;
185 while (it.HasNext()) {
186 Thread* thread = it.Next();
187 if (thread->ThreadInterruptsEnabled()) {
188 interrupted_thread_count++;
189 InterruptThread(thread);
190 }
191 }
192 }
193
194 if (interrupted_thread_count == 0) {
195 // No threads were interrupted. In order to reduce unnecessary CPU
206 // load, we will wait until we are notified before attempting to 196 // load, we will wait until we are notified before attempting to
207 // interrupt again. 197 // interrupt again.
208 current_wait_time_ = Monitor::kNoTimeout; 198 current_wait_time_ = Monitor::kNoTimeout;
209 continue; 199 continue;
210 } 200 }
211 201
212 ASSERT(current_wait_time_ != Monitor::kNoTimeout); 202 ASSERT(current_wait_time_ != Monitor::kNoTimeout);
213 } 203 }
214 } 204 }
215 RemoveSignalHandler(); 205 RemoveSignalHandler();
216 if (FLAG_trace_thread_interrupter) { 206 if (FLAG_trace_thread_interrupter) {
217 OS::Print("ThreadInterrupter thread exiting.\n"); 207 OS::Print("ThreadInterrupter thread exiting.\n");
218 } 208 }
219 { 209 {
220 // Signal to main thread we are exiting. 210 // Signal to main thread we are exiting.
221 MonitorLocker shutdown_ml(monitor_); 211 MonitorLocker shutdown_ml(monitor_);
222 thread_running_ = false; 212 thread_running_ = false;
223 shutdown_ml.Notify(); 213 shutdown_ml.Notify();
224 } 214 }
225 } 215 }
226 216
227 } // namespace dart 217 } // namespace dart
OLDNEW
« runtime/vm/profiler.cc ('K') | « runtime/vm/thread.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698