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

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

Issue 1271773003: Allow threads to exit an isolate during rendezvous. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Another assertion. 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
« no previous file with comments | « no previous file | runtime/vm/thread_registry.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/thread.h" 12 #include "vm/thread.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 // Unordered collection of threads relating to a particular isolate. 16 // Unordered collection of threads relating to a particular isolate.
17 class ThreadRegistry { 17 class ThreadRegistry {
18 public: 18 public:
19 ThreadRegistry() 19 ThreadRegistry()
20 : monitor_(new Monitor()), 20 : monitor_(new Monitor()),
21 entries_(), 21 entries_(),
22 in_rendezvous_(false), 22 in_rendezvous_(false),
23 remaining_(0), 23 remaining_(0),
24 round_(0) {} 24 round_(0) {}
25 25
26 // Bring all threads in this isolate to a safepoint. The caller is 26 // Bring all threads in this isolate to a safepoint. The caller is
27 // expected to be implicitly at a safepoint. The threads will wait 27 // expected to be implicitly at a safepoint. The threads will wait
28 // until ResumeAllThreads is called. Must be called at a safepoint, 28 // until ResumeAllThreads is called. First participates in any
29 // since it first waits for any already pending requests. Any thread 29 // already pending rendezvous requested by another thread. Any
30 // that tries to enter/exit this isolate during rendezvous will wait 30 // thread that tries to enter this isolate during rendezvous will
31 // in RestoreStateTo/SaveStateFrom, respectively. 31 // wait in RestoreStateTo. Nesting is not supported: the caller must
32 // call ResumeAllThreads before making further calls to
33 // SafepointThreads.
32 void SafepointThreads(); 34 void SafepointThreads();
33 35
34 // Unblocks all threads participating in the rendezvous that was organized 36 // Unblocks all threads participating in the rendezvous that was organized
35 // by a prior call to SafepointThreads. 37 // by a prior call to SafepointThreads.
36 // TODO(koda): Consider adding a scope helper to avoid omitting this call. 38 // TODO(koda): Consider adding a scope helper to avoid omitting this call.
37 void ResumeAllThreads(); 39 void ResumeAllThreads();
38 40
39 // Indicate that the current thread is at a safepoint, and offer to wait for 41 // Indicate that the current thread is at a safepoint, and offer to wait for
40 // any pending rendezvous request (if none, returns immediately). 42 // any pending rendezvous request (if none, returns immediately).
41 void CheckSafepoint() { 43 void CheckSafepoint() {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 #if defined(DEBUG) 75 #if defined(DEBUG)
74 // State field is not in use, so zap it. 76 // State field is not in use, so zap it.
75 memset(&new_entry.state, 0xda, sizeof(new_entry.state)); 77 memset(&new_entry.state, 0xda, sizeof(new_entry.state));
76 #endif 78 #endif
77 entries_.Add(new_entry); 79 entries_.Add(new_entry);
78 return false; 80 return false;
79 } 81 }
80 82
81 void SaveStateFrom(Thread* thread, const Thread::State& state) { 83 void SaveStateFrom(Thread* thread, const Thread::State& state) {
82 MonitorLocker ml(monitor_); 84 MonitorLocker ml(monitor_);
83 // Exiting an isolate must always be a safepoint.
84 CheckSafepointLocked();
85 Entry* entry = FindEntry(thread); 85 Entry* entry = FindEntry(thread);
86 ASSERT(entry != NULL); 86 ASSERT(entry != NULL);
87 ASSERT(entry->scheduled); 87 ASSERT(entry->scheduled);
88 entry->scheduled = false; 88 entry->scheduled = false;
89 entry->state = state; 89 entry->state = state;
90 if (in_rendezvous_) {
91 // Don't wait for this thread.
92 ASSERT(remaining_ > 0);
93 if (--remaining_ == 0) {
94 ml.NotifyAll();
95 }
96 }
90 } 97 }
91 98
92 bool Contains(Thread* thread) { 99 bool Contains(Thread* thread) {
93 MonitorLocker ml(monitor_); 100 MonitorLocker ml(monitor_);
94 return (FindEntry(thread) != NULL); 101 return (FindEntry(thread) != NULL);
95 } 102 }
96 103
97 void CheckNotScheduled(Isolate* isolate) { 104 void CheckNotScheduled(Isolate* isolate) {
98 MonitorLocker ml(monitor_); 105 MonitorLocker ml(monitor_);
99 for (int i = 0; i < entries_.length(); ++i) { 106 for (int i = 0; i < entries_.length(); ++i) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 intptr_t remaining_; // Number of threads yet to reach their safepoint. 159 intptr_t remaining_; // Number of threads yet to reach their safepoint.
153 int64_t round_; // Counter, to prevent missing updates to remaining_ 160 int64_t round_; // Counter, to prevent missing updates to remaining_
154 // (see comments in CheckSafepointLocked). 161 // (see comments in CheckSafepointLocked).
155 162
156 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); 163 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
157 }; 164 };
158 165
159 } // namespace dart 166 } // namespace dart
160 167
161 #endif // VM_THREAD_REGISTRY_H_ 168 #endif // VM_THREAD_REGISTRY_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/thread_registry.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698