LCOV - code coverage report
Current view: top level - src/heap - barrier.h (source / functions) Hit Total Coverage
Test: app.info Lines: 19 19 100.0 %
Date: 2019-03-21 Functions: 2 2 100.0 %

          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             : #include "src/base/platform/time.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : // Barrier that can be used once to synchronize a dynamic number of tasks
      16             : // working concurrently.
      17             : //
      18             : // The barrier takes a timeout which is used to avoid waiting for too long. If
      19             : // any of the users ever reach the timeout they will disable the barrier and
      20             : // signal others to fall through.
      21             : //
      22             : // Usage:
      23             : //   void RunConcurrently(OneShotBarrier* shared_barrier) {
      24             : //     shared_barrier->Start();
      25             : //     do {
      26             : //       {
      27             : //         /* process work and create new work */
      28             : //         barrier->NotifyAll();
      29             : //         /* process work and create new work */
      30             : //       }
      31             : //     } while(!shared_barrier->Wait());
      32             : //   }
      33             : //
      34             : // Note: If Start() is not called in time, e.g., because the first concurrent
      35             : // task is already done processing all work, then Done() will return true
      36             : // immediately.
      37       20978 : class OneshotBarrier {
      38             :  public:
      39       20978 :   explicit OneshotBarrier(base::TimeDelta timeout) : timeout_(timeout) {}
      40             : 
      41             :   void Start() {
      42       33442 :     base::MutexGuard guard(&mutex_);
      43       33500 :     tasks_++;
      44             :   }
      45             : 
      46      419823 :   void NotifyAll() {
      47      419823 :     base::MutexGuard guard(&mutex_);
      48      420027 :     if (waiting_ > 0) condition_.NotifyAll();
      49      420022 :   }
      50             : 
      51       36298 :   bool Wait() {
      52       36298 :     base::MutexGuard guard(&mutex_);
      53       36384 :     if (done_) return true;
      54             : 
      55             :     DCHECK_LE(waiting_, tasks_);
      56       27535 :     waiting_++;
      57       27535 :     if (waiting_ == tasks_) {
      58       20281 :       done_ = true;
      59       20281 :       condition_.NotifyAll();
      60             :     } else {
      61             :       // Spurious wakeup is ok here.
      62        7254 :       if (!condition_.WaitFor(&mutex_, timeout_)) {
      63             :         // If predefined timeout was reached, Stop waiting and signal being done
      64             :         // also to other tasks.
      65        1797 :         done_ = true;
      66             :       }
      67             :     }
      68       27535 :     waiting_--;
      69       27535 :     return done_;
      70             :   }
      71             : 
      72             :   // Only valid to be called in a sequential setting.
      73             :   bool DoneForTesting() const { return done_; }
      74             : 
      75             :  private:
      76             :   base::ConditionVariable condition_;
      77             :   base::Mutex mutex_;
      78             :   base::TimeDelta timeout_;
      79             :   int tasks_ = 0;
      80             :   int waiting_ = 0;
      81             :   bool done_ = false;
      82             : };
      83             : 
      84             : }  // namespace internal
      85             : }  // namespace v8
      86             : 
      87             : #endif  // V8_HEAP_BARRIER_H_

Generated by: LCOV version 1.10