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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/random.cc ('k') | runtime/vm/thread_barrier_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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef VM_THREAD_BARRIER_H_
6 #define VM_THREAD_BARRIER_H_
7
8 #include "vm/globals.h"
9 #include "vm/os_thread.h"
10 #include "vm/lockers.h"
11
12 namespace dart {
13
14 // Thread barrier with:
15 // * fixed (at construction) number n of participating threads {T1,T2,T3,...,Tn}
16 // * unknown number of rounds.
17 // Requirements:
18 // * there is some R such that each participating thread makes
19 // R calls to Sync() followed by its one and only call to Exit().
20 // Guarantees:
21 // * for any two threads Ti and Tj and round number r <= R,
22 // everything done by Ti before its r'th call to Sync() happens before
23 // everything done by Tj after its r'th call to Sync().
24 // Note:
25 // * it's not required that the thread that constructs the barrier participates.
26 //
27 // Example usage with 3 threads (1 controller + 2 workers) and 3 rounds:
28 //
29 // T1:
30 // ThreadBarrier barrier(3);
31 // Dart::thread_pool()->Run( T2:
32 // new FooTask(&barrier)); fooSetup();
33 // Dart::thread_pool()->Run( ... T3:
34 // new BarTask(&barrier)); ... barSetup();
35 // barrier.Sync(); barrier_->Sync(); barrier_->Sync();
36 // /* Both tasks have finished setup */ ... ...
37 // prepareWorkForTasks(); ... ...
38 // barrier.Sync(); barrier_->Sync(); barrier_->Sync();
39 // /* Idle while tasks are working */ fooWork(); barWork();
40 // barrier.Sync(); barrier_->Sync(); barrier_->Sync();
41 // collectResultsFromTasks(); barrier_->Exit(); barrier_->Exit();
42 // barrier.Exit();
43 //
44 // Note that the calls to Sync() "line up" in time, but there is no such
45 // guarantee for Exit().
46 //
47 class ThreadBarrier {
48 public:
49 explicit ThreadBarrier(intptr_t num_threads)
50 : num_threads_(num_threads),
51 remaining_(num_threads),
52 parity_(false),
53 done_(false) {
54 ASSERT(remaining_ > 0);
55 }
56
57 void Sync() {
58 MonitorLocker ml(&monitor_);
59 ASSERT(remaining_ > 0);
60 if (--remaining_ > 0) {
61 // I'm not last to arrive; wait until next round.
62 bool old_parity = parity_;
63 while (parity_ == old_parity) {
64 ml.Wait();
65 }
66 } else {
67 // Last one to arrive initiates the next round.
68 remaining_ = num_threads_;
69 parity_ = !parity_;
70 // Tell everyone else about the new round.
71 ml.NotifyAll();
72 }
73 }
74
75 void Exit() {
76 bool last = false;
77 {
78 MonitorLocker ml(&monitor_);
79 ASSERT(remaining_ > 0);
80 last = (--remaining_ == 0);
81 }
82 if (last) {
83 // Last one to exit sets done_.
84 MonitorLocker ml(&done_monitor_);
85 ASSERT(!done_);
86 done_ = true;
87 // Tell the destructor in case it's already waiting.
88 ml.Notify();
89 }
90 }
91
92 ~ThreadBarrier() {
93 MonitorLocker ml(&done_monitor_);
94 // Wait for everyone to exit before destroying the monitors.
95 while (!done_) {
96 ml.Wait();
97 }
98 ASSERT(remaining_ == 0);
99 }
100
101 private:
102 const intptr_t num_threads_;
103
104 Monitor monitor_;
105 intptr_t remaining_;
106 bool parity_;
107
108 Monitor done_monitor_; // TODO(koda): Try to optimize this away.
109 bool done_;
110
111 DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
112 };
113
114 } // namespace dart
115
116 #endif // VM_THREAD_BARRIER_H_
OLDNEW
« 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