resource bounded_buffer
   import MPDanimator
   op deposit(int pid, real item ), fetch(int cid) returns real  item
body bounded_buffer(int size )
   real buf[0:size-1]
   int  count = 0, take_out = 0, put_in = 0
   sem elements = 0, spaces = size, mutex = 1
   sem p_mutex = 1, c_mutex = 1

   write("bounded buffer resource with", size, "slots is alive")

   proc deposit(pid, item)  {
      P(spaces)
      P(p_mutex)

# Move the producer to the slot.
      call A_stepjumpto(2000+pid, 7000+put_in, 5, 100)
# Change a full buffer slot's symbol to be solid black.
      call A_fill(put_in, "solid")

      buf[put_in] = item
      put_in = (put_in + 1) % size
      V(p_mutex)

# Move the producer back to its original position.
      call A_stepjumpto(2000+pid, 4000+pid, 5, 100)
# Change producer's symbol to an outline black circle.
      call A_fill(2000+pid, "outline")
      call A_color(2000+pid, "black")

      P(mutex)
      count++
      write("                               count++ =", count)
      V(mutex)
      V(elements)
   }

   proc fetch(cid) returns item  {
      P(elements)
      P(c_mutex)

# Move the consumer to the slot.
      call A_stepjumpto(3000+cid, 7000+take_out, 5, 100)
# Change an empty buffer slot's symbol to an outline black circle.
      call A_fill(take_out, "outline")

      item = buf[take_out]
      take_out = (take_out + 1) % size
      V(c_mutex)

# Move the consumer back to its original position.
      call A_stepjumpto(3000+cid, 5000+cid, 5, 100)
# Change consumers's symbol to an outline black circle.
      call A_fill(3000+cid, "outline")
      call A_color(3000+cid, "black")

      P(mutex)
      count--
      write("                               count-- =", count)
      V(mutex)
      V(spaces)
   }
end bounded_buffer
