OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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_registry.h" | 5 #include "vm/thread_registry.h" |
6 | 6 |
7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
11 | 11 |
12 ThreadRegistry::~ThreadRegistry() { | 12 ThreadRegistry::~ThreadRegistry() { |
13 // Go over the free thread list and delete the thread objects. | 13 // Go over the free thread list and delete the thread objects. |
14 { | 14 { |
15 MonitorLocker ml(monitor_); | 15 MonitorLocker ml(monitor_); |
16 // At this point the mutator thread should be the only thread | 16 // At this point the active list should be empty. |
17 // in the active list, delete it. | 17 ASSERT(active_list_ == NULL); |
18 ASSERT(active_list_->next_ == NULL); | 18 // We have cached the mutator thread, delete it. |
19 ASSERT(active_list_ == mutator_thread_); | |
20 delete mutator_thread_; | 19 delete mutator_thread_; |
21 active_list_ = NULL; | |
22 mutator_thread_ = NULL; | 20 mutator_thread_ = NULL; |
23 // Now delete all the threads in the free list. | 21 // Now delete all the threads in the free list. |
24 while (free_list_ != NULL) { | 22 while (free_list_ != NULL) { |
25 Thread* thread = free_list_; | 23 Thread* thread = free_list_; |
26 free_list_ = thread->next_; | 24 free_list_ = thread->next_; |
27 delete thread; | 25 delete thread; |
28 } | 26 } |
29 } | 27 } |
30 | 28 |
31 // Delete monitor. | 29 // Delete monitor. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 bool bypass_safepoint) { | 71 bool bypass_safepoint) { |
74 MonitorLocker ml(monitor_); | 72 MonitorLocker ml(monitor_); |
75 // Wait for any rendezvous in progress. | 73 // Wait for any rendezvous in progress. |
76 while (!bypass_safepoint && in_rendezvous_) { | 74 while (!bypass_safepoint && in_rendezvous_) { |
77 ml.Wait(Monitor::kNoTimeout); | 75 ml.Wait(Monitor::kNoTimeout); |
78 } | 76 } |
79 Thread* thread = NULL; | 77 Thread* thread = NULL; |
80 OSThread* os_thread = OSThread::Current(); | 78 OSThread* os_thread = OSThread::Current(); |
81 ASSERT(os_thread != NULL); | 79 ASSERT(os_thread != NULL); |
82 ASSERT(isolate->heap() != NULL); | 80 ASSERT(isolate->heap() != NULL); |
| 81 // First get a Thread structure. (we special case the mutator thread |
| 82 // by reusing the cached structure, see comment in 'thread_registry.h'). |
83 if (is_mutator) { | 83 if (is_mutator) { |
84 if (mutator_thread_ == NULL) { | 84 if (mutator_thread_ == NULL) { |
85 mutator_thread_ = GetThreadFromFreelist(isolate); | 85 mutator_thread_ = GetThreadFromFreelist(isolate); |
86 } | 86 } |
87 thread = mutator_thread_; | 87 thread = mutator_thread_; |
88 } else { | 88 } else { |
89 thread = GetThreadFromFreelist(isolate); | 89 thread = GetThreadFromFreelist(isolate); |
90 ASSERT(thread->api_top_scope() == NULL); | 90 ASSERT(thread->api_top_scope() == NULL); |
91 } | 91 } |
| 92 // Now add this Thread to the active list for the isolate. |
| 93 AddThreadToActiveList(thread); |
| 94 // Set up other values and set the TLS value. |
92 thread->isolate_ = isolate; | 95 thread->isolate_ = isolate; |
93 thread->heap_ = isolate->heap(); | 96 thread->heap_ = isolate->heap(); |
94 thread->set_os_thread(os_thread); | 97 thread->set_os_thread(os_thread); |
95 os_thread->set_thread(thread); | 98 os_thread->set_thread(thread); |
96 Thread::SetCurrent(thread); | 99 Thread::SetCurrent(thread); |
97 os_thread->EnableThreadInterrupts(); | 100 os_thread->EnableThreadInterrupts(); |
98 return thread; | 101 return thread; |
99 } | 102 } |
100 | 103 |
101 | 104 |
102 void ThreadRegistry::Unschedule(Thread* thread, | 105 void ThreadRegistry::Unschedule(Thread* thread, |
103 bool is_mutator, | 106 bool is_mutator, |
104 bool bypass_safepoint) { | 107 bool bypass_safepoint) { |
105 MonitorLocker ml(monitor_); | 108 MonitorLocker ml(monitor_); |
106 OSThread* os_thread = thread->os_thread(); | 109 OSThread* os_thread = thread->os_thread(); |
107 ASSERT(os_thread != NULL); | 110 ASSERT(os_thread != NULL); |
108 os_thread->DisableThreadInterrupts(); | 111 os_thread->DisableThreadInterrupts(); |
109 os_thread->set_thread(NULL); | 112 os_thread->set_thread(NULL); |
110 OSThread::SetCurrent(os_thread); | 113 OSThread::SetCurrent(os_thread); |
111 thread->isolate_ = NULL; | 114 thread->isolate_ = NULL; |
112 thread->heap_ = NULL; | 115 thread->heap_ = NULL; |
113 thread->set_os_thread(NULL); | 116 thread->set_os_thread(NULL); |
| 117 // Remove thread from the active list for the isolate. |
| 118 RemoveThreadFromActiveList(thread); |
| 119 // Return thread to the free list (we special case the mutator |
| 120 // thread by holding on to it, see comment in 'thread_registry.h'). |
114 if (!is_mutator) { | 121 if (!is_mutator) { |
115 ASSERT(thread->api_top_scope() == NULL); | 122 ASSERT(thread->api_top_scope() == NULL); |
116 ReturnThreadToFreelist(thread); | 123 ReturnThreadToFreelist(thread); |
117 } | 124 } |
118 if (!bypass_safepoint && in_rendezvous_) { | 125 if (!bypass_safepoint && in_rendezvous_) { |
119 // Don't wait for this thread. | 126 // Don't wait for this thread. |
120 ASSERT(remaining_ > 0); | 127 ASSERT(remaining_ > 0); |
121 if (--remaining_ == 0) { | 128 if (--remaining_ == 0) { |
122 ml.NotifyAll(); | 129 ml.NotifyAll(); |
123 } | 130 } |
(...skipping 16 matching lines...) Expand all Loading... |
140 StackFrame* frame = frames_iterator.NextFrame(); | 147 StackFrame* frame = frames_iterator.NextFrame(); |
141 while (frame != NULL) { | 148 while (frame != NULL) { |
142 frame->VisitObjectPointers(visitor); | 149 frame->VisitObjectPointers(visitor); |
143 frame = frames_iterator.NextFrame(); | 150 frame = frames_iterator.NextFrame(); |
144 } | 151 } |
145 thread = thread->next_; | 152 thread = thread->next_; |
146 } | 153 } |
147 } | 154 } |
148 | 155 |
149 | 156 |
150 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) { | 157 void ThreadRegistry::AddThreadToActiveList(Thread* thread) { |
| 158 ASSERT(thread != NULL); |
151 ASSERT(monitor_->IsOwnedByCurrentThread()); | 159 ASSERT(monitor_->IsOwnedByCurrentThread()); |
152 Thread* thread = NULL; | |
153 // Get thread structure from free list or create a new one. | |
154 if (free_list_ == NULL) { | |
155 thread = new Thread(isolate); | |
156 } else { | |
157 thread = free_list_; | |
158 free_list_ = thread->next_; | |
159 } | |
160 // Add thread to active list. | |
161 thread->next_ = active_list_; | 160 thread->next_ = active_list_; |
162 active_list_ = thread; | 161 active_list_ = thread; |
163 return thread; | |
164 } | 162 } |
165 | 163 |
166 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) { | 164 |
| 165 void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) { |
167 ASSERT(thread != NULL); | 166 ASSERT(thread != NULL); |
168 ASSERT(thread->os_thread_ == NULL); | |
169 ASSERT(thread->isolate_ == NULL); | |
170 ASSERT(thread->heap_ == NULL); | |
171 ASSERT(monitor_->IsOwnedByCurrentThread()); | 167 ASSERT(monitor_->IsOwnedByCurrentThread()); |
172 // First remove the thread from the active list. | |
173 Thread* prev = NULL; | 168 Thread* prev = NULL; |
174 Thread* current = active_list_; | 169 Thread* current = active_list_; |
175 while (current != NULL) { | 170 while (current != NULL) { |
176 if (current == thread) { | 171 if (current == thread) { |
177 if (prev == NULL) { | 172 if (prev == NULL) { |
178 active_list_ = current->next_; | 173 active_list_ = current->next_; |
179 } else { | 174 } else { |
180 prev->next_ = current->next_; | 175 prev->next_ = current->next_; |
181 } | 176 } |
182 break; | 177 break; |
183 } | 178 } |
184 prev = current; | 179 prev = current; |
185 current = current->next_; | 180 current = current->next_; |
186 } | 181 } |
187 // Now add thread to the free list. | 182 } |
| 183 |
| 184 |
| 185 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) { |
| 186 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 187 Thread* thread = NULL; |
| 188 // Get thread structure from free list or create a new one. |
| 189 if (free_list_ == NULL) { |
| 190 thread = new Thread(isolate); |
| 191 } else { |
| 192 thread = free_list_; |
| 193 free_list_ = thread->next_; |
| 194 } |
| 195 return thread; |
| 196 } |
| 197 |
| 198 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) { |
| 199 ASSERT(thread != NULL); |
| 200 ASSERT(thread->os_thread_ == NULL); |
| 201 ASSERT(thread->isolate_ == NULL); |
| 202 ASSERT(thread->heap_ == NULL); |
| 203 ASSERT(monitor_->IsOwnedByCurrentThread()); |
| 204 // Add thread to the free list. |
188 thread->next_ = free_list_; | 205 thread->next_ = free_list_; |
189 free_list_ = thread; | 206 free_list_ = thread; |
190 } | 207 } |
191 | 208 |
192 | 209 |
193 void ThreadRegistry::CheckSafepointLocked() { | 210 void ThreadRegistry::CheckSafepointLocked() { |
194 int64_t last_round = -1; | 211 int64_t last_round = -1; |
195 while (in_rendezvous_) { | 212 while (in_rendezvous_) { |
196 ASSERT(round_ >= last_round); | 213 ASSERT(round_ >= last_round); |
197 if (round_ != last_round) { | 214 if (round_ != last_round) { |
(...skipping 22 matching lines...) Expand all Loading... |
220 intptr_t count = 0; | 237 intptr_t count = 0; |
221 Thread* current = active_list_; | 238 Thread* current = active_list_; |
222 while (current != NULL) { | 239 while (current != NULL) { |
223 ++count; | 240 ++count; |
224 current = current->next_; | 241 current = current->next_; |
225 } | 242 } |
226 return count; | 243 return count; |
227 } | 244 } |
228 | 245 |
229 } // namespace dart | 246 } // namespace dart |
OLD | NEW |