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.h

Issue 1292353004: Safepointing in GC (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Scavenger again. Created 5 years, 4 months 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 #ifndef VM_THREAD_REGISTRY_H_ 5 #ifndef VM_THREAD_REGISTRY_H_
6 #define VM_THREAD_REGISTRY_H_ 6 #define VM_THREAD_REGISTRY_H_
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #include "vm/growable_array.h" 9 #include "vm/growable_array.h"
10 #include "vm/isolate.h" 10 #include "vm/isolate.h"
11 #include "vm/lockers.h" 11 #include "vm/lockers.h"
12 #include "vm/stack_frame.h" 12 #include "vm/stack_frame.h"
13 #include "vm/thread.h" 13 #include "vm/thread.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 // Unordered collection of threads relating to a particular isolate. 17 // Unordered collection of threads relating to a particular isolate.
18 class ThreadRegistry { 18 class ThreadRegistry {
19 public: 19 public:
20 ThreadRegistry() 20 ThreadRegistry()
21 : monitor_(new Monitor()), 21 : monitor_(new Monitor()),
22 entries_(), 22 entries_(),
23 in_rendezvous_(false), 23 in_rendezvous_(false),
24 remaining_(0), 24 remaining_(0),
25 round_(0) {} 25 round_(0) {}
26 26
27 // Bring all threads in this isolate to a safepoint. The caller is 27 // Bring all threads in this isolate to a safepoint. The caller is
28 // expected to be implicitly at a safepoint. The threads will wait 28 // expected to be implicitly at a safepoint. The threads will wait
29 // until ResumeAllThreads is called. First participates in any 29 // until ResumeAllThreads is called. First participates in any
30 // already pending rendezvous requested by another thread. Any 30 // already pending rendezvous requested by another thread.
31 //
32 // Returns an identifier of this rendezvous, which can be passed to
33 // Thread::EnterIsolateAsHelper to allow the thread free passage in/out
34 // of the isolate while this rendezvous is in progress. Otherwise, any
31 // thread that tries to enter this isolate during rendezvous will 35 // thread that tries to enter this isolate during rendezvous will
32 // wait in RestoreStateTo. Nesting is not supported: the caller must 36 // wait in RestoreStateTo. Nesting is not supported: the caller must
33 // call ResumeAllThreads before making further calls to 37 // call ResumeAllThreads before making further calls to
34 // SafepointThreads. 38 // SafepointThreads.
35 void SafepointThreads(); 39 SafepointId SafepointThreads();
36 40
37 // Unblocks all threads participating in the rendezvous that was organized 41 // Unblocks all threads participating in the rendezvous that was organized
38 // by a prior call to SafepointThreads. 42 // by a prior call to SafepointThreads.
39 // TODO(koda): Consider adding a scope helper to avoid omitting this call. 43 // TODO(koda): Consider adding a scope helper to avoid omitting this call.
40 void ResumeAllThreads(); 44 void ResumeAllThreads();
41 45
42 // Indicate that the current thread is at a safepoint, and offer to wait for 46 // Indicate that the current thread is at a safepoint, and offer to wait for
43 // any pending rendezvous request (if none, returns immediately). 47 // any pending rendezvous request (if none, returns immediately).
44 void CheckSafepoint() { 48 void CheckSafepoint() {
45 MonitorLocker ml(monitor_); 49 MonitorLocker ml(monitor_);
46 CheckSafepointLocked(); 50 CheckSafepointLocked();
47 } 51 }
48 52
49 bool RestoreStateTo(Thread* thread, Thread::State* state) { 53 bool RestoreStateTo(Thread* thread, Thread::State* state) {
50 MonitorLocker ml(monitor_); 54 MonitorLocker ml(monitor_);
51 // Wait for any rendezvous in progress. 55 // Wait for any rendezvous in progress.
52 while (in_rendezvous_) { 56 while (IsParticipant(thread)) {
53 ml.Wait(Monitor::kNoTimeout); 57 ml.Wait(Monitor::kNoTimeout);
54 } 58 }
55 Entry* entry = FindEntry(thread); 59 Entry* entry = FindEntry(thread);
56 if (entry != NULL) { 60 if (entry != NULL) {
57 Thread::State st = entry->state; 61 Thread::State st = entry->state;
58 // TODO(koda): Support same thread re-entering same isolate with 62 // TODO(koda): Support same thread re-entering same isolate with
59 // Dart frames in between. For now, just assert it doesn't happen. 63 // Dart frames in between. For now, just assert it doesn't happen.
60 if (st.top_exit_frame_info != thread->top_exit_frame_info()) { 64 if (st.top_exit_frame_info != thread->top_exit_frame_info()) {
61 ASSERT(thread->top_exit_frame_info() == 0 || 65 ASSERT(thread->top_exit_frame_info() == 0 ||
62 thread->top_exit_frame_info() > st.top_exit_frame_info); 66 thread->top_exit_frame_info() > st.top_exit_frame_info);
(...skipping 18 matching lines...) Expand all
81 return false; 85 return false;
82 } 86 }
83 87
84 void SaveStateFrom(Thread* thread, const Thread::State& state) { 88 void SaveStateFrom(Thread* thread, const Thread::State& state) {
85 MonitorLocker ml(monitor_); 89 MonitorLocker ml(monitor_);
86 Entry* entry = FindEntry(thread); 90 Entry* entry = FindEntry(thread);
87 ASSERT(entry != NULL); 91 ASSERT(entry != NULL);
88 ASSERT(entry->scheduled); 92 ASSERT(entry->scheduled);
89 entry->scheduled = false; 93 entry->scheduled = false;
90 entry->state = state; 94 entry->state = state;
91 if (in_rendezvous_) { 95 if (IsParticipant(thread)) {
92 // Don't wait for this thread. 96 // Update count (don't wait for this thread when resuming).
93 ASSERT(remaining_ > 0); 97 ASSERT(remaining_ > 0);
94 if (--remaining_ == 0) { 98 if (--remaining_ == 0) {
95 ml.NotifyAll(); 99 ml.NotifyAll();
96 } 100 }
97 } 101 }
98 } 102 }
99 103
100 bool Contains(Thread* thread) { 104 bool Contains(Thread* thread) {
101 MonitorLocker ml(monitor_); 105 MonitorLocker ml(monitor_);
102 return (FindEntry(thread) != NULL); 106 return (FindEntry(thread) != NULL);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 if (entries_[i].thread == thread) { 155 if (entries_[i].thread == thread) {
152 return &entries_[i]; 156 return &entries_[i];
153 } 157 }
154 } 158 }
155 return NULL; 159 return NULL;
156 } 160 }
157 161
158 // Note: Lock should be taken before this function is called. 162 // Note: Lock should be taken before this function is called.
159 void CheckSafepointLocked(); 163 void CheckSafepointLocked();
160 164
161 // Returns the number threads that are scheduled on this isolate. 165 // Returns true if there is a rendezvous in progress and the given thread
162 // Note: Lock should be taken before this function is called. 166 // is/will be a participant of it.
163 intptr_t CountScheduledLocked(); 167 bool IsParticipant(Thread* thread) {
168 return in_rendezvous_ && (thread->pass_safepoint_ != round_);
169 }
164 170
165 Monitor* monitor_; // All access is synchronized through this monitor. 171 Monitor* monitor_; // All access is synchronized through this monitor.
166 MallocGrowableArray<Entry> entries_; 172 MallocGrowableArray<Entry> entries_;
167 173
168 // Safepoint rendezvous state. 174 // Safepoint rendezvous state.
169 bool in_rendezvous_; // A safepoint rendezvous request is in progress. 175 bool in_rendezvous_; // A safepoint rendezvous request is in progress.
170 intptr_t remaining_; // Number of threads yet to reach their safepoint. 176 intptr_t remaining_; // Number of threads yet to reach their safepoint.
171 int64_t round_; // Counter, to prevent missing updates to remaining_ 177 int64_t round_; // Counter, to prevent missing updates to remaining_
172 // (see comments in CheckSafepointLocked). 178 // (see comments in CheckSafepointLocked).
173 179
174 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); 180 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
175 }; 181 };
176 182
177 } // namespace dart 183 } // namespace dart
178 184
179 #endif // VM_THREAD_REGISTRY_H_ 185 #endif // VM_THREAD_REGISTRY_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698