Flutter Engine
The Flutter Engine
thread_barrier.h
Go to the documentation of this file.
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 RUNTIME_VM_THREAD_BARRIER_H_
6#define RUNTIME_VM_THREAD_BARRIER_H_
7
8#include "vm/globals.h"
9#include "vm/lockers.h"
10#include "vm/os_thread.h"
11
12namespace 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//
48 public:
49 explicit ThreadBarrier(intptr_t num_threads, intptr_t initial = 0)
50 : ref_count_(num_threads),
51 monitor_(),
52 participating_(initial),
53 remaining_(initial),
54 generation_(0) {}
55
56 bool TryEnter() {
57 MonitorLocker ml(&monitor_);
58 if (generation_ != 0) {
59 return false;
60 }
61 remaining_++;
62 participating_++;
63 return true;
64 }
65
66 void Sync() {
67 MonitorLocker ml(&monitor_);
68 const intptr_t g = generation_;
69 remaining_--;
70 if (remaining_ == 0) {
71 // I'm last, advance to the next generation and wake the others.
72 generation_++;
73 remaining_ = participating_;
74 ml.NotifyAll();
75 } else {
76 // Waiting for others.
77 while (g == generation_) {
78 ml.Wait();
79 }
80 }
81 }
82
83 void Release() {
84 intptr_t old = ref_count_.fetch_sub(1, std::memory_order_acq_rel);
85 ASSERT(old > 0);
86 if (old == 1) {
87 delete this;
88 }
89 }
90
91 private:
92 std::atomic<intptr_t> ref_count_;
93
94 Monitor monitor_;
95 intptr_t participating_;
96 intptr_t remaining_;
97 intptr_t generation_;
98
99 DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
100};
101
102} // namespace dart
103
104#endif // RUNTIME_VM_THREAD_BARRIER_H_
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition: lockers.h:172
ThreadBarrier(intptr_t num_threads, intptr_t initial=0)
#define ASSERT(E)
Definition: dart_vm.cc:33