/* ------------------------------------------------------------------------ * TestBoundedBuffer.cpp * ------------------------------------------------------------------------ * Test driver for the BoundedBuffer synchronization classes. * * Copyright 1997-1998 by G. Wade Johnson (Telescan, Inc.) * Use of this code is placed in the public domain as long as the * copyright notice is retained. */ #include #include #include "BoundedBuffer.h" #include "Event.h" const unsigned BufferSize = 5; const unsigned NumConsumers = 8; const unsigned NumProducers = 2; class ProtectedBuffer { unsigned mySize; unsigned myNumItems; long *mypBuffer; BoundedBuffer myProtect; public: ProtectedBuffer( unsigned size ) : mySize(size), myNumItems(0), mypBuffer(0), myProtect(BufferSize) { mypBuffer = new long[size]; for(unsigned i=0;i < mySize;++i) mypBuffer[i] = 0; } ~ProtectedBuffer() { delete mypBuffer; mypBuffer = 0; } void Push( long value ); long Pop(); } ; void ProtectedBuffer::Push( long value ) { BBProducer prot(myProtect); mypBuffer[myNumItems++] = value; } long ProtectedBuffer::Pop() { BBConsumer prot(myProtect); return mypBuffer[--myNumItems]; } ProtectedBuffer Buff(BufferSize); AutoResetEvent LockStep; // Used to reduce startup conflicts DWORD WINAPI ConsumeThread( LPVOID lpvBB ); DWORD WINAPI ProduceThread( LPVOID lpvBB ); int main( void ) { HANDLE Threads[2]; DWORD Dummy; int ThreadNum=0; int i; LockStep.Reset(); Threads[0] = CreateThread( NULL, 0, ConsumeThread, NULL, 0, &Dummy ); LockStep.Wait(); Threads[1] = CreateThread( NULL, 0, ProduceThread, NULL, 0, &Dummy ); LockStep.Wait(); ThreadNum = 2; for(i=0;i < ThreadNum;++i) { WaitForSingleObject( Threads[i], INFINITE ); } Sleep( 5000 ); return 0; } DWORD WINAPI ConsumeThread( LPVOID ) { unsigned i; LockStep.Set(); // Release main thread cout << "First Consume: " << Buff.Pop() << endl; for(i=0;i < BufferSize-1;++i) cout << "Consume: " << Buff.Pop() << endl; Sleep( 5000 ); for(i=0;i < BufferSize;++i) cout << "Consume: " << Buff.Pop() << endl; cout << "Consume: " << Buff.Pop() << endl; return 0L; } DWORD WINAPI ProduceThread( LPVOID ) { unsigned i; long in=0L; LockStep.Set(); // Release main thread Sleep( 2000 ); for(i=0;i < 2*BufferSize;++i) Buff.Push( ++in ); cout << "Last one ..."; Buff.Push( ++in ); cout << "Completed." << endl; return 0L; }