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

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: Add usage example. 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().
Ivan Posva 2015/09/16 04:36:11 Thanks for the example. It makes the use a lot cle
koda 2015/09/16 19:12:15 Done.
46 class ThreadBarrier {
47 public:
48 explicit ThreadBarrier(intptr_t num_threads)
49 : num_threads_(num_threads),
50 remaining_(num_threads),
51 parity_(false),
52 done_(false) {
53 ASSERT(remaining_ > 0);
54 }
55
56 void Sync() {
57 MonitorLocker ml(&monitor_);
58 ASSERT(remaining_ > 0);
59 if (--remaining_ > 0) {
60 // I'm not last to arrive; wait until next round.
61 bool old_parity = parity_;
62 while (parity_ == old_parity) {
63 ml.Wait();
64 }
65 } else {
66 // Last one to arrive initiates the next round.
67 remaining_ = num_threads_;
68 parity_ = !parity_;
69 // Tell everyone else about the new round.
70 ml.NotifyAll();
71 }
72 }
73
74 void Exit() {
75 bool last = false;
76 {
77 MonitorLocker ml(&monitor_);
78 ASSERT(remaining_ > 0);
79 last = (--remaining_ == 0);
80 }
81 if (last) {
82 // Last one to exit sets done_.
83 MonitorLocker ml(&done_monitor_);
Ivan Posva 2015/09/16 04:36:11 I am wondering whether this could be achieved with
koda 2015/09/16 19:12:15 Acknowledged.
84 ASSERT(!done_);
85 done_ = true;
86 // Tell the destructor in case it's already waiting.
87 ml.Notify();
88 }
89 }
90
91 ~ThreadBarrier() {
92 MonitorLocker ml(&done_monitor_);
93 // Wait for everyone to exit before destroying the monitors.
94 while (!done_) {
95 ml.Wait();
96 }
97 ASSERT(remaining_ == 0);
98 }
99
100 private:
101 const intptr_t num_threads_;
102
103 Monitor monitor_;
104 intptr_t remaining_;
105 bool parity_;
106
107 Monitor done_monitor_;
108 bool done_;
109
110 DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
111 };
112
113 } // namespace dart
114
115 #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