mardi 26 septembre 2017

reusable barrier simple (alternating) implementation

std::mutex mutex;
std::condition_variable cv;
uint8_t size = 2;
uint8_t count = size;
uint8_t direction = -1;

const auto sync = [&size, &count, &mutex, &cv, &direction]()  //.
{
    {
        std::unique_lock<std::mutex> lock(mutex);
        auto current_direction = direction;
        if (--count != 0)
        {
            count = size;
            direction *= -1;
            cv.notify_all();
        }
        else
        {
            cv.wait(lock,
                    [&direction, &current_direction]()  //.
                    { return direction != current_direction; });
        }
    }
};

as provided in the first unaccepted answer of reusable barrier

a 'generation' must be stored inside a barrier object to prevent a next generation from manipulating the wake up 'condition' of the current generation for a given set of threads. What I do not like about the first unaccepted answer is the growing counter of generations, I believe that we need only to differentiate between two generations at most that is if a thread satisfied the wait condition and started another barrier synchronization call as the second unaccepted solution suggests, the second solution however was somewhat complex and I believe that the above snippet would even be enough (currently implemented locally inside the main but could be abstracted into a struct). Am I correct in my 'belief' that a barrier can only be used simultaneously for 2 generations at most?

Aucun commentaire:

Enregistrer un commentaire