summaryrefslogtreecommitdiff
path: root/libraries/base/Control/Concurrent/QSem.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/base/Control/Concurrent/QSem.hs')
-rw-r--r--libraries/base/Control/Concurrent/QSem.hs90
1 files changed, 0 insertions, 90 deletions
diff --git a/libraries/base/Control/Concurrent/QSem.hs b/libraries/base/Control/Concurrent/QSem.hs
deleted file mode 100644
index 2fd2ad6ba7..0000000000
--- a/libraries/base/Control/Concurrent/QSem.hs
+++ /dev/null
@@ -1,90 +0,0 @@
-{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE CPP #-}
-#ifdef __GLASGOW_HASKELL__
-{-# LANGUAGE DeriveDataTypeable, StandaloneDeriving #-}
-#endif
-
------------------------------------------------------------------------------
--- |
--- Module : Control.Concurrent.QSem
--- Copyright : (c) The University of Glasgow 2001
--- License : BSD-style (see the file libraries/base/LICENSE)
---
--- Maintainer : libraries@haskell.org
--- Stability : experimental
--- Portability : non-portable (concurrency)
---
--- Simple quantity semaphores.
---
------------------------------------------------------------------------------
-
-module Control.Concurrent.QSem
- {-# DEPRECATED "Control.Concurrent.QSem will be removed in GHC 7.8. Please use an alternative, e.g. the SafeSemaphore package, instead." #-}
- ( -- * Simple Quantity Semaphores
- QSem, -- abstract
- newQSem, -- :: Int -> IO QSem
- waitQSem, -- :: QSem -> IO ()
- signalQSem -- :: QSem -> IO ()
- ) where
-
-import Prelude
-import Control.Concurrent.MVar
-import Control.Exception ( mask_ )
-import Data.Typeable
-
-#include "Typeable.h"
-
--- General semaphores are also implemented readily in terms of shared
--- @MVar@s, only have to catch the case when the semaphore is tried
--- waited on when it is empty (==0). Implement this in the same way as
--- shared variables are implemented - maintaining a list of @MVar@s
--- representing threads currently waiting. The counter is a shared
--- variable, ensuring the mutual exclusion on its access.
-
--- |A 'QSem' is a simple quantity semaphore, in which the available
--- \"quantity\" is always dealt with in units of one.
-newtype QSem = QSem (MVar (Int, [MVar ()])) deriving Eq
-
-INSTANCE_TYPEABLE0(QSem,qSemTc,"QSem")
-
--- |Build a new 'QSem' with a supplied initial quantity.
--- The initial quantity must be at least 0.
-newQSem :: Int -> IO QSem
-newQSem initial =
- if initial < 0
- then fail "newQSem: Initial quantity must be non-negative"
- else do sem <- newMVar (initial, [])
- return (QSem sem)
-
--- |Wait for a unit to become available
-waitQSem :: QSem -> IO ()
-waitQSem (QSem sem) = mask_ $ do
- (avail,blocked) <- takeMVar sem -- gain ex. access
- if avail > 0 then
- let avail' = avail-1
- in avail' `seq` putMVar sem (avail',[])
- else do
- b <- newEmptyMVar
- {-
- Stuff the reader at the back of the queue,
- so as to preserve waiting order. A signalling
- process then only have to pick the MVar at the
- front of the blocked list.
-
- The version of waitQSem given in the paper could
- lead to starvation.
- -}
- putMVar sem (0, blocked++[b])
- takeMVar b
-
--- |Signal that a unit of the 'QSem' is available
-signalQSem :: QSem -> IO ()
-signalQSem (QSem sem) = mask_ $ do
- (avail,blocked) <- takeMVar sem
- case blocked of
- [] -> let avail' = avail+1
- in avail' `seq` putMVar sem (avail',blocked)
-
- (b:blocked') -> do
- putMVar sem (0,blocked')
- putMVar b ()