Download pseudo source code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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 consumed_count := 0
    shared can_access_consumed_count := create_mutex()

    shared can_consume := create_semaphore(0)

    declare producers := create_threads(producer_count, produce0)
    declare consumers := create_threads(consumer_count, consume_busywait)

    join_threads(producers)
    join_threads(consumers)
  end if
end procedure

procedure produce0:
  declare my_unit := 0
  lock(can_access_next_unit)
    declare is_there_pending_work := next_unit < unit_count
    if is_there_pending_work then
      next_unit := next_unit + 1
      my_unit := next_unit
    end if
  unlock(can_access_next_unit)

  while is_there_pending_work do
    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)

    lock(can_access_next_unit)
      is_there_pending_work := next_unit < unit_count
      if is_there_pending_work then
        next_unit := next_unit + 1
        my_unit := next_unit
      end if
    unlock(can_access_next_unit)
  end while
end procedure

procedure consume_busywait:
  while true do
    lock(can_access_consumed_count)
      if consumed_count < unit_count then
        consumed_count := consumed_count + 1
      else
        break while
      end if
    unlock(can_access_consumed_count)

    lock(can_access_queue)
      if is_empty(queue) then
        lock(can_access_consumed_count)
          consumed_count := consumed_count - 1
        unlock(can_access_consumed_count)
      else
        declare my_unit := dequeue(queue)
        print("\tConsuming ", my_unit)
        delay(random_between(consumer_min_delay, consumer_max_delay))
      end if
    unlock(can_access_queue)
  end while
end procedure

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