// boundedbuf.cc // This is a simple bounded buffer of ints intended to be used as a // communication channel between threads. See boundedbuf.h for more // info. Some of the procedures have been left for you to implement. // -Max Hailperin 9/23/96 #include "boundedbuf.h" BBuf::BBuf(){ count = 0; // no data nextRead = nextWrite = 0; // start at buf[0] shut = 0; // not shutdown yet lock = new Lock("monitor lock for bounded buffer"); data = new Condition("condition variable for data availability in BBuf"); space = new Condition("condition variable for space availability in BBuf"); } //---------------------------------------------------------------------- //put // This puts a single int into the buffer, which must not have been // shutdown yet. This may involve sleeping until there is space, and // may involve waking up a consumer who was sleeping awaiting data. //---------------------------------------------------------------------- void BBuf::put(int n){ lock->Acquire(); ASSERT(!shut); while(count == size){ space->Wait(lock); } if(count++ == 0) data->Signal(lock); buf[nextWrite++] = n; if(nextWrite == size){ nextWrite = 0; // wrap around } lock->Release(); } //---------------------------------------------------------------------- //shutdown // This "shuts down" the buffer, which must not have been shutdown // yet. This should wake up *all* consumers who were sleeping awaiting // data, since unlike a data value put with put, there is no problem with // them all discovering that no more data is coming (and you don't want // them to sleep forever). You need to write this procedure. //---------------------------------------------------------------------- void BBuf::shutdown(){ } //---------------------------------------------------------------------- //get // This gets a single int from the buffer, unless it has been shutdown // and there is no buffered data remaining. (Note that even if the // buffer was shutdown, if there is data it should be returned -- we // "drain" all the buffered data out.) If a value is gotten, it will // be stored into the reference argument, n, and 1 returned. If none is // gotten, because the buffer is empty and shutdown, then 0 will be returned // (and n is unchanged). If there is no buffered data, but the buffer // isn't shut down yet, then get must sleep until there is data or the // buffer has been shutdown. Once a value is gotten, it may be necessary // to wake up a sleeping producer that was waiting for space. This is // another procedure you need to write. //---------------------------------------------------------------------- int BBuf::get(int& n){ }