OLD | NEW |
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 bool ThreadInterrupter::initialized_ = false; | 52 bool ThreadInterrupter::initialized_ = false; |
53 bool ThreadInterrupter::shutdown_ = false; | 53 bool ThreadInterrupter::shutdown_ = false; |
54 bool ThreadInterrupter::thread_running_ = false; | 54 bool ThreadInterrupter::thread_running_ = false; |
55 bool ThreadInterrupter::woken_up_ = false; | 55 bool ThreadInterrupter::woken_up_ = false; |
56 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ = | 56 ThreadJoinId ThreadInterrupter::interrupter_thread_id_ = |
57 OSThread::kInvalidThreadJoinId; | 57 OSThread::kInvalidThreadJoinId; |
58 Monitor* ThreadInterrupter::monitor_ = NULL; | 58 Monitor* ThreadInterrupter::monitor_ = NULL; |
59 intptr_t ThreadInterrupter::interrupt_period_ = 1000; | 59 intptr_t ThreadInterrupter::interrupt_period_ = 1000; |
60 intptr_t ThreadInterrupter::current_wait_time_ = Monitor::kNoTimeout; | 60 intptr_t ThreadInterrupter::current_wait_time_ = Monitor::kNoTimeout; |
61 | 61 |
62 | |
63 void ThreadInterrupter::InitOnce() { | 62 void ThreadInterrupter::InitOnce() { |
64 ASSERT(!initialized_); | 63 ASSERT(!initialized_); |
65 monitor_ = new Monitor(); | 64 monitor_ = new Monitor(); |
66 ASSERT(monitor_ != NULL); | 65 ASSERT(monitor_ != NULL); |
67 initialized_ = true; | 66 initialized_ = true; |
68 } | 67 } |
69 | 68 |
70 | |
71 void ThreadInterrupter::Startup() { | 69 void ThreadInterrupter::Startup() { |
72 ASSERT(initialized_); | 70 ASSERT(initialized_); |
73 if (IsDebuggerAttached()) { | 71 if (IsDebuggerAttached()) { |
74 MonitorLocker shutdown_ml(monitor_); | 72 MonitorLocker shutdown_ml(monitor_); |
75 shutdown_ = true; | 73 shutdown_ = true; |
76 if (FLAG_trace_thread_interrupter) { | 74 if (FLAG_trace_thread_interrupter) { |
77 OS::PrintErr( | 75 OS::PrintErr( |
78 "ThreadInterrupter disabled because a debugger is attached.\n"); | 76 "ThreadInterrupter disabled because a debugger is attached.\n"); |
79 } | 77 } |
80 return; | 78 return; |
81 } | 79 } |
82 if (FLAG_trace_thread_interrupter) { | 80 if (FLAG_trace_thread_interrupter) { |
83 OS::PrintErr("ThreadInterrupter starting up.\n"); | 81 OS::PrintErr("ThreadInterrupter starting up.\n"); |
84 } | 82 } |
85 ASSERT(interrupter_thread_id_ == OSThread::kInvalidThreadJoinId); | 83 ASSERT(interrupter_thread_id_ == OSThread::kInvalidThreadJoinId); |
86 { | 84 { |
87 MonitorLocker startup_ml(monitor_); | 85 MonitorLocker startup_ml(monitor_); |
88 OSThread::Start("ThreadInterrupter", ThreadMain, 0); | 86 OSThread::Start("ThreadInterrupter", ThreadMain, 0); |
89 while (!thread_running_) { | 87 while (!thread_running_) { |
90 startup_ml.Wait(); | 88 startup_ml.Wait(); |
91 } | 89 } |
92 } | 90 } |
93 ASSERT(interrupter_thread_id_ != OSThread::kInvalidThreadJoinId); | 91 ASSERT(interrupter_thread_id_ != OSThread::kInvalidThreadJoinId); |
94 if (FLAG_trace_thread_interrupter) { | 92 if (FLAG_trace_thread_interrupter) { |
95 OS::PrintErr("ThreadInterrupter running.\n"); | 93 OS::PrintErr("ThreadInterrupter running.\n"); |
96 } | 94 } |
97 } | 95 } |
98 | 96 |
99 | |
100 void ThreadInterrupter::Shutdown() { | 97 void ThreadInterrupter::Shutdown() { |
101 { | 98 { |
102 MonitorLocker shutdown_ml(monitor_); | 99 MonitorLocker shutdown_ml(monitor_); |
103 if (shutdown_) { | 100 if (shutdown_) { |
104 // Already shutdown. | 101 // Already shutdown. |
105 return; | 102 return; |
106 } | 103 } |
107 shutdown_ = true; | 104 shutdown_ = true; |
108 // Notify. | 105 // Notify. |
109 shutdown_ml.Notify(); | 106 shutdown_ml.Notify(); |
110 ASSERT(initialized_); | 107 ASSERT(initialized_); |
111 if (FLAG_trace_thread_interrupter) { | 108 if (FLAG_trace_thread_interrupter) { |
112 OS::PrintErr("ThreadInterrupter shutting down.\n"); | 109 OS::PrintErr("ThreadInterrupter shutting down.\n"); |
113 } | 110 } |
114 } | 111 } |
115 | 112 |
116 // Join the thread. | 113 // Join the thread. |
117 ASSERT(interrupter_thread_id_ != OSThread::kInvalidThreadJoinId); | 114 ASSERT(interrupter_thread_id_ != OSThread::kInvalidThreadJoinId); |
118 OSThread::Join(interrupter_thread_id_); | 115 OSThread::Join(interrupter_thread_id_); |
119 interrupter_thread_id_ = OSThread::kInvalidThreadJoinId; | 116 interrupter_thread_id_ = OSThread::kInvalidThreadJoinId; |
120 | 117 |
121 if (FLAG_trace_thread_interrupter) { | 118 if (FLAG_trace_thread_interrupter) { |
122 OS::PrintErr("ThreadInterrupter shut down.\n"); | 119 OS::PrintErr("ThreadInterrupter shut down.\n"); |
123 } | 120 } |
124 } | 121 } |
125 | 122 |
126 | |
127 // Delay between interrupts. | 123 // Delay between interrupts. |
128 void ThreadInterrupter::SetInterruptPeriod(intptr_t period) { | 124 void ThreadInterrupter::SetInterruptPeriod(intptr_t period) { |
129 if (shutdown_) { | 125 if (shutdown_) { |
130 return; | 126 return; |
131 } | 127 } |
132 ASSERT(initialized_); | 128 ASSERT(initialized_); |
133 ASSERT(period > 0); | 129 ASSERT(period > 0); |
134 interrupt_period_ = period; | 130 interrupt_period_ = period; |
135 } | 131 } |
136 | 132 |
137 | |
138 void ThreadInterrupter::WakeUp() { | 133 void ThreadInterrupter::WakeUp() { |
139 if (!initialized_) { | 134 if (!initialized_) { |
140 // Early call. | 135 // Early call. |
141 return; | 136 return; |
142 } | 137 } |
143 ASSERT(initialized_); | 138 ASSERT(initialized_); |
144 { | 139 { |
145 MonitorLocker ml(monitor_); | 140 MonitorLocker ml(monitor_); |
146 woken_up_ = true; | 141 woken_up_ = true; |
147 if (!InDeepSleep()) { | 142 if (!InDeepSleep()) { |
148 // No need to notify, regularly waking up. | 143 // No need to notify, regularly waking up. |
149 return; | 144 return; |
150 } | 145 } |
151 // Notify the interrupter to wake it from its deep sleep. | 146 // Notify the interrupter to wake it from its deep sleep. |
152 ml.Notify(); | 147 ml.Notify(); |
153 } | 148 } |
154 } | 149 } |
155 | 150 |
156 | |
157 void ThreadInterrupter::ThreadMain(uword parameters) { | 151 void ThreadInterrupter::ThreadMain(uword parameters) { |
158 ASSERT(initialized_); | 152 ASSERT(initialized_); |
159 InstallSignalHandler(); | 153 InstallSignalHandler(); |
160 if (FLAG_trace_thread_interrupter) { | 154 if (FLAG_trace_thread_interrupter) { |
161 OS::PrintErr("ThreadInterrupter thread running.\n"); | 155 OS::PrintErr("ThreadInterrupter thread running.\n"); |
162 } | 156 } |
163 { | 157 { |
164 // Signal to main thread we are ready. | 158 // Signal to main thread we are ready. |
165 MonitorLocker startup_ml(monitor_); | 159 MonitorLocker startup_ml(monitor_); |
166 OSThread* os_thread = OSThread::Current(); | 160 OSThread* os_thread = OSThread::Current(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 // Signal to main thread we are exiting. | 224 // Signal to main thread we are exiting. |
231 MonitorLocker shutdown_ml(monitor_); | 225 MonitorLocker shutdown_ml(monitor_); |
232 thread_running_ = false; | 226 thread_running_ = false; |
233 shutdown_ml.Notify(); | 227 shutdown_ml.Notify(); |
234 } | 228 } |
235 } | 229 } |
236 | 230 |
237 #endif // !PRODUCT | 231 #endif // !PRODUCT |
238 | 232 |
239 } // namespace dart | 233 } // namespace dart |
OLD | NEW |