uni-util-2.3.0.1: Utilities for the uniform workbench

Safe HaskellNone

Util.VSem

Description

| Implements locks which can be locked globally or locally. A global lock prevents any other lock; a local lock allows other local locks.

There are some subtle decisions to be made about when to give preference to local, and when to global, locks. There are two important cases: (1) When we free a global lock, and there is another queued global lock, we take that global lock (or the earliest for which someone is waiting, if there's a choice), irrespective of whether anyone is waiting for a local lock. (2) When at least one local lock is held, we allow people to acquire further local locks, even if there are queued global locks.

A bad consequence of (2) is that a global lock can be indefinitely not satisfied by a carefully-timed sequence of finite local locks:

local locks : --- --- --- --- . . . --- --- --- . . . no global lock can be acquired at all.

However the alternative, of not permitting any fresh local locks when a global lock is queued, is worse (in my opinion), since if a thread attempts to acquire two local locks, one inside the other, and another attempts to acquire a global lock, the whole thing can deadlock.

Thread 1 : acquire local lock attempt to acquire second local lock => DEADLOCK. Thread 2 : wait for global lock

We could deal with this partially by allowing local locks for free to a thread which already holds one, but this is more complicated and I suspect theoretically dodgy.

A consequence of this decision is that threads should avoid creating automated repeated sequences of local locks on the same VSem.

Synopsis

Documentation

data VSem Source

A lock which can be globally or locally locked. At any time, a VSem is either globally locked once, or locally locked zero or more times. Global locks always take priority over local locks.

newVSem :: IO VSemSource

Creates a VSem.

synchronizeLocal :: VSem -> IO b -> IO bSource

Perform an action while locking a VSem locally.

synchronizeGlobal :: VSem -> IO b -> IO bSource

Perform an action while locking a VSem globally.

acquireLocal :: VSem -> IO ()Source

Acquire a local lock on a VSem

releaseLocal :: VSem -> IO ()Source

Release a local lock on a VSem