4.80. kink/thread/COUNT_DOWN_LATCH

4.80.1. type count_down_latch

`count_down_latch` is a downward counter which is used to wait until the specified number of operations are performed in multiple threads.

Example:

:MUTEX.require_from('kink/thread/')
:THREAD.require_from('kink/thread/')
:COUNT_DOWN_LATCH.require_from('kink/thread/')

:Mut <- MUTEX.new
:Start_latch <- COUNT_DOWN_LATCH.new(1)
:Done_latch <- COUNT_DOWN_LATCH.new(10)
:Task_nums <- []

10.times.each{(:Num)
  THREAD.spawn{
    Start_latch.wait # wait for the start signal from the main thread
    Mut.with_lock{
      Task_nums.push_back(Num)
    }
    Done_latch.count_down
  }
}

Start_latch.count_down
Done_latch.wait  # wait until all the tasks have finished
stdout.print_line(Task_nums.sort.repr) # => [0 1 2 3 4 5 6 7 8 9]

Concurrency:

• If the count is not zero when `count_down` is called, the invocation of `count_down` happens-before returning from `wait` on the same latch.

• If the count is not zero when `count_down` is called, the invocation of `count_down` happens-before returning from `count` on the same latch the result of which is zero.

4.80.1.1. L.count_down

`count_down` subtract 1 from the count of the latch when it is greater than zero. `count_down` does nothing if the count is already zero.

If the count becomes zero, all the threads blocked by `wait` method of the latch are released.

4.80.1.2. L.wait

`wait` blocks the current thread until the count of the latch becomes zero.

If the count of the latch is already zero when `wait` is called, `wait` returns immediately without blocking the current thread.

4.80.1.3. L.count

`count` returns the count of the latch as an int num.

Result:

• The result is a non-negative int num.

4.80.2. COUNT_DOWN_LATCH.new(Count)

`new` makes a `count_down_latch` val with `Count` as the initial count.

Precondition:

• `Count` must be a non-negative int num.

4.80.3. COUNT_DOWN_LATCH.is?(Val)

`is?` returns whether `Val` is a `count_down_latch` val.