11 #ifndef BOOST_LOCKFREE_FREELIST_HPP_INCLUDED
12 #define BOOST_LOCKFREE_FREELIST_HPP_INCLUDED
14 #include <boost/lockfree/detail/tagged_ptr.hpp>
15 #include <boost/lockfree/atomic_int.hpp>
16 #include <boost/noncopyable.hpp>
18 #include <boost/mpl/map.hpp>
19 #include <boost/mpl/apply.hpp>
20 #include <boost/mpl/at.hpp>
21 #include <boost/type_traits/is_pod.hpp>
32 template <
typename T,
typename Alloc = std::allocator<T> >
34 private boost::noncopyable,
40 return Alloc::allocate(1);
43 void deallocate (T * n)
45 Alloc::deallocate(n, 1);
53 std::size_t maximum_size = 64,
54 typename Alloc = std::allocator<T> >
70 explicit freelist(std::size_t initial_nodes):
73 for (std::size_t i = 0; i != std::min(initial_nodes, maximum_size); ++i)
94 freelist_node * new_pool = old_pool->next.
get_ptr();
96 if (pool_.
cas(old_pool, new_pool))
99 return reinterpret_cast<T*
>(old_pool.
get_ptr());
104 void deallocate (T * n)
106 if (free_list_size > maximum_size)
116 freelist_node * new_pool =
reinterpret_cast<freelist_node*
>(n);
118 new_pool->next.set_ptr(old_pool.
get_ptr());
120 if (pool_.
cas(old_pool, new_pool))
129 void free_memory_pool(
void)
135 freelist_node * n = current.
get_ptr();
136 current.
set(current->next);
145 template <
typename T,
typename Alloc = std::allocator<T> >
164 for (std::size_t i = 0; i != initial_nodes; ++i)
185 freelist_node * new_pool = old_pool->next.
get_ptr();
187 if (pool_.
cas(old_pool, new_pool))
188 return reinterpret_cast<T*>(old_pool.
get_ptr());
192 void deallocate (T * n)
198 freelist_node * new_pool =
reinterpret_cast<freelist_node*
>(n);
200 new_pool->next.set_ptr(old_pool.
get_ptr());
202 if (pool_.
cas(old_pool,new_pool))
208 void free_memory_pool(
void)
214 freelist_node * n = current.
get_ptr();
215 current.
set(current->next);
223 template <
typename T,
typename Alloc = std::allocator<T> >
236 pool_(NULL), total_nodes(max_nodes)
238 chunks = Alloc::allocate(max_nodes);
239 for (std::size_t i = 0; i != max_nodes; ++i)
241 T * node = chunks + i;
248 Alloc::deallocate(chunks, total_nodes);
260 freelist_node * new_pool = old_pool->next.
get_ptr();
262 if (pool_.
cas(old_pool, new_pool))
263 return reinterpret_cast<T*>(old_pool.
get_ptr());
267 void deallocate (T * n)
273 freelist_node * new_pool =
reinterpret_cast<freelist_node*
>(n);
275 new_pool->next.set_ptr(old_pool.
get_ptr());
277 if (pool_.
cas(old_pool,new_pool))
285 const std::size_t total_nodes;
297 template <
typename T,
typename Alloc,
typename tag>
298 struct select_freelist
301 typedef typename Alloc::template rebind<T>::other Allocator;
306 typedef typename boost::mpl::map<
312 typedef typename boost::mpl::at<freelists, tag>::type type;