#ifndef BOUNDED_BUFFER_H_ #define BOUNDED_BUFFER_H_ #include "pthreads-semaphore.h" // has semaphoreObj class // ---- Class for buffer of fixed size, with synchronization --------- // If compiled with DEBUG flag: // Prints informational message to cerr. // Requires "outLock" declared as a global variable in the calling // program. #ifdef DEBUG #include "pthreads-lock.h" extern lockObj outLock; #endif // DEBUG template class boundedBuffer { public: // Constructor. boundedBuffer(const int sz) : mutex(1), notEmpty(0), notFull(sz) { bufferSize = sz; buffer = new T[sz]; nextToRemove = 0; numElements = 0; } // Destructor. ~boundedBuffer(void) { delete [] buffer; } // Put "itm" into buffer, with appropriate synchronization. void put(const T itm) { notFull.wait(); mutex.wait(); #ifdef DEBUG outLock.lock(); cerr << "**Adding item to buffer, numElements = " << numElements << endl; outLock.unlock(); #endif // DEBUG unsigned int next = (nextToRemove + numElements) % bufferSize; buffer[next] = itm; ++numElements; mutex.signal(); notEmpty.signal(); } // Get item from buffer and return, with appropriate synchronization. T get(void) { notEmpty.wait(); mutex.wait(); #ifdef DEBUG outLock.lock(); cerr << "**Removing item from buffer, numElements = " << numElements << endl; outLock.unlock(); #endif // DEBUG T returnVal = buffer[nextToRemove]; nextToRemove = (nextToRemove + 1) % bufferSize; --numElements; mutex.signal(); notFull.signal(); return returnVal; } private: // Make copy constructor and assignment operator private // so they can't be used (since it's not clear this would // make sense). boundedBuffer(const boundedBuffer & bb); boundedBuffer & operator= (const boundedBuffer & bb); // Member variables. // Variables for buffer -- implemented as a circular array: T * buffer; unsigned int bufferSize; unsigned int nextToRemove; unsigned int numElements; // Variables for synchronization: semaphoreObj mutex; // will be zero if buffer is "locked" // (in use by another thread) semaphoreObj notEmpty; // value should be number of slots // not empty -- i.e., in use semaphoreObj notFull; // value should be number of slots // not full -- i.e., empty }; #endif // BOUNDED_BUFFER_H_