Coverage for /Syzygy/agent/asan/quarantines/size_limited_quarantine.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%38380.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    :  // An implementation of a size-limited quarantine. This encapsulates the
  16    :  // logic for maintaining a size invariant over the items in a quarantine.
  17    :  
  18    :  #ifndef SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_H_
  19    :  #define SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_H_
  20    :  
  21    :  #include "base/atomicops.h"
  22    :  #include "base/synchronization/lock.h"
  23    :  #include "syzygy/agent/asan/quarantine.h"
  24    :  
  25    :  namespace agent {
  26    :  namespace asan {
  27    :  namespace quarantines {
  28    :  
  29    :  // Provides both the size of the quarantine and the number of elements it
  30    :  // contains. Both of these are accessed behind a lock, to ensure their
  31    :  // consistency. Hence, the lock must be acquired (by calling Lock) before any
  32    :  // other operation is performed. The lock should be returned (by calling Unlock)
  33    :  // as soon as possible to minimize the locked time.
  34    :  class QuarantineSizeCount {
  35    :   public:
  36    :    // Default constructor that sets the size and count to 0.
  37  E :    QuarantineSizeCount() : size_(0), count_(0) {}
  38    :  
  39    :    // Must be called before any other operation to acquire the lock.
  40  E :    void Lock() { lock_.Acquire(); }
  41    :  
  42    :    // Releases the lock.
  43  E :    void Unlock() {
  44  E :      lock_.AssertAcquired();
  45  E :      lock_.Release();
  46  E :    }
  47    :  
  48    :    // @returns the size.
  49  E :    int32 size() const {
  50  E :      lock_.AssertAcquired();
  51  E :      return size_;
  52  E :    }
  53    :  
  54    :    // @returns the count.
  55  E :    int32 count() const {
  56  E :      lock_.AssertAcquired();
  57  E :      return count_;
  58  E :    }
  59    :  
  60    :    // Increments the size and count (accepts negative values for decrementing).
  61    :    // @param size_delta The delta by which the size is incremented.
  62    :    // @param count_delta The delta by which the count is incremented.
  63  E :    void Increment(int32 size_delta, int32 count_delta) {
  64  E :      lock_.AssertAcquired();
  65  E :      size_ += size_delta;
  66  E :      count_ += count_delta;
  67  E :    }
  68    :  
  69    :   private:
  70    :    // The current size of the quarantine.
  71    :    int32 size_;
  72    :    // The number of elements in the quarantine.
  73    :    int32 count_;
  74    :    // Single lock that's used for both |size_| and |count_|.
  75    :    base::Lock lock_;
  76    :  };
  77    :  
  78    :  // An automatic lock on QuarantineSizeCount.
  79    :  class ScopedQuarantineSizeCountLock {
  80    :   public:
  81    :    // Constructor. Automatically lock the quarantine.
  82  E :    explicit ScopedQuarantineSizeCountLock(QuarantineSizeCount& size_count)
  83    :        : size_count_(size_count) {
  84  E :      size_count_.Lock();
  85  E :    }
  86    :  
  87    :    // Destructor. Automatically unlock the quarantine.
  88  E :    ~ScopedQuarantineSizeCountLock() { size_count_.Unlock(); }
  89    :  
  90    :   private:
  91    :    // The QuarantineSizeCount that this holds.
  92    :    QuarantineSizeCount& size_count_;
  93    :  
  94    :    DISALLOW_COPY_AND_ASSIGN(ScopedQuarantineSizeCountLock);
  95    :  };
  96    :  
  97    :  // A partial implementation of a size-limited quarantine. This quarantine
  98    :  // obeys a simple invariant: the sum of object weights within it must be
  99    :  // less than a certain threshold, and all objects within it must be smaller
 100    :  // than another given threshold.
 101    :  //
 102    :  // Provides implementations of QuarantineInterface Push/Pop/Empty methods.
 103    :  // Expects the derived class to provide implementations for a few methods:
 104    :  //
 105    :  //   bool PushImpl(const ObjectType& object);
 106    :  //   bool PopImpl(ObjectType* object);
 107    :  //   void EmptyImpl(ObjectVector* object);
 108    :  //
 109    :  // Calculates the sizes of objects using the provided SizeFunctor. This
 110    :  // must satisfy the following interface:
 111    :  //
 112    :  // struct SizeFunctor {
 113    :  //   size_t operator()(const ObjectType& object);
 114    :  // };
 115    :  //
 116    :  // @tparam ObjectType The type of object stored in the quarantine.
 117    :  // @tparam SizeFunctorType The size functor that will be used to extract
 118    :  //     a size from an object.
 119    :  template<typename ObjectType, typename SizeFunctorType>
 120    :  class SizeLimitedQuarantineImpl : public QuarantineInterface<ObjectType> {
 121    :   public:
 122    :    typedef SizeFunctorType SizeFunctor;
 123    :  
 124    :    static const size_t kUnboundedSize = SIZE_MAX;
 125    :  
 126    :    // Constructor. Initially the quarantine has unlimited capacity.
 127    :    SizeLimitedQuarantineImpl()
 128    :        : max_object_size_(kUnboundedSize),
 129    :          max_quarantine_size_(kUnboundedSize),
 130  E :          size_functor_() {
 131  E :    }
 132    :  
 133    :    // Constructor. Initially the quarantine has unlimited capacity.
 134    :    // @param size_functor The size functor to be used. This will be copied
 135    :    //     into the classes member size functor.
 136    :    explicit SizeLimitedQuarantineImpl(const SizeFunctor& size_functor)
 137    :        : max_object_size_(kUnboundedSize),
 138    :          max_quarantine_size_(kUnboundedSize),
 139    :          size_functor_(size_functor) {
 140    :    }
 141    :  
 142    :    // Virtual destructor.
 143  E :    virtual ~SizeLimitedQuarantineImpl() { }
 144    :  
 145    :    // Sets the maximum object size. This only gates the entry of future
 146    :    // objects to 'Push', and does not invalidate overly objects already in
 147    :    // the quarantine.
 148    :    // @param max_object_size The maximum size of any single object in the
 149    :    //     quarantine. Use kUnboundedSize for unlimited (no max).
 150  E :    void set_max_object_size(size_t max_object_size) {
 151  E :      max_object_size_ = max_object_size;
 152  E :    }
 153    :  
 154    :    // Sets the maximum quarantine size. This may cause the quarantine
 155    :    // invariant to be immediately invalidated, requiring calls to 'Pop'.
 156    :    // @param max_quarantine_size The maximum size of the entire quarantine.
 157    :    //     Use kUnboundedSize for unlimited (no max).
 158  E :    void set_max_quarantine_size(size_t max_quarantine_size) {
 159  E :      max_quarantine_size_ = max_quarantine_size;
 160  E :    }
 161    :  
 162    :    // @returns the maximum object size.
 163  E :    size_t max_object_size() const { return max_object_size_; }
 164    :  
 165    :    // @returns the maximum quarantine size.
 166  E :    size_t max_quarantine_size() const { return max_quarantine_size_; }
 167    :  
 168    :    // @returns the current size of the quarantine.
 169    :    // @note that this function could be racing with a push/pop operation and
 170    :    // return a stale value. It should only be used when this is acceptable (in
 171    :    // tests for example).
 172  E :    size_t size() {
 173  E :      ScopedQuarantineSizeCountLock size_count_lock(size_count_);
 174  E :      return size_count_.size();
 175  E :    }
 176    :  
 177    :    // @name QuarantineInterface implementation.
 178    :    // @note that GetCount could be racing with a push/pop operation and return a
 179    :    // stale value. It should only be used when this is acceptable (in tests for
 180    :    // example).
 181    :    // @{
 182    :    virtual bool Push(const Object& object);
 183    :    virtual bool Pop(Object* object);
 184    :    virtual void Empty(ObjectVector* objects);
 185    :    virtual size_t GetCount();
 186    :    virtual size_t GetLockId(const Object& object);
 187    :    virtual void Lock(size_t id);
 188    :    virtual void Unlock(size_t id);
 189    :    // @}
 190    :  
 191    :   protected:
 192    :    // @name SizeLimitedQuarantine interface.
 193    :    // @{
 194    :    virtual bool PushImpl(const Object& object) = 0;
 195    :    virtual bool PopImpl(Object* object) = 0;
 196    :    virtual void EmptyImpl(ObjectVector* objects) = 0;
 197    :    virtual size_t GetLockIdImpl(const Object& object) = 0;
 198    :    virtual void LockImpl(size_t id) = 0;
 199    :    virtual void UnlockImpl(size_t id) = 0;
 200    :    // @}
 201    :  
 202    :    // Parameters controlling the quarantine invariant.
 203    :    size_t max_object_size_;
 204    :    size_t max_quarantine_size_;
 205    :  
 206    :    QuarantineSizeCount size_count_;
 207    :  
 208    :    // The size functor.
 209    :    SizeFunctor size_functor_;
 210    :  
 211    :   private:
 212    :    DISALLOW_COPY_AND_ASSIGN(SizeLimitedQuarantineImpl);
 213    :  };
 214    :  
 215    :  }  // namespace quarantines
 216    :  }  // namespace asan
 217    :  }  // namespace agent
 218    :  
 219    :  #include "syzygy/agent/asan/quarantines/size_limited_quarantine_impl.h"
 220    :  
 221    :  #endif  // SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_H_

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