#ifndef BOUNDED_BUFFER_H_ #define BOUNDED_BUFFER_H_ #include // has pthread_ routines #include // has sem_ routines // ---- Class for "buffer" (array of type T) of fixed size ----------- // This version of the class is implemented using semaphores. template class boundedBuffer { private: T * buffer; unsigned int bufferSize; pthread_mutex_t bufferLock; sem_t bufferNotEmpty; // will be zero if buffer is empty sem_t bufferNotFull; // will be zero if buffer is full // 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); sem_init(&bufferNotEmpty, 0, 0); sem_init(&bufferNotFull, 0, sz); nextToRemove = 0; numElements = 0; } // Destructor. ~boundedBuffer(void) { pthread_mutex_destroy(&bufferLock); sem_destroy(&bufferNotEmpty); sem_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) { sem_wait(&bufferNotFull); pthread_mutex_lock(&bufferLock); unsigned int next = (nextToRemove + numElements) % bufferSize; buffer[next] = itm; numElements++; pthread_mutex_unlock(&bufferLock); sem_post(&bufferNotEmpty); } T get(void) { sem_wait(&bufferNotEmpty); pthread_mutex_lock(&bufferLock); T returnVal = buffer[nextToRemove]; nextToRemove = (nextToRemove + 1) % bufferSize; --numElements; pthread_mutex_unlock(&bufferLock); sem_post(&bufferNotFull); return returnVal; } }; #endif // BOUNDED_BUFFER_H_