val create : int ‑> tcreate n creates a semaphore with initial value n.
n <= 0.val acquire : int ‑> t ‑> unitacquire n s blocks until get s >= n, then atomically
sets s := !s - n.
val with_acquire : n:int ‑> t ‑> f:(unit ‑> 'a) ‑> 'awith_acquire ~n s ~f first acquires s with n units,
calls f (), and then releases s with n units.
Safely release the semaphore even if f () fails.
val wait_until_at_least : n:int ‑> t ‑> f:(unit ‑> 'a) ‑> 'await_until_at_least ~n s ~f waits until get s >= n, then calls f ()
and returns its result. Doesn't modify the semaphore.