Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with boost::lockfree::queue in shared memory (boost 1.53, gcc 4.7.2 / clang 3.0-6ubuntu3)

I have a problem with placing boost::lockfree::queue<<T, fixed_sized<false>, ..> in shared memory. I need it because I have to be able to insert more than 65535 messages into the queue, and fixed_sized queue is limited with 65535.
The following code works properly (but capacity<...> option implies fixed_sized<true>):

typedef boost::interprocess::allocator<
    MessageT, 
    boost::interprocess::managed_shared_memory::segment_manager>
        ShmemAllocator;
typedef boost::lockfree::queue<
    MessageT,
    boost::lockfree::capacity<65535>,
    boost::lockfree::allocator<ShmemAllocator> >
        Queue;
m_segment = new boost::interprocess::managed_shared_memory(
    boost::interprocess::create_only, segmentName, size);
Queue* m_queue = m_segment->construct<Queue>(
    queueName)(
    m_segment->get_segment_manager());
...
m_queue->bounded_push(message);

The following code works properly too (but it doesn't use shared memory):

boost::lockfree::queue<MessageT> q;
....
q.bounded_push(message);

But when I try to combine it:

typedef boost::interprocess::allocator<
    MessageT, 
    boost::interprocess::managed_shared_memory::segment_manager>
        ShmemAllocator;
typedef boost::lockfree::queue<
    MessageT,
    boost::lockfree::allocator<ShmemAllocator> >
        Queue;
m_segment = new boost::interprocess::managed_shared_memory(
    boost::interprocess::create_only, segmentName, size);
Queue* m_queue = m_segment->construct<Queue>(
    queueName)(
    m_segment->get_segment_manager());
...
m_queue->bounded_push(message);

it fails to compile with the following log:

In file included from src/model/Queue.h:16:

In file included from /home/uppi/lib/include/boost/lockfree/queue.hpp:24:

/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:171:28: error: no viable conversion from 'pointer' (aka 'offset_ptr<boost::lockfree::queue<PacketMessage,
      boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node, long, unsigned long, 0UL>') to
      'boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_,
      boost::parameter::void_>::node *'
                    return Alloc::allocate(1);
                           ~~~~~~~~~~~~~~~~~

/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:157:20: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage,
      boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node,
      boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_,
      boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned
      long, 0>, 0>, iset_index> > >::allocate_impl<true>' requested here
            return allocate_impl<Bounded>();


/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:89:20: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage,
      boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node,
      boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_,
      boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned
      long, 0>, 0>, iset_index> > >::allocate<true, true>' requested here
        T * node = allocate<ThreadSafe, Bounded>();


/home/uppi/lib/include/boost/lockfree/queue.hpp:281:34: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage,
      boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node,
      boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char,
      boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_,
      boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned
      long, 0>, 0>, iset_index> > >::construct<true, true, PacketMessage, boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage,
      boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >,
      boost::parameter::void_, boost::parameter::void_>::node *>' requested here
        node * n = pool.template construct<true, Bounded>(t, pool.null_handle());


/home/uppi/lib/include/boost/lockfree/queue.hpp:270:16: note: in instantiation of function template specialization 'boost::lockfree::queue<PacketMessage,
      boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family,
      boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::do_push<true>' requested here
        return do_push<true>(t);


src/model/Queue.inl:4:18: note: in instantiation of member function 'boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage,
      boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >,
      boost::parameter::void_, boost::parameter::void_>::bounded_push' requested here
        return m_queue->bounded_push(message);                         

/home/uppi/lib/include/boost/interprocess/offset_ptr.hpp:450:4: note: candidate function
   operator unspecified_bool_type() const

Please tell me what I'm missing

like image 921
uppi Avatar asked Feb 15 '13 11:02

uppi


1 Answers

using boost::lockfree::queue or boost::lockfree::stack in shared memory is limited to 65535 elements, for compatibility reasons. if you have a single-producer, single-consumer use-case, you might want to use the boost::lockfree::spsc_queue. however this is also not dynamically-sized.

reason for this is limitation is 32bit compatibility. for 64bit platforms one might be able to adapt the boost.lockfree code to use 32bit instead of 16bit indices. but it would require some non-trivial changes to implement things correctly.

like image 191
timblechmann Avatar answered Oct 06 '22 23:10

timblechmann