Module 7: Synchronization
  Lecture 14: Scalable Locks and Barriers
 


Centralized Barrier

struct bar_type {
int counter;
struct lock_type lock;
int flag = 0;
} bar_name ;
BARINIT ( bar_name ) {
LOCKINIT( bar_name.lock );
bar_name.counter = 0;
}

BARRIER ( bar_name , P) {
int my_count ;
LOCK ( bar_name.lock );
if (! bar_name.counter ) {
bar_name.flag = 0; /* first one */
}
my_count = ++ bar_name.counter ;
UNLOCK ( bar_name.lock );
if ( my_count == P) {
bar_name.counter = 0;
bar_name.flag = 1; /* last one */
}
else {
while (! bar_name.flag );
}
}

Sense Reversal

  • The last implementation fails to work for two consecutive barrier invocations
    • Need to prevent a process from entering a barrier instance until all have left the previous instance
    • Reverse the sense of a barrier i.e. every other barrier will have the same sense: basically attach parity or sense to a barrier
 

BARRIER ( bar_name , P) {
local sense = ! local_sense ; /* this is private per processor */
LOCK ( bar_name.lock );
bar_name.counter ++;
if ( bar_name.counter == P) {
UNLOCK ( bar_name.lock );
bar_name.counter = 0;
bar_name.flag = local_sense ;
}
else {
UNLOCK ( bar_name.lock );
while ( bar_name.flag != local_sense );
}
}