It seems like the real difference between TChan and the Ch code below
is that TChan is, basically, [TVar a] whereas Ch is MVar [a], plus
the order is guaranteed for a TChan.
Now why would it matter so much speed-wise?
This is the CVS code. newTChanIO is exported but undocumented in GHC
6.4.1. I'm not sure what purpose it serves.
-- | 'TChan' is an abstract type representing an unbounded FIFO channel.
data TChan a = TChan (TVar (TVarList a)) (TVar (TVarList a))
type TVarList a = TVar (TList a)
data TList a = TNil | TCons a (TVarList a)
newTChan :: STM (TChan a)
newTChan = do
hole <- newTVar TNil
read <- newTVar hole
write <- newTVar hole
return (TChan read write)
newTChanIO :: IO (TChan a)
newTChanIO = do
hole <- newTVarIO TNil
read <- newTVarIO hole
write <- newTVarIO hole
return (TChan read write)
writeTChan :: TChan a -> a -> STM ()
writeTChan (TChan _read write) a = do
listend <- readTVar write -- listend == TVar pointing to TNil
new_listend <- newTVar TNil
writeTVar listend (TCons a new_listend)
writeTVar write new_listend
readTChan :: TChan a -> STM a
readTChan (TChan read _write) = do
listhead <- readTVar read
head <- readTVar listhead
case head of
TNil -> retry
TCons a tail -> do
writeTVar read tail
return a
On Jan 3, 2006, at 11:25 AM, Chris Kuklewicz wrote:
The latest Ch code is very very short:
{- Ch : fast unordered channel implementation -}
newtype Ch a = Ch (MVar [a], MVar a)
newCh = liftM2 (,) (newMVar []) newEmptyMVar >>= return.Ch
readCh (Ch (w,r)) = takeMVar w >>= \lst ->
case lst of (x:xs) -> putMVar w xs >> return x
[] -> putMVar w [] >> takeMVar r
writeCh (Ch (w,r)) x = do
ok <- tryPutMVar r x -- opportunistic, helps for this problem
unless ok $ takeMVar w >>= \lst -> do
ok <- tryPutMVar r x -- safe inside take/put
putMVar w $ if ok then lst else (x:lst)
It could be used in general purpose code, note the parametric type "a"
in "Ch a". It makes absolutely no guarantees about the order of
values.
That means that the order they are written is unlikely to be the
order
in which they are read. Writes to the channel are non-blocking and
the
"MVar [a]" holds some items waiting to be read (in LIFO order).
--
http://wagerlabs.com/
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe