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 "syzygy/agent/asan/quarantine.h"
22 :
23 : namespace agent {
24 : namespace asan {
25 : namespace quarantines {
26 :
27 : // A partial implementation of a size-limited quarantine. This quarantine
28 : // obeys a simple invariant: the sum of object weights within it must be
29 : // less than a certain threshold, and all objects within it must be smaller
30 : // than another given threshold.
31 : //
32 : // Provides implementations of QuarantineInterface Push/Pop/Empty methods.
33 : // Expects the derived class to provide implementations for a few methods:
34 : //
35 : // bool PushImpl(const ObjectType& object);
36 : // bool PopImpl(ObjectType* object);
37 : // void EmptyImpl(ObjectVector* object);
38 : //
39 : // Calculates the sizes of objects using the provided SizeFunctor. This
40 : // must satisfy the following interface:
41 : //
42 : // struct SizeFunctor {
43 : // size_t operator()(const ObjectType& object);
44 : // };
45 : //
46 : // @tparam ObjectType The type of object stored in the quarantine.
47 : // @tparam SizeFunctorType The size functor that will be used to extract
48 : // a size from an object.
49 : template<typename ObjectType, typename SizeFunctorType>
50 : class SizeLimitedQuarantineImpl : public QuarantineInterface<ObjectType> {
51 : public:
52 : typedef SizeFunctorType SizeFunctor;
53 :
54 : static const size_t kUnboundedSize = ~0;
55 :
56 : // Constructor. Initially the quarantine has unlimited capacity.
57 : SizeLimitedQuarantineImpl()
58 : : max_object_size_(kUnboundedSize),
59 : max_quarantine_size_(kUnboundedSize),
60 : size_(0),
61 : count_(0),
62 E : size_functor_() {
63 E : }
64 :
65 : // Constructor. Initially the quarantine has unlimited capacity.
66 : // @param size_functor The size functor to be used. This will be copied
67 : // into the classes member size functor.
68 : explicit SizeLimitedQuarantineImpl(const SizeFunctor& size_functor)
69 : : max_object_size_(kUnboundedSize),
70 : max_quarantine_size_(kUnboundedSize),
71 : size_(0),
72 : count_(0),
73 : size_functor_(size_functor) {
74 : }
75 :
76 : // Virtual destructor.
77 E : virtual ~SizeLimitedQuarantineImpl() { }
78 :
79 : // Sets the maximum object size. This only gates the entry of future
80 : // objects to 'Push', and does not invalidate overly objects already in
81 : // the quarantine.
82 : // @param max_object_size The maximum size of any single object in the
83 : // quarantine. Use kUnboundedSize for unlimited (no max).
84 E : void set_max_object_size(size_t max_object_size) {
85 E : max_object_size_ = max_object_size;
86 E : }
87 :
88 : // Sets the maximum quarantine size. This may cause the quarantine
89 : // invariant to be immediately invalidated, requiring calls to 'Pop'.
90 : // @param max_quarantine_size The maximum size of the entire quarantine.
91 : // Use kUnboundedSize for unlimited (no max).
92 E : void set_max_quarantine_size(size_t max_quarantine_size) {
93 E : max_quarantine_size_ = max_quarantine_size;
94 E : }
95 :
96 : // @returns the maximum object size.
97 E : size_t max_object_size() const { return max_object_size_; }
98 :
99 : // @returns the maximum quarantine size.
100 E : size_t max_quarantine_size() const { return max_quarantine_size_; }
101 :
102 : // @returns the current size of the quarantine.
103 E : size_t size() const { return size_; }
104 :
105 : // @name QuarantineInterface implementation.
106 : // @{
107 : virtual bool Push(const Object& object);
108 : virtual bool Pop(Object* object);
109 : virtual void Empty(ObjectVector* objects);
110 : virtual size_t GetCount();
111 : virtual size_t GetLockId(const Object& object);
112 : virtual void Lock(size_t id);
113 : virtual void Unlock(size_t id);
114 : // @}
115 :
116 : protected:
117 : // @name SizeLimitedQuarantine interface.
118 : // @{
119 : virtual bool PushImpl(const Object& object) = 0;
120 : virtual bool PopImpl(Object* object) = 0;
121 : virtual void EmptyImpl(ObjectVector* objects) = 0;
122 : virtual size_t GetLockIdImpl(const Object& object) = 0;
123 : virtual void LockImpl(size_t id) = 0;
124 : virtual void UnlockImpl(size_t id) = 0;
125 : // @}
126 :
127 : // TODO(chrisha): RACE ALERT!
128 : // The member variables below need some mode of locking. If they're not
129 : // managed atomically to insertions/removal, then it seems it'll not be
130 : // possible to maintain an invariant where they can't e.g. drop below zero.
131 : // Maybe that's the right tradeoff, however, as the momentary size of the
132 : // quarantine is fairly unimportant.
133 :
134 : // Parameters controlling the quarantine invariant.
135 : size_t max_object_size_;
136 : size_t max_quarantine_size_;
137 :
138 : // The current size of the quarantine.
139 : size_t size_;
140 :
141 : // The number of elements in the quarantine.
142 : size_t count_;
143 :
144 : // The size functor.
145 : SizeFunctor size_functor_;
146 :
147 : private:
148 : DISALLOW_COPY_AND_ASSIGN(SizeLimitedQuarantineImpl);
149 : };
150 :
151 : } // namespace quarantines
152 : } // namespace asan
153 : } // namespace agent
154 :
155 : #include "syzygy/agent/asan/quarantines/size_limited_quarantine_impl.h"
156 :
157 : #endif // SYZYGY_AGENT_ASAN_QUARANTINES_SIZE_LIMITED_QUARANTINE_H_
|