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

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

Issue 1425093006: Revert "Switch profiler from isolates to threads" (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 | « runtime/vm/thread_interrupter.h ('k') | runtime/vm/thread_interrupter_android.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) 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // thread local storage pointer is set again. This has an important side 44 // thread local storage pointer is set again. This has an important side
45 // effect: if the thread is interrupted by a signal handler during a ThreadState 45 // effect: if the thread is interrupted by a signal handler during a ThreadState
46 // update the signal handler will immediately return. 46 // update the signal handler will immediately return.
47 47
48 DEFINE_FLAG(bool, trace_thread_interrupter, false, 48 DEFINE_FLAG(bool, trace_thread_interrupter, false,
49 "Trace thread interrupter"); 49 "Trace thread interrupter");
50 50
51 bool ThreadInterrupter::initialized_ = false; 51 bool ThreadInterrupter::initialized_ = false;
52 bool ThreadInterrupter::shutdown_ = false; 52 bool ThreadInterrupter::shutdown_ = false;
53 bool ThreadInterrupter::thread_running_ = false; 53 bool ThreadInterrupter::thread_running_ = false;
54 bool ThreadInterrupter::woken_up_ = false;
55 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ = 54 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ =
56 OSThread::kInvalidThreadJoinId; 55 OSThread::kInvalidThreadJoinId;
57 Monitor* ThreadInterrupter::monitor_ = NULL; 56 Monitor* ThreadInterrupter::monitor_ = NULL;
58 intptr_t ThreadInterrupter::interrupt_period_ = 1000; 57 intptr_t ThreadInterrupter::interrupt_period_ = 1000;
59 intptr_t ThreadInterrupter::current_wait_time_ = Monitor::kNoTimeout; 58 intptr_t ThreadInterrupter::current_wait_time_ = Monitor::kNoTimeout;
60 59
61 60
62 void ThreadInterrupter::InitOnce() { 61 void ThreadInterrupter::InitOnce() {
63 ASSERT(!initialized_); 62 ASSERT(!initialized_);
64 monitor_ = new Monitor(); 63 monitor_ = new Monitor();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 if (shutdown_) { 117 if (shutdown_) {
119 return; 118 return;
120 } 119 }
121 ASSERT(initialized_); 120 ASSERT(initialized_);
122 ASSERT(period > 0); 121 ASSERT(period > 0);
123 interrupt_period_ = period; 122 interrupt_period_ = period;
124 } 123 }
125 124
126 125
127 void ThreadInterrupter::WakeUp() { 126 void ThreadInterrupter::WakeUp() {
128 if (!initialized_) {
129 // Early call.
130 return;
131 }
132 ASSERT(initialized_); 127 ASSERT(initialized_);
133 { 128 {
134 MonitorLocker ml(monitor_); 129 MonitorLocker ml(monitor_);
135 woken_up_ = true;
136 if (!InDeepSleep()) { 130 if (!InDeepSleep()) {
137 // No need to notify, regularly waking up. 131 // No need to notify, regularly waking up.
138 return; 132 return;
139 } 133 }
140 // Notify the interrupter to wake it from its deep sleep. 134 // Notify the interrupter to wake it from its deep sleep.
141 ml.Notify(); 135 ml.Notify();
142 } 136 }
143 } 137 }
144 138
145 139
140 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) {
141 // NoOp.
142 }
143
144
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
146 void ThreadInterrupter::ThreadMain(uword parameters) { 169 void ThreadInterrupter::ThreadMain(uword parameters) {
147 ASSERT(initialized_); 170 ASSERT(initialized_);
148 InstallSignalHandler(); 171 InstallSignalHandler();
149 if (FLAG_trace_thread_interrupter) { 172 if (FLAG_trace_thread_interrupter) {
150 OS::Print("ThreadInterrupter thread running.\n"); 173 OS::Print("ThreadInterrupter thread running.\n");
151 } 174 }
152 { 175 {
153 // Signal to main thread we are ready. 176 // Signal to main thread we are ready.
154 MonitorLocker startup_ml(monitor_); 177 MonitorLocker startup_ml(monitor_);
155 interrupter_thread_id_ = OSThread::GetCurrentThreadJoinId(); 178 interrupter_thread_id_ = OSThread::GetCurrentThreadJoinId();
156 thread_running_ = true; 179 thread_running_ = true;
157 startup_ml.Notify(); 180 startup_ml.Notify();
158 } 181 }
159 { 182 {
160 intptr_t interrupted_thread_count = 0; 183 ThreadInterrupterVisitIsolates visitor;
161 current_wait_time_ = interrupt_period_; 184 current_wait_time_ = interrupt_period_;
162 MonitorLocker wait_ml(monitor_); 185 MonitorLocker wait_ml(monitor_);
163 while (!shutdown_) { 186 while (!shutdown_) {
164 intptr_t r = wait_ml.WaitMicros(current_wait_time_); 187 intptr_t r = wait_ml.WaitMicros(current_wait_time_);
165 188
166 if (shutdown_) { 189 if ((r == Monitor::kNotified) && shutdown_) {
167 break; 190 break;
168 } 191 }
169 192
170 if ((r == Monitor::kNotified) && InDeepSleep()) { 193 if ((r == Monitor::kNotified) && InDeepSleep()) {
171 // Woken up from deep sleep. 194 // Woken up from deep sleep.
172 ASSERT(interrupted_thread_count == 0); 195 ASSERT(visitor.profiled_thread_count() == 0);
173 // Return to regular interrupts. 196 // Return to regular interrupts.
174 current_wait_time_ = interrupt_period_; 197 current_wait_time_ = interrupt_period_;
175 } 198 }
176 199
177 // Reset count before interrupting any threads. 200 // Reset count before visiting isolates.
178 interrupted_thread_count = 0; 201 visitor.set_profiled_thread_count(0);
202 Isolate::VisitIsolates(&visitor);
179 203
180 // Temporarily drop the monitor while we interrupt threads. 204 if (visitor.profiled_thread_count() == 0) {
181 monitor_->Exit(); 205 // No isolates were profiled. In order to reduce unnecessary CPU
182 206 // load, we will wait until we are notified before attempting to
183 { 207 // interrupt again.
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 // Take the monitor lock again.
195 monitor_->Enter();
196
197 // Now that we have the lock, check if we were signaled to wake up while
198 // interrupting threads.
199 if (!woken_up_ && (interrupted_thread_count == 0)) {
200 // No threads were interrupted and we were not signaled to interrupt
201 // new threads. In order to reduce unnecessary CPU load, we will wait
202 // until we are notified before attempting to interrupt again.
203 current_wait_time_ = Monitor::kNoTimeout; 208 current_wait_time_ = Monitor::kNoTimeout;
204 continue; 209 continue;
205 } 210 }
206 211
207 woken_up_ = false;
208
209 ASSERT(current_wait_time_ != Monitor::kNoTimeout); 212 ASSERT(current_wait_time_ != Monitor::kNoTimeout);
210 } 213 }
211 } 214 }
212 RemoveSignalHandler(); 215 RemoveSignalHandler();
213 if (FLAG_trace_thread_interrupter) { 216 if (FLAG_trace_thread_interrupter) {
214 OS::Print("ThreadInterrupter thread exiting.\n"); 217 OS::Print("ThreadInterrupter thread exiting.\n");
215 } 218 }
216 { 219 {
217 // Signal to main thread we are exiting. 220 // Signal to main thread we are exiting.
218 MonitorLocker shutdown_ml(monitor_); 221 MonitorLocker shutdown_ml(monitor_);
219 thread_running_ = false; 222 thread_running_ = false;
220 shutdown_ml.Notify(); 223 shutdown_ml.Notify();
221 } 224 }
222 } 225 }
223 226
224 } // namespace dart 227 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/thread_interrupter.h ('k') | runtime/vm/thread_interrupter_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698