
bool enqueue(T const & t); Shouldn't this function throw an exception if t cannot be enqueued?
i would prefer not to throw an exception! if a constant-size freelist is used, the enqueue operation may fail, although no `error' occurred. i prefer this interface
If memory for the operation cannot be obtained, I believe common practice is to throw an exception. IMO, it does not matter if a fixed size pool is exhausted or the global heap, since the effect is the same -> a no op. With current interface I'd need to always check return value for every enqueue for out of memory conditions, something I don't need to do with any other container.
true ... but if you use the fixed-size memory pool, you would have to add a try/catch block ...
If I can do something about the error, then yes, I would -always- need to add a try/catch block, since the global heap may be exhausted just as the fixed-size memory pool can. What I am trying to say, is that I'd prefer the same semantic of enqueue(T const&) as any std::container::insert(T const&). std::vector<int> vec; vec.push_back(1); // may throw fifo<int> fifo; fifo.enqueue(1); // may throw With current interface, I'd need to do something like if(!fifo.enqueue(1)) { throw std::bad_alloc(); // Or something } I think the semantic's should be equal to that of std::containers, when possible. How about a compromise: void enqueue(const T&) throw(...) void try_enqueue(const T&) // no throw guarantee if T's copy constructor is no throw guarantee For reference, it might be a good idea to have a look at Intel's TBB concurrent_queue/vector and see what design decisions they've made. I've no practical use of TBB unfortunately, but I've studied it a bit in order to make a recommendation for my employer. Reference is here: TBB Reference<http://www.threadingbuildingblocks.org/uploads/81/91/Latest%20Open%20Source%20Documentation/Reference.pdf>
Would if suffice to add another constructor for that?
template<class Iterator> fifo(Iterator first, Iterator last)
Then you can have an optimized way of populating the lockfree container,without adding unsafe member functions.
for my most important use case, this would not be sufficient. during some times, i am accessing my fifos from a single thread only, during other times by multiple threads ...
It would be interesting if you could add some performance benchmarks between lockfree vs non-lockfree.
Slightly unrelated: Have you considered proposing your lockfree algorithms and datastructures as part of boost::intrusive? To me, using intrusive datastructures would be preferable in performance critical scenarios, and it's an excellent way of guaranteeing a non-throwing/non-failing enqueue operation (since the user can avoid the copy constructor all-together). A higher-level container such as the current lockfree:fifo could then be built upon such a foundation.