Search code examples
c++multithreadingc++11lock-free

How to write a blockng waitUntil() method to a pool that uses std::atomics


I have a validation class that uses ah threadpool to process all of its jobs.

Now, when the user asks, I start a thread that feeds my validation class with jobs by reading from disk. And I am certain that at one point reading will be faster than processing. So I want to write a method that allows this thread to wait if there are more than, say, 1000 jobs being processed.

I already introduced an atomic that increases when a job is added and decreases when one is finished.

My attempt to add a method have been less than pretty. And I know it must be possible to use something better.

void Validator::waitUntilAvailable() {
    while (m_blocksInFlight > 1000) { // thats my atomic
        usleep(50000); // seems to be unavailable on Windows.
    }
}

Would anyone here be able to assist in having a non-polling method to solve my issue?

Thank you.


Solution

  • There is a condition that your would like to wait for, but no waiting mechanism.

    That mechanism is std::condition_variable and std::mutex. E.g.:

    class Validator
    {
        std::mutex m_mutex;
        std::condition_variable m_condition;
        std::atomic<int> m_blocksInFlight{0};
    
        bool test() const {
            return m_blocksInFlight.load(std::memory_order_relaxed) > 1000;
        }
    
        void addJob() {
            ++m_blocksInFlight;
    
            // Only lock the mutex when the test succeeds.
            if(this->test()) {
                std::unique_lock<decltype(m_mutex)> lock(m_mutex);
                m_condition.notify_one();
            }
        }
    
        void waitUntilAvailable() {
            std::unique_lock<decltype(m_mutex)> lock(m_mutex);
            while(!this->test())
                m_condition.wait(lock);
        }
    };