Download pseudo source code

procedure main(argc, argv[]):
  if argc = 8 then
    shared unit_count := integer(argv[1])
    shared producer_count := integer(argv[2])
    shared consumer_count := integer(argv[3])
    shared producer_min_delay := integer(argv[4])
    shared producer_max_delay := integer(argv[5])
    shared consumer_min_delay := integer(argv[6])
    shared consumer_max_delay := integer(argv[7])

    shared queue := create_integer_queue()
    shared can_access_queue := create_mutex()

    shared next_unit := 0
    shared can_access_next_unit := create_mutex()

    shared can_consume := create_semaphore(0)

    declare producers := create_threads(producer_count, produce1)
    declare consumers := create_threads(consumer_count, consume)

    join_threads(producers)

    for index := 0 to consumer_count do
      signal(can_consume)
    end for

    join_threads(consumers)
  end if
end procedure

procedure produce1:
  while true do
    declare my_unit := 0
    lock(can_access_next_unit)
      if next_unit < unit_count then
        next_unit := next_unit + 1
        my_unit := next_unit
      else
        unlock(can_access_next_unit)
        break while
      end if
    unlock(can_access_next_unit)
  
    delay(random_between(producer_min_delay, producer_max_delay))
    lock(can_access_queue)
      enqueue(queue, my_unit)
    unlock(can_access_queue)
    print("Produced ", my_unit)
    signal(can_consume)
  end while
end procedure

procedure consume2:
  while true do
    wait(can_consume)
    lock(can_access_queue)
      if is_empty(queue) then
        break while
      end if
    declare my_unit := dequeue(queue)
    unlock(can_access_queue)
    print("\tConsuming ", my_unit)
    delay(random_between(consumer_min_delay, consumer_max_delay))
  end while
  unlock(can_access_queue)
end procedure

function random_between(min, max):
  return min + rand() % (max - min)
end function