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

Unified Diff: runtime/vm/thread_registry.h

Issue 1259223005: Safepoint interface and unit tests. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Ready for review. Created 5 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/thread_registry.h
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index af160269fa33ad7d2207229bdaa13115df81573f..b360374de52c3b582b1e455ed775fbe2b1d2129d 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -16,10 +16,38 @@ namespace dart {
// Unordered collection of threads relating to a particular isolate.
class ThreadRegistry {
public:
- ThreadRegistry() : mutex_(new Mutex()), entries_() {}
+ ThreadRegistry()
+ : monitor_(new Monitor()),
+ entries_(),
+ in_rendezvous_(false),
+ remaining_(0),
+ round_(0) {}
+
+ // Bring all threads in this isolate, except the caller, to a safepoint. The
Ivan Posva 2015/07/31 20:28:09 Please add a comment that the caller is expected t
koda 2015/07/31 22:40:44 Done.
+ // threads will wait until ResumeAllThreads is called. Must be called at a
+ // safepoint, since it first waits for any already pending requests. Any
+ // thread that tries to enter/exit this isolate during rendezvous will wait
+ // in RestoreStateTo/SaveStateFrom, respectively.
+ void SafepointAllThreads();
Ivan Posva 2015/07/31 20:28:09 Isn't the All redundant here?
koda 2015/07/31 22:40:44 Done.
+
+ // Unblocks all threads participating in the rendezvous that was organized
+ // by a prior call to SafepointAllThreads.
+ // TODO(koda): Consider adding a scope helper to avoid omitting this call.
+ void ResumeAllThreads();
+
+ // Indicate that the current thread is at a safepoint, and offer to wait for
+ // any pending rendezvous request (if none, returns immediately).
+ void CheckSafepoint() {
+ MonitorLocker ml(monitor_);
+ CheckSafepointLocked();
+ }
bool RestoreStateTo(Thread* thread, Thread::State* state) {
- MutexLocker ml(mutex_);
+ MonitorLocker ml(monitor_);
+ // Wait for any rendezvous in progress.
+ while (in_rendezvous_) {
+ ml.Wait(Monitor::kNoTimeout);
+ }
Entry* entry = FindEntry(thread);
if (entry != NULL) {
Thread::State st = entry->state;
@@ -50,7 +78,9 @@ class ThreadRegistry {
}
void SaveStateFrom(Thread* thread, const Thread::State& state) {
- MutexLocker ml(mutex_);
+ MonitorLocker ml(monitor_);
+ // Exiting an isolate must always be a safepoint.
Ivan Posva 2015/07/31 20:28:09 As already discussed I strongly disagree with this
koda 2015/07/31 22:40:44 You convinced me that this should change in a futu
+ CheckSafepointLocked();
Entry* entry = FindEntry(thread);
ASSERT(entry != NULL);
ASSERT(entry->scheduled);
@@ -59,12 +89,12 @@ class ThreadRegistry {
}
bool Contains(Thread* thread) {
- MutexLocker ml(mutex_);
+ MonitorLocker ml(monitor_);
return (FindEntry(thread) != NULL);
}
void CheckNotScheduled(Isolate* isolate) {
- MutexLocker ml(mutex_);
+ MonitorLocker ml(monitor_);
for (int i = 0; i < entries_.length(); ++i) {
const Entry& entry = entries_[i];
if (entry.scheduled) {
@@ -77,7 +107,7 @@ class ThreadRegistry {
}
void VisitObjectPointers(ObjectPointerVisitor* visitor) {
- MutexLocker ml(mutex_);
+ MonitorLocker ml(monitor_);
for (int i = 0; i < entries_.length(); ++i) {
const Entry& entry = entries_[i];
Zone* zone = entry.scheduled ? entry.thread->zone() : entry.state.zone;
@@ -96,8 +126,8 @@ class ThreadRegistry {
// Returns Entry corresponding to thread in registry or NULL.
// Note: Lock should be taken before this function is called.
+ // TODO(koda): Add method Monitor::IsOwnedByCurrentThread.
Entry* FindEntry(Thread* thread) {
- DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread());
for (int i = 0; i < entries_.length(); ++i) {
if (entries_[i].thread == thread) {
return &entries_[i];
@@ -106,9 +136,21 @@ class ThreadRegistry {
return NULL;
}
- Mutex* mutex_;
+ // Note: Lock should be taken before this function is called.
+ void CheckSafepointLocked();
+
+ // Returns the number threads that are scheduled on this isolate.
+ // Note: Lock should be taken before this function is called.
+ intptr_t CountScheduledLocked();
+
+ Monitor* monitor_; // All access is synchronized through this monitor.
MallocGrowableArray<Entry> entries_;
+ // Safepoint rendezvous state.
+ bool in_rendezvous_; // A safepoint rendezvous request is in progress.
+ intptr_t remaining_; // Number of threads yet to reach their safepoint.
+ int64_t round_; // Counter, to prevent missing updates to remaining_
+ // (see comments in CheckSafepointLocked).
DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
};

Powered by Google App Engine
This is Rietveld 408576698