Counting semaphores

Counting semaphores are used to ensure that no more than a fixed number of threads are executing in a critical section at a time; as such, they generalize concurrency.locks, since locks can be thought of as semaphores with an initial count of 1.
Semaphore examples

Creating semaphores:

<semaphore> ( n -- semaphore )

Unlike locks, where acquisition and release are always paired by a combinator, semaphores expose these operations directly and there is no requirement that they be performed in the same thread:
acquire ( semaphore -- )

acquire-timeout ( semaphore timeout -- )

release ( semaphore -- )

Combinators which pair acquisition and release:
with-semaphore ( semaphore quot -- )

with-semaphore-timeout ( semaphore timeout quot -- )