/* ****************SPIN12.C******** Jonathan W. Valvano April 21, 1998 Spinlock binary semaphore, without disabling interrupts */ void bWait(char *semaphore){ asm(" clra\n" // new value for semaphore "loop: minm [2,x]\n" // test and set " bcc loop\n"); } void bSignal(char *semaphore){ (*semaphore)=1; // compiler makes this atomic } /* Example Usage: //-------------------------Start of OutString------------------------ char mutex=1; // 1 means free, 0 means in use // Output String (NULL termination) void OutString(char *pt){ char letter; bWait(&mutex); while (letter=*pt++) OutChar(letter); bSignal(&mutex);} void main(void){ mutex=1; // initially free OutString("Hello World");} */ // reference Silberschatz Section 6.4.4 void Wait(sema4Ptr semaphore){ bWait(&semaphore->s3); // wait if other caller to Wait gets here first bWait(&semaphore->s1); // mutual exclusive access to value (semaphore->value)--; // basic function of Wait if((semaphore->value)<0){ bSignal(&semaphore->s1); // end of mutual exclusive access to value bWait(&semaphore->s2); // wait for value to go above 0 } else bSignal(&semaphore->s1); // end of mutual exclusive access to value bWait(&semaphore->s3); // let other callers to Wait get in } void Signal(sema4Ptr semaphore){ bWait(&semaphore->s1); // mutual exclusive access to value (semaphore->value)++; // basic function of Signal if((semaphore->value)<=0) bSignal(&semaphore->s2); // allow S2 spinner to continue bSignal(&semaphore->s1); // end of mutual exclusive access to value } void Initialize(sema4Ptr semaphore, int initial){ semaphore->s1=1; // first one to bWait(s1) continues semaphore->s2=0; // first one to bWait(s2) spins semaphore->s3=1; // first one to bWait(s3) continues semaphore->value=initial;} /* Example producer/consumer problem unsigned int *PutPt; // Pointer of where to put next unsigned int *GetPt; // Pointer of where to get next // FIFO is empty when Available is less than or equal to zero // FIFO is full when RoomLeft is less than or equal to zero sema4Type RoomLeft; // Semaphore counting empty spaces sema4Type Available; // Semaphore counting data in fifo char Mutex; // binary semaphore for mutual exclusion #define FifoSize 10 unsigned int Fifo[FifoSize]; // The statically allocated fifo data void InitFifo(void) { Initialize(&RoomLeft,FifoSize-1); // Maximum storage capability Initialize(&Available,0); // Initially empty Mutex=1; PutPt=GetPt=&Fifo[0]; } void Put(unsigned int data) { Wait(&RoomLeft); bWait(&Mutex); *(PutPt++)=data; // Put data into fifo if (PutPt==&Fifo[FifoSize]) PutPt = &Fifo[0]; bSignal(&Mutex); Signal(&Available); } unsigned int Get(void) { unsigned int data; Wait(&Available); bWait(&Mutex); data=*(GetPt++); if (GetPt==&Fifo[FifoSize]) GetPt = &Fifo[0]; bSignal(&Mutex); Signal(&RoomLeft); return(data);} void main(void){ unsigned int n; InitFifo(); Put(5); Put(6); n=Get(); n=Get();} */