Coverage for /Syzygy/agent/asan/timed_try_impl.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%40400.C++source

Line-by-line coverage:

   1    :  // Copyright 2014 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Utility functions for spending a fixed amount of time trying to acquire
  16    :  // a base::Lock (or any lock with the same API).
  17    :  
  18    :  #ifndef SYZYGY_AGENT_ASAN_TIMED_TRY_IMPL_H_
  19    :  #define SYZYGY_AGENT_ASAN_TIMED_TRY_IMPL_H_
  20    :  
  21    :  #ifndef SYZYGY_AGENT_ASAN_TIMED_TRY_H_
  22    :  #error Meant to be included from timed_try.h only.
  23    :  #endif
  24    :  
  25    :  #include "base/logging.h"
  26    :  #include "base/time/time.h"
  27    :  #include "syzygy/agent/asan/heap.h"
  28    :  
  29    :  namespace agent {
  30    :  namespace asan {
  31    :  
  32    :  namespace detail {
  33    :  
  34    :  // A simple adapter for base::Lock-like locks (Try and Release).
  35    :  template<typename LockType>
  36    :  struct BaseLockAdapter {
  37  E :    bool Try(LockType* lock) {
  38  E :      DCHECK_NE(static_cast<LockType*>(NULL), lock);
  39  E :      return lock->Try();
  40  E :    }
  41    :  
  42  E :    void Release(LockType* lock) {
  43  E :      DCHECK_NE(static_cast<LockType*>(NULL), lock);
  44  E :      lock->Release();
  45  E :    }
  46    :  };
  47    :  
  48    :  // A lock adapter for HeapInterface objects.
  49    :  struct HeapInterfaceAdapter {
  50  E :    bool Try(HeapInterface* heap) {
  51  E :      DCHECK_NE(static_cast<HeapInterface*>(NULL), heap);
  52  E :      return heap->TryLock();
  53  E :    }
  54    :  
  55  E :    void Release(HeapInterface* heap) {
  56  E :      DCHECK_NE(static_cast<HeapInterface*>(NULL), heap);
  57  E :      heap->Unlock();
  58  E :    }
  59    :  };
  60    :  
  61    :  // A lock adapter selector. By default selects BaseLockAdapter, and expects
  62    :  // the lock to implement 'Try' and 'Release'.
  63    :  template<typename LockType>
  64    :  struct SelectLockAdapter {
  65    :    typedef BaseLockAdapter<LockType> type;
  66    :  };
  67    :  
  68    :  // A specialization that selects HeapInterfaceAdapter for HeapInterface objects.
  69    :  template<>
  70    :  struct SelectLockAdapter<HeapInterface> {
  71    :    typedef HeapInterfaceAdapter type;
  72    :  };
  73    :  
  74    :  }  // namespace detail
  75    :  
  76    :  template<typename LockType>
  77  E :  bool TimedTry(base::TimeDelta delta, LockType* lock) {
  78  E :    DCHECK_NE(static_cast<LockType*>(NULL), lock);
  79    :  
  80    :    // Try at least once, even if |delta| is zero or negative.
  81    :    detail::SelectLockAdapter<LockType>::type adapter;
  82  E :    if (adapter.Try(lock))
  83  E :      return true;
  84    :  
  85    :    // Try repeatedly, until timeout.
  86  E :    base::Time end = base::Time::Now() + delta;
  87  E :    while (base::Time::Now() < end) {
  88    :      // Spin a bunch of times.
  89  E :      for (size_t i = 0; i < 100; ++i)
  90  E :        if (adapter.Try(lock))
  91  E :          return true;
  92    :  
  93    :      // Cede the processor to another thread, hoping the lock will become
  94    :      // available at some point.
  95  E :      ::SwitchToThread();
  96  E :    }
  97    :  
  98  E :    return false;
  99  E :  }
 100    :  
 101    :  template<typename LockType>
 102    :  AutoTimedTry<LockType>::AutoTimedTry(
 103    :      base::TimeDelta delta, LockType* lock)
 104  E :      : lock_(lock) {
 105  E :    DCHECK_NE(static_cast<LockType*>(NULL), lock);
 106  E :    is_acquired_ = TimedTry<LockType>(delta, lock);
 107  E :  }
 108    :  
 109    :  template<typename LockType>
 110  E :  AutoTimedTry<LockType>::~AutoTimedTry() {
 111    :    detail::SelectLockAdapter<LockType>::type adapter;
 112  E :    if (is_acquired_)
 113  E :      adapter.Release(lock_);
 114  E :  }
 115    :  
 116    :  template<typename LockType>
 117  E :  bool AutoTimedTry<LockType>::is_acquired() const {
 118  E :    return is_acquired_;
 119  E :  }
 120    :  
 121    :  }  // namespace asan
 122    :  }  // namespace agent
 123    :  
 124    :  #endif  // SYZYGY_AGENT_ASAN_TIMED_TRY_IMPL_H_

Coverage information generated Thu Jan 14 17:40:38 2016.