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

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

Issue 1439483003: - Add an OSThread structure which is the generic TLS structure for all C++ (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address-comments 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
OLDNEW
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.
14 {
15 MonitorLocker ml(monitor_);
16 // At this point the mutator thread should be the only thread
17 // in the active list, delete it.
18 ASSERT(active_list_->next_ == NULL);
19 ASSERT(active_list_ == mutator_thread_);
20 delete mutator_thread_;
21 active_list_ = NULL;
22 mutator_thread_ = NULL;
23 // Now delete all the threads in the free list.
24 while (free_list_ != NULL) {
25 Thread* thread = free_list_;
26 free_list_ = thread->next_;
27 delete thread;
28 }
29 }
30
13 // Delete monitor. 31 // Delete monitor.
14 delete monitor_; 32 delete monitor_;
15 } 33 }
16 34
17 35
18 void ThreadRegistry::SafepointThreads() { 36 void ThreadRegistry::SafepointThreads() {
19 MonitorLocker ml(monitor_); 37 MonitorLocker ml(monitor_);
20 // First wait for any older rounds that are still in progress. 38 // First wait for any older rounds that are still in progress.
21 while (in_rendezvous_) { 39 while (in_rendezvous_) {
22 // Assert we are not the organizer trying to nest calls to SafepointThreads. 40 // Assert we are not the organizer trying to nest calls to SafepointThreads.
(...skipping 20 matching lines...) Expand all
43 61
44 62
45 void ThreadRegistry::ResumeAllThreads() { 63 void ThreadRegistry::ResumeAllThreads() {
46 MonitorLocker ml(monitor_); 64 MonitorLocker ml(monitor_);
47 ASSERT(in_rendezvous_); 65 ASSERT(in_rendezvous_);
48 in_rendezvous_ = false; 66 in_rendezvous_ = false;
49 ml.NotifyAll(); 67 ml.NotifyAll();
50 } 68 }
51 69
52 70
53 void ThreadRegistry::PruneThread(Thread* thread) { 71 Thread* ThreadRegistry::Schedule(Isolate* isolate,
72 bool is_mutator,
73 bool bypass_safepoint) {
54 MonitorLocker ml(monitor_); 74 MonitorLocker ml(monitor_);
55 intptr_t length = entries_.length(); 75 // Wait for any rendezvous in progress.
56 if (length == 0) { 76 while (!bypass_safepoint && in_rendezvous_) {
57 return; 77 ml.Wait(Monitor::kNoTimeout);
58 } 78 }
59 intptr_t found_index = -1; 79 Thread* thread = NULL;
60 for (intptr_t index = 0; index < length; index++) { 80 OSThread* os_thread = OSThread::Current();
61 if (entries_.At(index).thread == thread) { 81 ASSERT(os_thread != NULL);
62 found_index = index; 82 ASSERT(isolate->heap() != NULL);
63 break; 83 if (is_mutator) {
84 if (mutator_thread_ == NULL) {
85 mutator_thread_ = GetThreadFromFreelist(isolate);
64 } 86 }
87 thread = mutator_thread_;
88 } else {
89 thread = GetThreadFromFreelist(isolate);
65 } 90 }
66 if (found_index < 0) { 91 thread->isolate_ = isolate;
67 return; 92 thread->heap_ = isolate->heap();
68 } 93 thread->set_os_thread(os_thread);
69 entries_.RemoveAt(found_index); 94 os_thread->set_thread(thread);
95 Thread::SetCurrent(thread);
96 os_thread->EnableThreadInterrupts();
97 return thread;
70 } 98 }
71 99
72 100
73 ThreadRegistry::EntryIterator::EntryIterator(ThreadRegistry* registry) 101 void ThreadRegistry::Unschedule(Thread* thread,
74 : index_(0), 102 bool is_mutator,
75 registry_(NULL) { 103 bool bypass_safepoint) {
76 Reset(registry); 104 MonitorLocker ml(monitor_);
77 } 105 OSThread* os_thread = thread->os_thread();
78 106 ASSERT(os_thread != NULL);
79 107 os_thread->DisableThreadInterrupts();
80 ThreadRegistry::EntryIterator::~EntryIterator() { 108 thread->isolate_ = NULL;
81 Reset(NULL); 109 thread->heap_ = NULL;
82 } 110 thread->set_os_thread(NULL);
83 111 os_thread->set_thread(NULL);
84 112 OSThread::SetCurrent(os_thread);
85 void ThreadRegistry::EntryIterator::Reset(ThreadRegistry* registry) { 113 if (!is_mutator) {
86 // Reset index. 114 ReturnThreadToFreelist(thread);
87 index_ = 0;
88
89 // Unlock old registry.
90 if (registry_ != NULL) {
91 registry_->monitor_->Exit();
92 } 115 }
93 116 if (!bypass_safepoint && in_rendezvous_) {
94 registry_ = registry; 117 // Don't wait for this thread.
95 118 ASSERT(remaining_ > 0);
96 // Lock new registry. 119 if (--remaining_ == 0) {
97 if (registry_ != NULL) { 120 ml.NotifyAll();
98 registry_->monitor_->Enter(); 121 }
99 } 122 }
100 } 123 }
101 124
102 125
103 bool ThreadRegistry::EntryIterator::HasNext() const { 126 void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
104 if (registry_ == NULL) { 127 bool validate_frames) {
105 return false; 128 MonitorLocker ml(monitor_);
129 Thread* thread = active_list_;
130 while (thread != NULL) {
131 if (thread->zone() != NULL) {
132 thread->zone()->VisitObjectPointers(visitor);
133 }
134 thread->VisitObjectPointers(visitor);
135 // Iterate over all the stack frames and visit objects on the stack.
136 StackFrameIterator frames_iterator(thread->top_exit_frame_info(),
137 validate_frames);
138 StackFrame* frame = frames_iterator.NextFrame();
139 while (frame != NULL) {
140 frame->VisitObjectPointers(visitor);
141 frame = frames_iterator.NextFrame();
142 }
143 thread = thread->next_;
106 } 144 }
107 return index_ < registry_->entries_.length();
108 } 145 }
109 146
110 147
111 const ThreadRegistry::Entry& ThreadRegistry::EntryIterator::Next() { 148 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
112 ASSERT(HasNext()); 149 ASSERT(monitor_->IsOwnedByCurrentThread());
113 return registry_->entries_.At(index_++); 150 Thread* thread = NULL;
151 // Get thread structure from free list or create a new one.
152 if (free_list_ == NULL) {
153 thread = new Thread(isolate);
154 } else {
155 thread = free_list_;
156 free_list_ = thread->next_;
157 }
158 // Add thread to active list.
159 thread->next_ = active_list_;
160 active_list_ = thread;
161 return thread;
162 }
163
164 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
165 ASSERT(thread != NULL);
166 ASSERT(thread->os_thread_ == NULL);
167 ASSERT(thread->isolate_ == NULL);
168 ASSERT(thread->heap_ == NULL);
169 ASSERT(monitor_->IsOwnedByCurrentThread());
170 // First remove the thread from the active list.
171 Thread* prev = NULL;
172 Thread* iterator = active_list_;
173 while (iterator != NULL) {
Ivan Posva 2015/11/19 06:23:23 iterator is a weird name for this. How about using
siva 2015/11/19 20:54:05 Done.
174 if (iterator == thread) {
175 if (prev == NULL) {
176 active_list_ = iterator->next_;
177 } else {
178 prev->next_ = iterator->next_;
179 }
180 break;
181 }
182 prev = iterator;
183 iterator = iterator->next_;
184 }
185 // Now add thread to the free list.
186 thread->next_ = free_list_;
187 free_list_ = thread;
114 } 188 }
115 189
116 190
117 void ThreadRegistry::CheckSafepointLocked() { 191 void ThreadRegistry::CheckSafepointLocked() {
118 int64_t last_round = -1; 192 int64_t last_round = -1;
119 while (in_rendezvous_) { 193 while (in_rendezvous_) {
120 ASSERT(round_ >= last_round); 194 ASSERT(round_ >= last_round);
121 if (round_ != last_round) { 195 if (round_ != last_round) {
122 ASSERT((last_round == -1) || (round_ == (last_round + 1))); 196 ASSERT((last_round == -1) || (round_ == (last_round + 1)));
123 last_round = round_; 197 last_round = round_;
(...skipping 11 matching lines...) Expand all
135 // b) after ResumeAllThreads, another call to SafepointThreads was 209 // b) after ResumeAllThreads, another call to SafepointThreads was
136 // made before this thread got a chance to reaquire monitor_, thus this 210 // made before this thread got a chance to reaquire monitor_, thus this
137 // thread should (again) decrease remaining_ to indicate cooperation in 211 // thread should (again) decrease remaining_ to indicate cooperation in
138 // this new round. 212 // this new round.
139 } 213 }
140 } 214 }
141 215
142 216
143 intptr_t ThreadRegistry::CountScheduledLocked() { 217 intptr_t ThreadRegistry::CountScheduledLocked() {
144 intptr_t count = 0; 218 intptr_t count = 0;
145 for (int i = 0; i < entries_.length(); ++i) { 219 Thread* iterator = active_list_;
Ivan Posva 2015/11/19 06:23:23 ditto
siva 2015/11/19 20:54:05 Done.
146 const Entry& entry = entries_[i]; 220 while (iterator != NULL) {
147 if (entry.scheduled) { 221 ++count;
148 ++count; 222 iterator = iterator->next_;
149 }
150 } 223 }
151 return count; 224 return count;
152 } 225 }
153 226
154 } // namespace dart 227 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698