Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_HEAP_BARRIER_H_
6 : #define V8_HEAP_BARRIER_H_
7 :
8 : #include "src/base/platform/condition-variable.h"
9 : #include "src/base/platform/mutex.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : // Barrier that can be used once to synchronize a dynamic number of tasks
15 : // working concurrently.
16 : //
17 : // Usage:
18 : // void RunConcurrently(OneShotBarrier* shared_barrier) {
19 : // shared_barrier->Start();
20 : // do {
21 : // {
22 : // /* process work and create new work */
23 : // barrier->NotifyAll();
24 : // /* process work and create new work */
25 : // }
26 : // } while(!shared_barrier->Wait());
27 : // }
28 : //
29 : // Note: If Start() is not called in time, e.g., because the first concurrent
30 : // task is already done processing all work, then Done() will return true
31 : // immediately.
32 29657 : class OneshotBarrier {
33 : public:
34 29657 : OneshotBarrier() : tasks_(0), waiting_(0), done_(false) {}
35 :
36 44132 : void Start() {
37 44132 : base::LockGuard<base::Mutex> guard(&mutex_);
38 44171 : tasks_++;
39 44168 : }
40 :
41 458575 : void NotifyAll() {
42 458575 : base::LockGuard<base::Mutex> guard(&mutex_);
43 458816 : if (waiting_ > 0) condition_.NotifyAll();
44 458809 : }
45 :
46 45675 : bool Wait() {
47 45675 : base::LockGuard<base::Mutex> guard(&mutex_);
48 45692 : if (done_) return true;
49 :
50 : DCHECK_LE(waiting_, tasks_);
51 36315 : waiting_++;
52 36315 : if (waiting_ == tasks_) {
53 29656 : done_ = true;
54 29656 : condition_.NotifyAll();
55 : } else {
56 : // Spurious wakeup is ok here.
57 6659 : condition_.Wait(&mutex_);
58 : }
59 36315 : waiting_--;
60 36315 : return done_;
61 : }
62 :
63 : // Only valid to be called in a sequential setting.
64 : bool DoneForTesting() const { return done_; }
65 :
66 : private:
67 : base::ConditionVariable condition_;
68 : base::Mutex mutex_;
69 : int tasks_;
70 : int waiting_;
71 : bool done_;
72 : };
73 :
74 : } // namespace internal
75 : } // namespace v8
76 :
77 : #endif // V8_HEAP_BARRIER_H_
|