2 // Copyright (C) 2009 Tim Blechmann
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef UTILITIES_STATIC_POOLED_CLASS_HPP
20 #define UTILITIES_STATIC_POOLED_CLASS_HPP
24 #include <boost/mpl/equal_to.hpp>
25 #include <boost/mpl/if.hpp>
27 #include "freelist.hpp"
28 #include "static_pool.hpp"
34 * base class for a class, which uses a static memory pool for
37 * memory is allocated from a static pool and freed to a lock-free
38 * freelist, which is freed during the memory allocation routine.
39 * this way, the derived class can be allocated and freed from
40 * different threads, while all the access to the pool is done from
41 * the allocating thread.
43 * \tparam pool_locking specifies the locking policy for the object
44 * pool (default: nonblocking)
46 * \tparam recover_count limits the number of objects to be disposed
47 * from the freelist to avoid (default: dispose all objects
50 * \todo we could allocate one word more and store the size of the
51 * chunk just before the object. if a disposed object is large
52 * enough for a request, it wouldn't need to be added to the
56 template <typename tag
,
57 std::size_t pool_size
,
58 bool pool_locking
= false,
59 unsigned int recover_count
= 0 >
60 class static_pooled_class
63 static_pooled_class(void)
66 static_pooled_class(static_pooled_class
const & rhs
)
69 ~static_pooled_class(void)
73 /** free one object from freelist
75 * \return true if freelist is empty
78 static inline bool free_disposed_object(void)
80 void * chunk
= disposed_objects
.pop();
83 object_pool
.free(chunk
);
87 struct disposing_allocator
89 static void * allocate(std::size_t size
)
91 free_disposed_objects();
92 return object_pool
.malloc(size
);
96 struct dispose_n_object_allocator
98 static void * allocate(std::size_t size
)
100 for (unsigned int i
= 0; i
!= recover_count
; ++i
) {
101 bool freelist_empty
= free_disposed_object();
108 void * ret
= object_pool
.malloc(size
);
112 if (free_disposed_object())
113 return NULL
; /* no object in freelist, we */
118 typedef typename
boost::mpl::equal_to
<boost::mpl::int_
<recover_count
>,
121 typedef typename
boost::mpl::if_
<greater_zero
,
122 dispose_n_object_allocator
,
127 static inline void * allocate(std::size_t size
)
129 #ifndef NOVA_MEMORY_DEBUGGING
130 size
= std::max(2*sizeof(void*), size
); /* size requirement for lockfree freelist */
131 return allocator::allocate(size
);
137 inline void* operator new(std::size_t size
)
139 return allocate(size
);
142 static inline void free_disposed_objects(void)
145 if (free_disposed_object())
150 static inline void deallocate(void * p
)
152 #ifndef NOVA_MEMORY_DEBUGGING
153 disposed_objects
.push(p
);
159 inline void operator delete(void * p
)
164 typedef static_pool
<pool_size
, pool_locking
> object_pool_type
;
166 static object_pool_type object_pool
;
167 static freelist disposed_objects
;
170 template <typename tag
,
171 std::size_t pool_size
,
173 unsigned int recover_count
>
174 typename static_pooled_class
<tag
, pool_size
, pool_locking
, recover_count
>::object_pool_type
175 static_pooled_class
<tag
, pool_size
, pool_locking
, recover_count
>::object_pool(true);
177 template <typename tag
,
178 std::size_t pool_size
,
180 unsigned int recover_count
>
181 freelist static_pooled_class
<tag
, pool_size
, pool_locking
, recover_count
>::disposed_objects
;
184 } /* namespace nova */
186 #endif /* UTILITIES_STATIC_POOLED_CLASS_HPP */