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

Unified Diff: runtime/vm/thread_barrier.h

Issue 1337943004: Add ThreadBarrier; use in GCMarker and unit test (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix git again. Created 5 years, 3 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
« no previous file with comments | « runtime/vm/random.cc ('k') | runtime/vm/thread_barrier_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/thread_barrier.h
diff --git a/runtime/vm/thread_barrier.h b/runtime/vm/thread_barrier.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cc1d97fc5e92b9c019108b24197e4207b5327b1
--- /dev/null
+++ b/runtime/vm/thread_barrier.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_THREAD_BARRIER_H_
+#define VM_THREAD_BARRIER_H_
+
+#include "vm/globals.h"
+#include "vm/os_thread.h"
+#include "vm/lockers.h"
+
+namespace dart {
+
+// Thread barrier with:
+// * fixed (at construction) number n of participating threads {T1,T2,T3,...,Tn}
+// * unknown number of rounds.
+// Requirements:
+// * there is some R such that each participating thread makes
+// R calls to Sync() followed by its one and only call to Exit().
+// Guarantees:
+// * for any two threads Ti and Tj and round number r <= R,
+// everything done by Ti before its r'th call to Sync() happens before
+// everything done by Tj after its r'th call to Sync().
+// Note:
+// * it's not required that the thread that constructs the barrier participates.
+//
+// Example usage with 3 threads (1 controller + 2 workers) and 3 rounds:
+//
+// T1:
+// ThreadBarrier barrier(3);
+// Dart::thread_pool()->Run( T2:
+// new FooTask(&barrier)); fooSetup();
+// Dart::thread_pool()->Run( ... T3:
+// new BarTask(&barrier)); ... barSetup();
+// barrier.Sync(); barrier_->Sync(); barrier_->Sync();
+// /* Both tasks have finished setup */ ... ...
+// prepareWorkForTasks(); ... ...
+// barrier.Sync(); barrier_->Sync(); barrier_->Sync();
+// /* Idle while tasks are working */ fooWork(); barWork();
+// barrier.Sync(); barrier_->Sync(); barrier_->Sync();
+// collectResultsFromTasks(); barrier_->Exit(); barrier_->Exit();
+// barrier.Exit();
+//
+// Note that the calls to Sync() "line up" in time, but there is no such
+// guarantee for Exit().
+//
+class ThreadBarrier {
+ public:
+ explicit ThreadBarrier(intptr_t num_threads)
+ : num_threads_(num_threads),
+ remaining_(num_threads),
+ parity_(false),
+ done_(false) {
+ ASSERT(remaining_ > 0);
+ }
+
+ void Sync() {
+ MonitorLocker ml(&monitor_);
+ ASSERT(remaining_ > 0);
+ if (--remaining_ > 0) {
+ // I'm not last to arrive; wait until next round.
+ bool old_parity = parity_;
+ while (parity_ == old_parity) {
+ ml.Wait();
+ }
+ } else {
+ // Last one to arrive initiates the next round.
+ remaining_ = num_threads_;
+ parity_ = !parity_;
+ // Tell everyone else about the new round.
+ ml.NotifyAll();
+ }
+ }
+
+ void Exit() {
+ bool last = false;
+ {
+ MonitorLocker ml(&monitor_);
+ ASSERT(remaining_ > 0);
+ last = (--remaining_ == 0);
+ }
+ if (last) {
+ // Last one to exit sets done_.
+ MonitorLocker ml(&done_monitor_);
+ ASSERT(!done_);
+ done_ = true;
+ // Tell the destructor in case it's already waiting.
+ ml.Notify();
+ }
+ }
+
+ ~ThreadBarrier() {
+ MonitorLocker ml(&done_monitor_);
+ // Wait for everyone to exit before destroying the monitors.
+ while (!done_) {
+ ml.Wait();
+ }
+ ASSERT(remaining_ == 0);
+ }
+
+ private:
+ const intptr_t num_threads_;
+
+ Monitor monitor_;
+ intptr_t remaining_;
+ bool parity_;
+
+ Monitor done_monitor_; // TODO(koda): Try to optimize this away.
+ bool done_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
+};
+
+} // namespace dart
+
+#endif // VM_THREAD_BARRIER_H_
« no previous file with comments | « runtime/vm/random.cc ('k') | runtime/vm/thread_barrier_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698