Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory ordering in boost::lockfree:queue

Consider the following structure:

struct T { 
 ~T() { delete[] buff; }
  int* buff = nullptr; };
T* t = new T();
auto queue = boost::lockfree::queue<T*>(0);
// Thread A
t->buff = int[10];
queue.push(t);
// Thread Z
T* t = nullptr;
while(true)
  if(queue.pop(t))
    delete t; // Is this OK? If not, what kind of synchronization I need to make it OK?

The general problem is that different threads (A to Y) work together on shared pointers (not std::shared_ptr). At some point, no one but Thread A works with a pointer t and Thread A sees everything others have done to *t, so Thread A can safely call delete t. Instead, it pushes t into a queue and Thread Z pops from the queue and does the delete t. The question is how do we make sure Thread Z sees the last value assigned to t->buff? Is there any synchronization in boost::lockfree::queue that guarantees this? or we need to do something ourselves (what)?

like image 283
Koosha Avatar asked Oct 16 '25 14:10

Koosha


1 Answers

Yes, this is safe! You have sole ownership over the value popped from the queue. push has to use memory_order_release (or stronger) and pop has to use memory_order_acquire (or stronger), because otherwise the implementation would be completely useless (you could do nothing with the pointer you just popped from the queue). I haven't checked the code, but you say that the implementation uses memory_order_seq_cst, so you should be good!

like image 117
mpoeter Avatar answered Oct 19 '25 03:10

mpoeter