#ifndef BOUNDED_BUFFER_H_ #define BOUNDED_BUFFER_H_ #include // has pthread_ routines // ---- Class for "buffer" (array of type T) of fixed size ----------- // This version of the class is implemented using condition variables. template class boundedBuffer { private: T * buffer; unsigned int bufferSize; pthread_mutex_t bufferLock; pthread_cond_t bufferNotEmpty; pthread_cond_t bufferNotFull; // Implement as circular array: unsigned int nextToRemove; // index of next element to remove unsigned int numElements; // number of elements public: // Constructor. boundedBuffer(const int sz) { bufferSize = sz; buffer = new T[sz]; pthread_mutex_init(&bufferLock, NULL); pthread_cond_init(&bufferNotEmpty, NULL); pthread_cond_init(&bufferNotFull, NULL); nextToRemove = 0; numElements = 0; } // Destructor. ~boundedBuffer(void) { pthread_mutex_destroy(&bufferLock); pthread_cond_destroy(&bufferNotEmpty); pthread_cond_destroy(&bufferNotFull); } private: // Copy constructor and assignment operator: Make private so // they can't be used (and we don't have to write them). boundedBuffer(const boundedBuffer & bb); boundedBuffer & operator= (const boundedBuffer & bb); public: void put(const T itm) { pthread_mutex_lock(&bufferLock); while (numElements == bufferSize) { pthread_cond_wait(&bufferNotFull, &bufferLock); } unsigned int next = (nextToRemove + numElements) % bufferSize; buffer[next] = itm; numElements++; pthread_cond_broadcast(&bufferNotEmpty); pthread_mutex_unlock(&bufferLock); } T get(void) { pthread_mutex_lock(&bufferLock); while (numElements == 0) { pthread_cond_wait(&bufferNotEmpty, &bufferLock); } T returnVal = buffer[nextToRemove]; nextToRemove = (nextToRemove + 1) % bufferSize; --numElements; pthread_cond_broadcast(&bufferNotFull); pthread_mutex_unlock(&bufferLock); return returnVal; } }; #endif // BOUNDED_BUFFER_H_