[boost.lockfree][spsc_queue] runtime sizing and producer's thread
Hi, Two questions on lockfree spsc_queue: 1. Can spsc_queue be dynamically (runtime) sized, and if so how do you correctly do it? * Creating a mpmc queue with size 0 (i.e. queue<T>(0)) creates a dynamically sizes mpmc queue, but doing the same for spsc queue doesn't. * creating a spsc queue with size 10 (i.e. queue<T>(10)) seems to create a fixed sized ring buffer since at high transfer rates, push fails, however the constructor code that takes the size asserts that it's runtime sized. explicit spsc_queue(size_type element_count): base_type(element_count) { BOOST_ASSERT(runtime_sized); } * documentation mentions lockfree::fixed_sized<> in policies, and can also be found in (mpmc) queue.hpp, but it doesn't seem to be in spsc_queue.hpp * all examples I could find on the internet (and documentation) was for fixed size or for mpmc dynamic, but not for spsc dynamic. 2. In a normal (spsc using) program the producer will be a single OS thread; however is it still safe to use on something like an actor framework or fiber framework? (i.e. you only have a single producer object, but it can actually be executed in different threads -- though strictly on one thread at any given time). for example in spsc_queue.hpp there's some code such as: bool push(T const & t, T * buffer, size_t max_size) { const size_t write_index = write_index_.load(memory_order_relaxed); // only written from push thread Refs on actors/fibers: https://en.wikipedia.org/wiki/Fiber_%28computer_science%29 https://en.wikipedia.org/wiki/Actor_model Thank you. Sampath Tilakumara
On 11/05/2016 20:06, Sampath Tilakumara wrote:
Two questions on lockfree spsc_queue:
1. Can spsc_queue be dynamically (runtime) sized, and if so how do you correctly do it?
* Creating a mpmc queue with size 0 (i.e. queue<T>(0)) creates a dynamically sizes mpmc queue, but doing the same for spsc queue doesn't. * creating a spsc queue with size 10 (i.e. queue<T>(10)) seems to create a fixed sized ring buffer since at high transfer rates, push fails, however the constructor code that takes the size asserts that it's runtime sized. explicit spsc_queue(size_type element_count): base_type(element_count) { BOOST_ASSERT(runtime_sized); }
* documentation mentions |lockfree::fixed_sized<> in policies, and can also be found in (mpmc) queue.hpp, but it doesn't seem to be in spsc_queue.hpp | | * all examples I could find on the internet (and documentation) was for fixed size or for mpmc dynamic, but not for spsc dynamic. |
The spsc_queue is always a fixed size at construction time -- your choice is whether this size is fixed by the type itself (via the capacity<> policy) or per instance (via the constructor). You can't expand the capacity of an existing instance in either case.
2. In a normal (spsc using) program the producer will be a single OS thread; however is it still safe to use on something like an actor framework or fiber framework? (i.e. you only have a single producer object, but it can actually be executed in different threads -- though strictly on one thread at any given time).
It implements a simple ringbuffer, so it is safe as long as there can never be two concurrent calls to push nor two concurrent calls to pop (one call to push concurrent with one call to pop is safe). It does not matter which threads those calls are made on as long as you can provide that guarantee.
participants (2)
-
Gavin Lambert
-
Sampath Tilakumara