/src/resiprocate/rutil/StlPoolAllocator.hxx
Line | Count | Source |
1 | | #ifndef StlPoolAllocator_Include_Guard |
2 | | #define StlPoolAllocator_Include_Guard |
3 | | |
4 | | #include <limits> |
5 | | #include <memory> |
6 | | #include <stddef.h> |
7 | | |
8 | | // .bwc. gcc 4.2 and above support stateful allocators. I don't know about other |
9 | | // compilers; if you do, add them here please. |
10 | | #if ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) ) || ( __GNUC__ > 4 ) |
11 | | #define RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT |
12 | | #endif |
13 | | |
14 | | #ifdef max // Max is defined under WIN32 and conflicts with std::numeric_limits<size_type>::max use below |
15 | | #undef max |
16 | | #endif |
17 | | |
18 | | namespace resip |
19 | | { |
20 | | /** |
21 | | A dirt-simple lightweight stl pool allocator meant for use in short-lifetime |
22 | | objects. This will pool-allocate at most S bytes, after which no further pool |
23 | | allocation will be performed, and fallback to the system new/delete will be |
24 | | used (deallocating a pool allocated object will _not_ free up room in the |
25 | | pool). |
26 | | */ |
27 | | template<typename T, typename P> |
28 | | class StlPoolAllocator |
29 | | { |
30 | | public: |
31 | | typedef T value_type; |
32 | | typedef value_type* pointer; |
33 | | typedef const value_type* const_pointer; |
34 | | typedef value_type& reference; |
35 | | typedef const value_type& const_reference; |
36 | | typedef size_t size_type; |
37 | | typedef ptrdiff_t difference_type; |
38 | | |
39 | | #ifdef RESIP_HAS_STATEFUL_ALLOCATOR_SUPPORT |
40 | | explicit StlPoolAllocator(P* pool=0) : |
41 | 411k | mPool(pool){} resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*) Line | Count | Source | 41 | 366k | mPool(pool){} |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*) Line | Count | Source | 41 | 267 | mPool(pool){} |
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*) Line | Count | Source | 41 | 25.0k | mPool(pool){} |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*) Line | Count | Source | 41 | 9.51k | mPool(pool){} |
resip::StlPoolAllocator<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, resip::PoolBase>::StlPoolAllocator(resip::PoolBase*) Line | Count | Source | 41 | 9.51k | mPool(pool){} |
|
42 | | StlPoolAllocator(const StlPoolAllocator& other) : |
43 | 438k | mPool(other.mPool){} resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase> const&) Line | Count | Source | 43 | 366k | mPool(other.mPool){} |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase> const&) Line | Count | Source | 43 | 267 | mPool(other.mPool){} |
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase> const&) Line | Count | Source | 43 | 25.0k | mPool(other.mPool){} |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase> const&) Line | Count | Source | 43 | 9.51k | mPool(other.mPool){} |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::StlPoolAllocator(resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase> const&) Line | Count | Source | 43 | 36.9k | mPool(other.mPool){} |
|
44 | | StlPoolAllocator& operator=(const StlPoolAllocator& rhs) |
45 | | { |
46 | | if (&rhs != this) |
47 | | { |
48 | | mPool=rhs.mPool; |
49 | | } |
50 | | return *this; |
51 | | } |
52 | | #else |
53 | | // Disable pool allocation if stateful allocators are not supported by the |
54 | | // STL |
55 | | explicit StlPoolAllocator(P* pool=0) : |
56 | | mPool(0){} |
57 | | StlPoolAllocator(const StlPoolAllocator& other) : |
58 | | mPool(0){} |
59 | | StlPoolAllocator& operator=(const StlPoolAllocator& rhs) |
60 | | { |
61 | | return *this; |
62 | | } |
63 | | #endif |
64 | | |
65 | | |
66 | | template<typename U> |
67 | | StlPoolAllocator(const StlPoolAllocator<U,P>& other) : |
68 | 9.51k | mPool(other.mPool){} |
69 | | |
70 | 858k | ~StlPoolAllocator(){} resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 733k | ~StlPoolAllocator(){} |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 534 | ~StlPoolAllocator(){} |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 46.4k | ~StlPoolAllocator(){} |
resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 50.0k | ~StlPoolAllocator(){} |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 19.0k | ~StlPoolAllocator(){} |
resip::StlPoolAllocator<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, resip::PoolBase>::~StlPoolAllocator() Line | Count | Source | 70 | 9.51k | ~StlPoolAllocator(){} |
|
71 | | |
72 | | |
73 | | template<typename U> |
74 | | struct rebind |
75 | | { |
76 | | typedef StlPoolAllocator<U, P> other; |
77 | | }; |
78 | | |
79 | | pointer address(reference ref) const |
80 | | { |
81 | | return &ref; |
82 | | } |
83 | | |
84 | | const_pointer address(const_reference ref) const |
85 | | { |
86 | | return &ref; |
87 | | } |
88 | | |
89 | | pointer allocate(size_type n, const void* hint=0) |
90 | 74.4k | { |
91 | 74.4k | return (pointer)(allocate_raw(n*sizeof(T))); |
92 | 74.4k | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::allocate(unsigned long, void const*) Line | Count | Source | 90 | 21.7k | { | 91 | 21.7k | return (pointer)(allocate_raw(n*sizeof(T))); | 92 | 21.7k | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::allocate(unsigned long, void const*) Line | Count | Source | 90 | 267 | { | 91 | 267 | return (pointer)(allocate_raw(n*sizeof(T))); | 92 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::allocate(unsigned long, void const*) Line | Count | Source | 90 | 29.0k | { | 91 | 29.0k | return (pointer)(allocate_raw(n*sizeof(T))); | 92 | 29.0k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::allocate(unsigned long, void const*) Line | Count | Source | 90 | 9.56k | { | 91 | 9.56k | return (pointer)(allocate_raw(n*sizeof(T))); | 92 | 9.56k | } |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::allocate(unsigned long, void const*) Line | Count | Source | 90 | 13.7k | { | 91 | 13.7k | return (pointer)(allocate_raw(n*sizeof(T))); | 92 | 13.7k | } |
|
93 | | |
94 | | void deallocate(pointer ptr, size_type n) |
95 | 74.4k | { |
96 | 74.4k | deallocate_raw((void*)ptr); |
97 | 74.4k | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::deallocate(resip::HeaderFieldValue*, unsigned long) Line | Count | Source | 95 | 21.7k | { | 96 | 21.7k | deallocate_raw((void*)ptr); | 97 | 21.7k | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::deallocate(resip::ParserContainerBase::HeaderKit*, unsigned long) Line | Count | Source | 95 | 267 | { | 96 | 267 | deallocate_raw((void*)ptr); | 97 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::deallocate(resip::Parameter**, unsigned long) Line | Count | Source | 95 | 29.0k | { | 96 | 29.0k | deallocate_raw((void*)ptr); | 97 | 29.0k | } |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::deallocate(std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>*, unsigned long) Line | Count | Source | 95 | 13.7k | { | 96 | 13.7k | deallocate_raw((void*)ptr); | 97 | 13.7k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::deallocate(resip::HeaderFieldValueList**, unsigned long) Line | Count | Source | 95 | 9.56k | { | 96 | 9.56k | deallocate_raw((void*)ptr); | 97 | 9.56k | } |
|
98 | | |
99 | | inline void* allocate_raw(size_type bytes) |
100 | 74.4k | { |
101 | 74.4k | if(mPool) |
102 | 45.7k | { |
103 | 45.7k | return mPool->allocate(bytes); |
104 | 45.7k | } |
105 | 28.7k | return ::operator new(bytes); |
106 | 74.4k | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::allocate_raw(unsigned long) Line | Count | Source | 100 | 21.7k | { | 101 | 21.7k | if(mPool) | 102 | 21.7k | { | 103 | 21.7k | return mPool->allocate(bytes); | 104 | 21.7k | } | 105 | 0 | return ::operator new(bytes); | 106 | 21.7k | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::allocate_raw(unsigned long) Line | Count | Source | 100 | 267 | { | 101 | 267 | if(mPool) | 102 | 267 | { | 103 | 267 | return mPool->allocate(bytes); | 104 | 267 | } | 105 | 0 | return ::operator new(bytes); | 106 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::allocate_raw(unsigned long) Line | Count | Source | 100 | 29.0k | { | 101 | 29.0k | if(mPool) | 102 | 392 | { | 103 | 392 | return mPool->allocate(bytes); | 104 | 392 | } | 105 | 28.7k | return ::operator new(bytes); | 106 | 29.0k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::allocate_raw(unsigned long) Line | Count | Source | 100 | 9.56k | { | 101 | 9.56k | if(mPool) | 102 | 9.56k | { | 103 | 9.56k | return mPool->allocate(bytes); | 104 | 9.56k | } | 105 | 0 | return ::operator new(bytes); | 106 | 9.56k | } |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::allocate_raw(unsigned long) Line | Count | Source | 100 | 13.7k | { | 101 | 13.7k | if(mPool) | 102 | 13.7k | { | 103 | 13.7k | return mPool->allocate(bytes); | 104 | 13.7k | } | 105 | 0 | return ::operator new(bytes); | 106 | 13.7k | } |
|
107 | | |
108 | | void deallocate_raw(void* ptr) |
109 | 74.4k | { |
110 | 74.4k | if(mPool) |
111 | 45.7k | { |
112 | 45.7k | mPool->deallocate(ptr); |
113 | 45.7k | return; |
114 | 45.7k | } |
115 | 28.7k | ::operator delete(ptr); |
116 | 28.7k | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::deallocate_raw(void*) Line | Count | Source | 109 | 21.7k | { | 110 | 21.7k | if(mPool) | 111 | 21.7k | { | 112 | 21.7k | mPool->deallocate(ptr); | 113 | 21.7k | return; | 114 | 21.7k | } | 115 | 0 | ::operator delete(ptr); | 116 | 0 | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::deallocate_raw(void*) Line | Count | Source | 109 | 267 | { | 110 | 267 | if(mPool) | 111 | 267 | { | 112 | 267 | mPool->deallocate(ptr); | 113 | 267 | return; | 114 | 267 | } | 115 | 0 | ::operator delete(ptr); | 116 | 0 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::deallocate_raw(void*) Line | Count | Source | 109 | 29.0k | { | 110 | 29.0k | if(mPool) | 111 | 392 | { | 112 | 392 | mPool->deallocate(ptr); | 113 | 392 | return; | 114 | 392 | } | 115 | 28.7k | ::operator delete(ptr); | 116 | 28.7k | } |
resip::StlPoolAllocator<std::__1::__list_node<std::__1::pair<resip::Data, resip::HeaderFieldValueList*>, void*>, resip::PoolBase>::deallocate_raw(void*) Line | Count | Source | 109 | 13.7k | { | 110 | 13.7k | if(mPool) | 111 | 13.7k | { | 112 | 13.7k | mPool->deallocate(ptr); | 113 | 13.7k | return; | 114 | 13.7k | } | 115 | 0 | ::operator delete(ptr); | 116 | 0 | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::deallocate_raw(void*) Line | Count | Source | 109 | 9.56k | { | 110 | 9.56k | if(mPool) | 111 | 9.56k | { | 112 | 9.56k | mPool->deallocate(ptr); | 113 | 9.56k | return; | 114 | 9.56k | } | 115 | 0 | ::operator delete(ptr); | 116 | 0 | } |
|
117 | | |
118 | | size_type max_size() const |
119 | 60.6k | { |
120 | 60.6k | if(mPool) |
121 | 31.9k | { |
122 | 31.9k | return mPool->max_size(); |
123 | 31.9k | } |
124 | 28.7k | return std::numeric_limits<size_type>::max()/sizeof(T); |
125 | 60.6k | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::max_size() const Line | Count | Source | 119 | 21.7k | { | 120 | 21.7k | if(mPool) | 121 | 21.7k | { | 122 | 21.7k | return mPool->max_size(); | 123 | 21.7k | } | 124 | 0 | return std::numeric_limits<size_type>::max()/sizeof(T); | 125 | 21.7k | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::max_size() const Line | Count | Source | 119 | 267 | { | 120 | 267 | if(mPool) | 121 | 267 | { | 122 | 267 | return mPool->max_size(); | 123 | 267 | } | 124 | 0 | return std::numeric_limits<size_type>::max()/sizeof(T); | 125 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::max_size() const Line | Count | Source | 119 | 29.0k | { | 120 | 29.0k | if(mPool) | 121 | 392 | { | 122 | 392 | return mPool->max_size(); | 123 | 392 | } | 124 | 28.7k | return std::numeric_limits<size_type>::max()/sizeof(T); | 125 | 29.0k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::max_size() const Line | Count | Source | 119 | 9.56k | { | 120 | 9.56k | if(mPool) | 121 | 9.56k | { | 122 | 9.56k | return mPool->max_size(); | 123 | 9.56k | } | 124 | 0 | return std::numeric_limits<size_type>::max()/sizeof(T); | 125 | 9.56k | } |
|
126 | | |
127 | | size_type max_size(size_type _sz) const |
128 | | { |
129 | | if(mPool) |
130 | | { |
131 | | return mPool->max_size(); |
132 | | } |
133 | | return std::numeric_limits<size_type>::max()/_sz; |
134 | | } |
135 | | |
136 | | void construct(pointer p, const_reference orig) |
137 | 2.57M | { |
138 | 2.57M | new (p) T(orig); |
139 | 2.57M | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::construct(resip::HeaderFieldValue*, resip::HeaderFieldValue const&) Line | Count | Source | 137 | 2.45M | { | 138 | 2.45M | new (p) T(orig); | 139 | 2.45M | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::construct(resip::ParserContainerBase::HeaderKit*, resip::ParserContainerBase::HeaderKit const&) Line | Count | Source | 137 | 267 | { | 138 | 267 | new (p) T(orig); | 139 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::construct(resip::Parameter**, resip::Parameter* const&) Line | Count | Source | 137 | 104k | { | 138 | 104k | new (p) T(orig); | 139 | 104k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::construct(resip::HeaderFieldValueList**, resip::HeaderFieldValueList* const&) Line | Count | Source | 137 | 12.0k | { | 138 | 12.0k | new (p) T(orig); | 139 | 12.0k | } |
|
140 | | |
141 | | void destroy(pointer ptr) |
142 | 2.57M | { |
143 | 2.57M | ptr->~T(); |
144 | 2.57M | } resip::StlPoolAllocator<resip::HeaderFieldValue, resip::PoolBase>::destroy(resip::HeaderFieldValue*) Line | Count | Source | 142 | 2.45M | { | 143 | 2.45M | ptr->~T(); | 144 | 2.45M | } |
resip::StlPoolAllocator<resip::ParserContainerBase::HeaderKit, resip::PoolBase>::destroy(resip::ParserContainerBase::HeaderKit*) Line | Count | Source | 142 | 267 | { | 143 | 267 | ptr->~T(); | 144 | 267 | } |
resip::StlPoolAllocator<resip::Parameter*, resip::PoolBase>::destroy(resip::Parameter**) Line | Count | Source | 142 | 104k | { | 143 | 104k | ptr->~T(); | 144 | 104k | } |
resip::StlPoolAllocator<resip::HeaderFieldValueList*, resip::PoolBase>::destroy(resip::HeaderFieldValueList**) Line | Count | Source | 142 | 12.0k | { | 143 | 12.0k | ptr->~T(); | 144 | 12.0k | } |
|
145 | | |
146 | | bool operator==(const StlPoolAllocator& rhs) const |
147 | | { |
148 | | return mPool == rhs.mPool; |
149 | | } |
150 | | |
151 | | bool operator!=(const StlPoolAllocator& rhs) const |
152 | | { |
153 | | return mPool != rhs.mPool; |
154 | | } |
155 | | |
156 | | P* mPool; |
157 | | }; |
158 | | |
159 | | } |
160 | | |
161 | | #endif |
162 | | |
163 | | |
164 | | /* ==================================================================== |
165 | | * The Vovida Software License, Version 1.0 |
166 | | * |
167 | | * Redistribution and use in source and binary forms, with or without |
168 | | * modification, are permitted provided that the following conditions |
169 | | * are met: |
170 | | * |
171 | | * 1. Redistributions of source code must retain the above copyright |
172 | | * notice, this list of conditions and the following disclaimer. |
173 | | * |
174 | | * 2. Redistributions in binary form must reproduce the above copyright |
175 | | * notice, this list of conditions and the following disclaimer in |
176 | | * the documentation and/or other materials provided with the |
177 | | * distribution. |
178 | | * |
179 | | * 3. The names "VOCAL", "Vovida Open Communication Application Library", |
180 | | * and "Vovida Open Communication Application Library (VOCAL)" must |
181 | | * not be used to endorse or promote products derived from this |
182 | | * software without prior written permission. For written |
183 | | * permission, please contact vocal@vovida.org. |
184 | | * |
185 | | * 4. Products derived from this software may not be called "VOCAL", nor |
186 | | * may "VOCAL" appear in their name, without prior written |
187 | | * permission of Vovida Networks, Inc. |
188 | | * |
189 | | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
190 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
191 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
192 | | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
193 | | * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
194 | | * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
195 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
196 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
197 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
198 | | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
199 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
200 | | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
201 | | * DAMAGE. |
202 | | * |
203 | | * ==================================================================== |
204 | | * |
205 | | * This software consists of voluntary contributions made by Vovida |
206 | | * Networks, Inc. and many individuals on behalf of Vovida Networks, |
207 | | * Inc. For more information on Vovida Networks, Inc., please see |
208 | | * <http://www.vovida.org/>. |
209 | | * |
210 | | */ |