15 #ifndef BOOST_LOCKFREE_FIFO_HPP_INCLUDED
16 #define BOOST_LOCKFREE_FIFO_HPP_INCLUDED
18 #include <boost/lockfree/atomic_int.hpp>
19 #include <boost/lockfree/detail/tagged_ptr.hpp>
20 #include <boost/lockfree/detail/freelist.hpp>
22 #include <boost/static_assert.hpp>
23 #include <boost/type_traits/is_pod.hpp>
26 #include <boost/scoped_ptr.hpp>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/noncopyable.hpp>
38 template <
typename T,
typename freelist_t,
typename Alloc>
42 BOOST_STATIC_ASSERT(boost::is_pod<T>::value);
44 struct BOOST_LOCKFREE_CACHELINE_ALIGNMENT node
51 next.set(NULL, next.get_tag()+1);
64 typedef typename Alloc::template rebind<node>::other node_allocator;
67 typedef typename boost::mpl::if_<boost::is_same<freelist_t, caching_freelist_t>,
73 static const bool is_lockfree = node::tagged_ptr_t::is_lockfree;
78 node * n = alloc_node();
83 explicit fifo(std::size_t initial_nodes):
86 node * n = alloc_node();
102 bool enqueue(T
const & t)
104 node * n = alloc_node(t);
111 atomic_node_ptr tail (tail_);
112 read_memory_barrier();
113 atomic_node_ptr next (tail->next);
115 if (likely(tail == tail_))
119 if ( tail->next.
cas(next, n) )
131 bool dequeue (T * ret)
135 atomic_node_ptr head (head_);
136 read_memory_barrier();
138 atomic_node_ptr tail(tail_);
139 node * next = head->next.
get_ptr();
141 if (likely(head == head_))
148 tail_.
cas(tail, next);
153 if (head_.
cas(head, next))
165 node * alloc_node(
void)
167 node * chunk = pool.allocate();
172 node * alloc_node(T
const & t)
174 node * chunk = pool.allocate();
179 void dealloc_node(node * n)
185 atomic_node_ptr head_;
186 static const int padding_size = 64 -
sizeof(atomic_node_ptr);
188 char padding1[padding_size];
189 atomic_node_ptr tail_;
190 char padding2[padding_size];
201 template <
typename T,
203 typename Alloc = std::allocator<T>
212 explicit fifo(std::size_t initial_nodes):
223 template <
typename T,
typename freelist_t,
typename Alloc>
224 class fifo<T*, freelist_t, Alloc>:
229 template <
typename smart_ptr>
230 bool dequeue_smart_ptr(smart_ptr & ptr)
233 bool success = fifo_t::dequeue(&result);
244 explicit fifo(std::size_t initial_nodes):
245 fifo_t(initial_nodes)
250 return fifo_t::enqueue(t);
253 bool dequeue (T ** ret)
255 return fifo_t::dequeue(ret);
258 bool dequeue (std::auto_ptr<T> & ret)
260 return dequeue_smart_ptr(ret);
263 bool dequeue (boost::scoped_ptr<T> & ret)
265 BOOST_STATIC_ASSERT(
sizeof(boost::scoped_ptr<T>) ==
sizeof(T*));
266 return dequeue(reinterpret_cast<T**>(&ret));
269 bool dequeue (boost::shared_ptr<T> & ret)
271 return dequeue_smart_ptr(ret);
bool cas(tagged_ptr const &oldval, T *newptr)