# Lock Words A lock enforces mutual exclusion, typically with regard to control of a resource, between multiple tasks. It also serves as a queue for multiple tasks waiting on the lock which is held by another task. Furthermore, it provides a mechanism to avoid priority inversion, by temporarily elevating each task holding a lock's priority to the maximum priority of all the tasks waiting for it; this applies even when chaining together multiple locks held by tasks holding some locks and waiting on others. Recursive lockings are permitted, with a recursive locking count being maintained by a given lock, which is finally released when all the lockings are matched by releases. ### `lock` The following words are in `lock`: ##### `x-not-currently-owned` ( -- ) Exception raised if a task attempts to unlock a lock it is not the holder of. ##### `lock-size` ( -- bytes ) Get the size of a lock in bytes. ##### `init-lock` ( addr -- ) Initialize a lock starting at the specified address *addr*; note that it must be `lock-size` bytes in size. ##### `claim-lock` ( lock -- ) Attempt to acquire a lock *lock*; if the lock is already held, put the current task in a queue and disable it. In that case, update the priority of the holder of a lock, and any subsequent holders of any locks waited for by the holder of this lock, in order to avoid priority inversion. Note that this must not be called within a critical section. Any number of lockings by the same task are permitted; the lock will be freed when they are balanced by an equal number of releasings. ##### `release-lock` ( lock -- ) Attempt to release a lock *lock* if it is not recursively locked; if the current task is not the holder of the lock, raise `x-not-currently-owned`. If releasing the lock is successful, restore the priority of the current task to what it would be had its priority not been updated in order to avoid priority inversion; afterwards, carry out all the functionality that `lock` would carry out had it been called by the task at the head of the queue if there is one. If a lock *lock* is recursively locked, decrement the recursive lock count by one. Note that this must not be called within a critical section. ##### `with-lock` ( xt lock -- ) Execute an xt with a given lock *lock* locked while it executes, unlocking it afterwards. If an exception is raised by *xt*, unlock *lock* and then re-raise the exception.