Conveyors

A conveyor is a long belt on which items are placed at the starting point of the conveyor. The items leave the conveyor at the end point, after traveling a certain period of time on the conveyor. The number of items traveling on the conveyor varies, while each item stays the same amount of time on the conveyor. It works like a buffer that provides output based on item arrival time instead of based on demand from the next process.

Timers

To model a conveyor, you have to wait until a particular point in time. The Chi language has timers to signal such a time-out. The timer is started by assigning it a value. From that moment, it automatically decrements when time progresses in the model, until it reaches zero. The function ready gives the boolean value true if the timer is ready. The amount of time left can be obtained by reading from the variable. An example:

proc P():
    timer t;

    delay 10.0;
    t = timer(5.0); # Get a time-out at time = 15.0
    for i in range(7):
        write("%f %f %b\n", time, real(t), ready(t));
        delay 1.0
    end
end

model M():
    run P()
end

Initially, time equals 0.0. The first action of process P is to delay the time for 10.0 time units. Now the value of time equals 10.0. Nothing happens to timer t as it was already zero. At time 10 timer t is started with the value 5.0. The output of the program is:

10.0   5.0    false
11.0   4.0    false
12.0   3.0    false
13.0   2.0    false
14.0   1.0    false
15.0   0.0    true
16.0   0.0    true

Timer t decrements as time progresses, and it is ready at 10.0 + 5.0 units. A process can have more timers active at the same moment.

A conveyor

A conveyor is schematically depicted in the following figure:

conveyor 3items

Three items are placed on the conveyor. For simplicity, assume the conveyor is 60.0 meter long and has a speed of 1 meter per second. An item thus stays on the conveyor for 60.0 seconds.

Item 0 has been placed on the conveyor 50.0 seconds ago, and will leave the conveyor 10.0 second from now. In the same way, item 1 will leave 30.0 seconds from now, and 2 leaves after 45.0 seconds. Each item has a yellow sticker with the time that the item leaves the conveyor. Based on this idea, tuple type conv_item has been defined, consisting of a field item, denoting the received item, and a timer field t, with the remaining time until the item leaves the conveyor:

type conv_item = tuple(item x; timer t);

proc T(chan? item a; chan! item b; real convey_time):
    list conv_item xst; item x;

    while true:
        select
            a?x:
                xst = xst + [(x, timer(convey_time))]
        alt
            not empty(xst) and ready(xst[0].t), b!xst[0].x:
                xst = xst[1:]
        end
    end
end

The conveyor always accepts new items from channel a, and adds the item with the yellow sticker to the list. If the conveyor is not empty, and the timer has expired for the first item in the list, it is sent (without sticker) to the next process. The conveyor sends items to a process that is always willing to a receive an item, this implies that the conveyor is never blocked. Blocking implies that the items nevertheless are transported to the end of the conveyor.

A priority conveyor

In this example, items are placed on a conveyor, where the time of an item on the conveyor varies between items. Items arriving at the conveyor process, get inserted in the list with waiting items, in ascending order of their remaining time on the conveyor. The field tt in the item denotes the traveling time of the item on the conveyor:

type item      = tuple(...; real tt; ...),
     conv_item = tuple(item x; timer t);

The predicate function pred is defined by:

func bool pred(conv_item x, y):
    return real(x.t) <= real(y.t)
end

The conveyor process becomes:

proc T(chan? item a; chan! item b):
    list conv_item xst; item x;

    while true:
        select
            a?x:
                xst = insert(xst, (x, timer(x.tt)), pred)
        alt
            not empty(xst) and ready(xst[0].t), b!xst[0].item:
                xst = xst[1:]
        end
    end
end

The conveyor process works like before, except the new item is inserted in the list according to its remaining time, instead of at the rear of the list.

Exercises

  1. Model the system as shown in the figure below, where T is a conveyor process with a capacity of at most three products and exponentially distributed conveying times with an average of 4.0.

    Compute the average flow time of products in the system.

    conveyor system
  2. Model the system as shown in the figure below, with exponentially distributed server processing times with an average of 4.0.

    three parallel servers
    1. Compute the average flow time of products in the system.

    2. Are there differences in behavior between both systems? Why (not)?