// This Barrier works even for multiple calls. // Header file barrierm.h for class Barrier // Includes all functions associated with the Barrier // To use a Barrier, first share a pointer variable of size // (Barrier*) and use the constructor function on that pointer // passing the numtoblock. // For example, if 3 processes are to be blocked, // Barrier *B; // B = (Barrier*)shareint(sizeof(Barrier*), shareid); // B->Barrier(3); #ifndef BARRIER_H #define BARRIER_H #include "utility.h" class Barrier { public: Barrier(); //default constructor ~Barrier() {} //destructor void Barrierinit(int numtoblock); // Initialize barrier void WaitAtBarrier(); //Blocks processes void SemRelease(); //Releases Semaphores private: int toblock; //number of processes to be blocked int blocked; // number blocked int released; //number released int gate; //ID of spinlock to enforce barrier }; Barrier::Barrier() { toblock = blocked = gate = 0; } void Barrier::Barrierinit(int numtoblock) { toblock = numtoblock; //number of processes that will call released = 0; // none released yet blocked = 0; // no process trapped yet spin_lock_init(gate, 0);//initialize spinlock controlling barrier } void Barrier::WaitAtBarrier() { int done; int newproc; done=0; newproc=1; // a new process arrives at the barrier // and is blocked till done =1; // Note done =1 only when all processes arrive // at the barrier and is in release mode; while (done==0) { spin_lock(gate); if (newproc==1 && released>0) { spin_unlock(gate); //New process and in release } // mode. This new process is at // a new subsequent barrier, while // others are still being released // at the previous barrier. //Simply keep spinning else //one or both of the following are true // released=0 | newproc=0 { if (newproc==1) //New process and is being trapped. { blocked++; // released =0 at this point. newproc=0; // This process is no longer new } // and is waiting to be released if ((blocked