dimanche 19 mai 2019

C++11 memory_model_relaxed and memory_order_seq_cst relation

Hi I am trying to understand lock-free work stealing dequeue implementation. Currently, I am reading one implementation by google's filament here. I am mostly concerned about the steal operation.

template <typename TYPE, size_t COUNT>
TYPE WorkStealingDequeue<TYPE, COUNT>::steal() noexcept {
    do {
        // mTop must be read before mBottom
        int32_t top = mTop.load(std::memory_order_seq_cst);

        // mBottom is written concurrently to the read below in pop() or push(), so
        // we need basic atomicity. Also makes sure that writes made in push()
        // (prior to mBottom update) are visible.
        int32_t bottom = mBottom.load(std::memory_order_acquire);

        if (top >= bottom) { 
            // queue is empty
            return TYPE();
        }

        // The queue isn't empty
        TYPE item(getItemAt(top));
        if (mTop.compare_exchange_strong(top, top + 1,
                std::memory_order_seq_cst,
                std::memory_order_relaxed)) {
            // success: we stole a job, just return it.
            return item;
        }
        // failure: the item we just tried to steal was pop()'ed under our feet,
        // simply discard it; nothing to do.
    } while (true);
}

I am wondering whether it's correct to replace the initial mtop.load memory order to memory_order_relaxed and the subsequent mBottom.load memory order to memory_order_seq_cst. This should still preserve the mtop.load and mBottom.load order right? memory_order_seq_cst flag should still prevent memory_order_relaxed to be reordered pass the the load operation right?

Aucun commentaire:

Enregistrer un commentaire