Reputation: 1323
I was reading about barriers found an example in Wikipedia. I have doubt whether it is correct. Here is the code from ( https://en.wikipedia.org/wiki/Barrier_(computer_science)#Implementation )
struct barrier_type
{
// how many processors have entered the barrier
// initialize to 0
int arrive_counter;
// how many processors have exited the barrier
// initialize to P
int leave_counter;
int flag;
std::mutex lock;
};
// barrier for p processors
void barrier(barrier_type* b, int p)
{
b->lock.lock();
if (b->leave_counter == P)
{
if (b->arrive_counter == 0) // no other threads in barrier
{
b->flag = 0; // first arriver clears flag
}
else
{
b->lock.unlock();
while (b->leave_counter != P); // wait for all to leave before clearing
b->lock.lock();
b->flag = 0; // first arriver clears flag
}
}
b->arrive_counter++;
int arrived = b->arrive_counter;
b->lock.unlock();
if (arrived == p) // last arriver sets flag
{
b->arrive_counter = 0;
b->leave_counter = 1;
b->flag = 1;
}
else
{
while (b->flag == 0); // wait for flag
b->lock.lock();
b->leave_counter++;
b->lock.unlock();
}
}
In barrier function, before entering the first if
block, leave_counter
is compared with P
to check, whether it equals to P
. Again in the else
block, there is a comparison.
What is the reason for the second comparison, since the control entered only when leave_counter
value is P
? Am I missing something here?
Upvotes: 3
Views: 641
Reputation: 6659
The mutex is locked before the initial test of leave_counter
, blocking all other threads.
If the caller is not the first to pass, it unlocks the mutex and then spin-waits in the
while ( b->leave_counter != P )
, allowing the other threads to proceed.
Eventually, b->leave_counter == P
and the caller proceeds.
Upvotes: 1