mutex_lock(m, @optional timeout = false, t = self())
Lock the mutex m. Return a boolean value.
If m is currently locked, the current task waits until
m is unlocked, or until timeout is reached (if timeout is supplied).
If timeout is reached, mutex_lock returns false. Otherwise, the state of
m is changed as follows:
if t is false, m becomes locked/not-owned,
otherwise, if t is a task and it is terminated m becomes unlocked/abandoned,
otherwise m becomes locked/owned with t as the owner.
After changing the state of m, an abandoned-mutex-exception object
is raised if m was unlocked/abandoned before the state change,
otherwise mutex_lock returns true. It is not an error if m is owned
by the current task (but the current task will have to wait).
If provided, timeout should be an exact or inexact real number representing a relative time in seconds from the moment
mutex_lock was called.
// updating shared state without a data race:
let x = 0
let mx = mutex()
function incx()
{ mutex_lock(mx)
x = inc(x)
mutex_unlock(mx) }
!incx()
!incx()
x
// 2