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

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: tweak-comment 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 Thread::SetCurrent(thread);
95 os_thread->EnableThreadInterrupts();
96 return thread;
70 } 97 }
71 98
72 99
73 ThreadRegistry::EntryIterator::EntryIterator(ThreadRegistry* registry) 100 void ThreadRegistry::Unschedule(Thread* thread,
74 : index_(0), 101 bool is_mutator,
75 registry_(NULL) { 102 bool bypass_safepoint) {
76 Reset(registry); 103 MonitorLocker ml(monitor_);
77 } 104 OSThread* os_thread = thread->os_thread();
78 105 ASSERT(os_thread != NULL);
79 106 os_thread->DisableThreadInterrupts();
80 ThreadRegistry::EntryIterator::~EntryIterator() { 107 thread->isolate_ = NULL;
81 Reset(NULL); 108 thread->heap_ = NULL;
82 } 109 thread->set_os_thread(NULL);
83 110 OSThread::SetCurrent(os_thread);
84 111 if (!is_mutator) {
85 void ThreadRegistry::EntryIterator::Reset(ThreadRegistry* registry) { 112 ReturnThreadToFreelist(thread);
86 // Reset index.
87 index_ = 0;
88
89 // Unlock old registry.
90 if (registry_ != NULL) {
91 registry_->monitor_->Exit();
92 } 113 }
93 114 if (!bypass_safepoint && in_rendezvous_) {
94 registry_ = registry; 115 // Don't wait for this thread.
95 116 ASSERT(remaining_ > 0);
96 // Lock new registry. 117 if (--remaining_ == 0) {
97 if (registry_ != NULL) { 118 ml.NotifyAll();
98 registry_->monitor_->Enter(); 119 }
99 } 120 }
100 } 121 }
101 122
102 123
103 bool ThreadRegistry::EntryIterator::HasNext() const { 124 void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
104 if (registry_ == NULL) { 125 bool validate_frames) {
105 return false; 126 MonitorLocker ml(monitor_);
127 Thread* thread = active_list_;
128 while (thread != NULL) {
129 if (thread->zone() != NULL) {
130 thread->zone()->VisitObjectPointers(visitor);
131 }
132 thread->VisitObjectPointers(visitor);
133 // Iterate over all the stack frames and visit objects on the stack.
134 StackFrameIterator frames_iterator(thread->top_exit_frame_info(),
135 validate_frames);
136 StackFrame* frame = frames_iterator.NextFrame();
137 while (frame != NULL) {
138 frame->VisitObjectPointers(visitor);
139 frame = frames_iterator.NextFrame();
140 }
141 thread = thread->next_;
106 } 142 }
107 return index_ < registry_->entries_.length();
108 } 143 }
109 144
110 145
111 const ThreadRegistry::Entry& ThreadRegistry::EntryIterator::Next() { 146 Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
112 ASSERT(HasNext()); 147 ASSERT(monitor_->IsOwnedByCurrentThread());
113 return registry_->entries_.At(index_++); 148 Thread* thread = NULL;
149 // Get thread structure from free list or create a new one.
150 if (free_list_ == NULL) {
151 thread = new Thread(isolate);
152 } else {
153 thread = free_list_;
154 free_list_ = thread->next_;
155 }
156 // Add thread to active list.
157 thread->next_ = active_list_;
158 active_list_ = thread;
159 return thread;
160 }
161
162 void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
163 ASSERT(thread != NULL);
164 ASSERT(thread->os_thread_ == NULL);
165 ASSERT(thread->isolate_ == NULL);
166 ASSERT(thread->heap_ == NULL);
167 ASSERT(monitor_->IsOwnedByCurrentThread());
168 // First remove the thread from the active list.
169 Thread* prev = NULL;
170 Thread* iterator = active_list_;
171 while (iterator != NULL) {
172 if (iterator == thread) {
173 if (prev == NULL) {
174 active_list_ = iterator->next_;
175 } else {
176 prev->next_ = iterator->next_;
177 }
178 break;
179 }
180 prev = iterator;
181 iterator = iterator->next_;
182 }
183 // Now add thread to the free list.
184 thread->next_ = free_list_;
185 free_list_ = thread;
114 } 186 }
115 187
116 188
117 void ThreadRegistry::CheckSafepointLocked() { 189 void ThreadRegistry::CheckSafepointLocked() {
118 int64_t last_round = -1; 190 int64_t last_round = -1;
119 while (in_rendezvous_) { 191 while (in_rendezvous_) {
120 ASSERT(round_ >= last_round); 192 ASSERT(round_ >= last_round);
121 if (round_ != last_round) { 193 if (round_ != last_round) {
122 ASSERT((last_round == -1) || (round_ == (last_round + 1))); 194 ASSERT((last_round == -1) || (round_ == (last_round + 1)));
123 last_round = round_; 195 last_round = round_;
(...skipping 11 matching lines...) Expand all
135 // b) after ResumeAllThreads, another call to SafepointThreads was 207 // b) after ResumeAllThreads, another call to SafepointThreads was
136 // made before this thread got a chance to reaquire monitor_, thus this 208 // made before this thread got a chance to reaquire monitor_, thus this
137 // thread should (again) decrease remaining_ to indicate cooperation in 209 // thread should (again) decrease remaining_ to indicate cooperation in
138 // this new round. 210 // this new round.
139 } 211 }
140 } 212 }
141 213
142 214
143 intptr_t ThreadRegistry::CountScheduledLocked() { 215 intptr_t ThreadRegistry::CountScheduledLocked() {
144 intptr_t count = 0; 216 intptr_t count = 0;
145 for (int i = 0; i < entries_.length(); ++i) { 217 Thread* iterator = active_list_;
146 const Entry& entry = entries_[i]; 218 while (iterator != NULL) {
147 if (entry.scheduled) { 219 ++count;
148 ++count; 220 iterator = iterator->next_;
149 }
150 } 221 }
151 return count; 222 return count;
152 } 223 }
153 224
154 } // namespace dart 225 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698