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

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

Issue 2126413002: Allow for recursive invocation of SafepointOperationScopes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address code review comments. Created 4 years, 5 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 | « runtime/vm/safepoint.h ('k') | runtime/vm/thread_test.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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/safepoint.h" 5 #include "vm/safepoint.h"
6 6
7 #include "vm/thread.h" 7 #include "vm/thread.h"
8 #include "vm/thread_registry.h" 8 #include "vm/thread_registry.h"
9 9
10 namespace dart { 10 namespace dart {
(...skipping 23 matching lines...) Expand all
34 SafepointHandler* handler = I->safepoint_handler(); 34 SafepointHandler* handler = I->safepoint_handler();
35 ASSERT(handler != NULL); 35 ASSERT(handler != NULL);
36 handler->ResumeThreads(T); 36 handler->ResumeThreads(T);
37 } 37 }
38 38
39 39
40 SafepointHandler::SafepointHandler(Isolate* isolate) 40 SafepointHandler::SafepointHandler(Isolate* isolate)
41 : isolate_(isolate), 41 : isolate_(isolate),
42 safepoint_lock_(new Monitor()), 42 safepoint_lock_(new Monitor()),
43 number_threads_not_at_safepoint_(0), 43 number_threads_not_at_safepoint_(0),
44 safepoint_in_progress_(false) { 44 safepoint_operation_count_(0),
45 owner_(NULL) {
45 } 46 }
46 47
47 48
48 SafepointHandler::~SafepointHandler() { 49 SafepointHandler::~SafepointHandler() {
49 ASSERT(safepoint_in_progress_ == false); 50 ASSERT(owner_ == NULL);
51 ASSERT(safepoint_operation_count_ == 0);
50 delete safepoint_lock_; 52 delete safepoint_lock_;
51 safepoint_lock_ = NULL; 53 safepoint_lock_ = NULL;
52 isolate_ = NULL; 54 isolate_ = NULL;
53 } 55 }
54 56
55 57
56 void SafepointHandler::SafepointThreads(Thread* T) { 58 void SafepointHandler::SafepointThreads(Thread* T) {
57 { 59 {
58 // First grab the threads list lock for this isolate 60 // First grab the threads list lock for this isolate
59 // and check if a safepoint is already in progress. This 61 // and check if a safepoint is already in progress. This
60 // ensures that two threads do not start a safepoint operation 62 // ensures that two threads do not start a safepoint operation
61 // at the same time. 63 // at the same time.
62 MonitorLocker sl(threads_lock()); 64 MonitorLocker sl(threads_lock());
63 65
64 // Now check to see if a safepoint operation is already in progress 66 // Now check to see if a safepoint operation is already in progress
65 // for this isolate, block if an operation is in progress. 67 // for this isolate, block if an operation is in progress.
66 while (safepoint_in_progress()) { 68 while (SafepointInProgress()) {
69 // If we are recursively invoking a Safepoint operation then we
70 // just increment the count and return, otherwise we wait for the
71 // safepoint operation to be done.
72 if (owner_ == T) {
73 increment_safepoint_operation_count();
74 return;
75 }
67 sl.WaitWithSafepointCheck(T); 76 sl.WaitWithSafepointCheck(T);
68 } 77 }
69 78
70 // Set safepoint in progress by this thread. 79 // Set safepoint in progress state by this thread.
71 set_safepoint_in_progress(true); 80 SetSafepointInProgress(T);
72 81
73 // Go over the active thread list and ensure that all threads active 82 // Go over the active thread list and ensure that all threads active
74 // in the isolate reach a safepoint. 83 // in the isolate reach a safepoint.
75 Thread* current = isolate()->thread_registry()->active_list(); 84 Thread* current = isolate()->thread_registry()->active_list();
76 while (current != NULL) { 85 while (current != NULL) {
77 MonitorLocker tl(current->thread_lock()); 86 MonitorLocker tl(current->thread_lock());
78 if (current != T) { 87 if (current != T) {
79 uint32_t state = current->SetSafepointRequested(true); 88 uint32_t state = current->SetSafepointRequested(true);
80 if (!Thread::IsAtSafepoint(state)) { 89 if (!Thread::IsAtSafepoint(state)) {
81 // Thread is not already at a safepoint so try to 90 // Thread is not already at a safepoint so try to
(...skipping 25 matching lines...) Expand all
107 } 116 }
108 } 117 }
109 } 118 }
110 } 119 }
111 120
112 121
113 void SafepointHandler::ResumeThreads(Thread* T) { 122 void SafepointHandler::ResumeThreads(Thread* T) {
114 // First resume all the threads which are blocked for the safepoint 123 // First resume all the threads which are blocked for the safepoint
115 // operation. 124 // operation.
116 MonitorLocker sl(threads_lock()); 125 MonitorLocker sl(threads_lock());
126
127 // First check if we are in a recursive safepoint operation, in that case
128 // we just decrement safepoint_operation_count and return.
129 ASSERT(SafepointInProgress());
130 if (safepoint_operation_count() > 1) {
131 decrement_safepoint_operation_count();
132 return;
133 }
117 Thread* current = isolate()->thread_registry()->active_list(); 134 Thread* current = isolate()->thread_registry()->active_list();
118 while (current != NULL) { 135 while (current != NULL) {
119 MonitorLocker tl(current->thread_lock()); 136 MonitorLocker tl(current->thread_lock());
120 if (current != T) { 137 if (current != T) {
121 uint32_t state = current->SetSafepointRequested(false); 138 uint32_t state = current->SetSafepointRequested(false);
122 if (Thread::IsBlockedForSafepoint(state)) { 139 if (Thread::IsBlockedForSafepoint(state)) {
123 tl.Notify(); 140 tl.Notify();
124 } 141 }
125 } else { 142 } else {
126 current->SetAtSafepoint(false); 143 current->SetAtSafepoint(false);
127 } 144 }
128 current = current->next(); 145 current = current->next();
129 } 146 }
130 // Now set the safepoint_in_progress_ flag to false and notify all threads 147 // Now reset the safepoint_in_progress_ state and notify all threads
131 // that are waiting to enter the isolate or waiting to start another 148 // that are waiting to enter the isolate or waiting to start another
132 // safepoint operation. 149 // safepoint operation.
133 set_safepoint_in_progress(false); 150 ResetSafepointInProgress(T);
134 sl.NotifyAll(); 151 sl.NotifyAll();
135 } 152 }
136 153
137 154
138 void SafepointHandler::EnterSafepointUsingLock(Thread* T) { 155 void SafepointHandler::EnterSafepointUsingLock(Thread* T) {
139 MonitorLocker tl(T->thread_lock()); 156 MonitorLocker tl(T->thread_lock());
140 T->SetAtSafepoint(true); 157 T->SetAtSafepoint(true);
141 if (T->IsSafepointRequested()) { 158 if (T->IsSafepointRequested()) {
142 MonitorLocker sl(safepoint_lock_); 159 MonitorLocker sl(safepoint_lock_);
143 ASSERT(number_threads_not_at_safepoint_ > 0); 160 ASSERT(number_threads_not_at_safepoint_ > 0);
(...skipping 28 matching lines...) Expand all
172 while (T->IsSafepointRequested()) { 189 while (T->IsSafepointRequested()) {
173 T->SetBlockedForSafepoint(true); 190 T->SetBlockedForSafepoint(true);
174 tl.Wait(); 191 tl.Wait();
175 T->SetBlockedForSafepoint(false); 192 T->SetBlockedForSafepoint(false);
176 } 193 }
177 T->SetAtSafepoint(false); 194 T->SetAtSafepoint(false);
178 } 195 }
179 } 196 }
180 197
181 } // namespace dart 198 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/safepoint.h ('k') | runtime/vm/thread_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698