Skip to content

try_enqueue() fail when queue size went down to 0 #292

@solokacher

Description

@solokacher

Hi, I have the following code snippet that is stuck in the loop of doing try_enqueue(), and hence some remaining threads doing try_dequeue(). (not always repros, had to run it in a bash loop)

  ConcurrentQueue<int> queue(100);

  for (auto i = 0; i < 1000; ++i) {
    threads.push_back(thread([i, &queue, &bitmap, &count]() {
      auto index = i;
      while (!queue.try_enqueue(index)) {
        yield();
      }
    }));

    threads.push_back(thread([&queue, &bitmap, &count]() {
      int index = -1;
      while (!queue.try_dequeue(index)) {
        yield();
      }
    }));
  }

  for (auto& thread : threads) {
    thread.join();
  }

At the time of hang, I could see the queue.size_approx() is 0, but try_enqueue() cannot find a block to use so it fails all the time. My assumption is that we have freelist that holds the blocks, and size 0 implies freelist should hold something.

I feel that I made some wrong assumptions around the queue's internal logic. Would you please correct me :) and help me understand why there's a hang here.

When removing the initial size 100 from the constructor, and guarding the queue size to 100 with my own atomic<int>, the hang seems to go away.

Code compiled with g++ (Ubuntu 9.4.0-1ubuntu1~16.04) 9.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions