@@ -109,13 +109,19 @@ instance MonadAsync m => Applicative (AsyncT m) where
109109 pure = return
110110 (<*>) = ap
111111
112−-- The current model is to start a new thread for every task. The input is
113−-- provided at the time of the creation and therefore no synchronization is
114−-- needed compared to a pool of threads contending to get the input from a
115−-- channel. However the thread creation overhead may be more than the
116−-- synchronization cost?
112+------------------------------------------------------------------------------
113+-- Alternative
114+------------------------------------------------------------------------------
115+
116+-- Thread pool vs transient threads
117117--
118−-- When the task is over the outputs need to be collected and that requires
118+-- The current model is to start a new thread for every task. The computation
119+-- input is provided at the time of the creation and therefore no
120+-- synchronization is needed compared to a pool of threads contending to get
121+-- the input from a channel. However the thread creation overhead may be more
122+-- than the synchronization cost needed in the case of pool?
123+--
124+-- When the task is over, the outputs need to be collected and that requires
119125-- synchronization irrespective of a thread pool model or per task new thread
120126-- model.
121127--
@@ -123,35 +129,6 @@ instance MonadAsync m => Applicative (AsyncT m) where
123129-- threads and send them work via a shared channel. When there is no more work
124130-- available we need a way to close the channel and wakeup all waiters so that
125131-- they can go away rather than waiting indefinitely.
126−--
127−
128−-- Only those actions that are marked with 'async' are guaranteed to be
129−-- asynchronous. Asyncly is free to run other actions synchronously or
130−-- asynchronously and it should not matter to the semantics of the program, if
131−-- it does then use async to force.
132−--
133−-- Why not make async as default and ask the programmer to use a 'sync'
134−-- primitive to force an action to run synchronously? But then we would not
135−-- have the freedom to convert the async actions to sync dynamically. Note that
136−-- it is safe to convert a sync action to async but vice-versa is not true.
137−-- Converting an async to sync can cause change in semantics if the async
138−-- action was an infinite loop for example.
139−--
140−-- | In an 'Alternative' composition, force the action to run asynchronously.
141−-- The @\<|\>@ operator implies "can be parallel", whereas 'async' implies
142−-- "must be parallel". Note that outside an 'Alternative' composition 'async'
143−-- is not useful and should not be used. Even in an 'Alternative' composition
144−-- 'async' is not useful as the last action as the last action always runs in
145−-- the current thread.
146−async :: MonadAsync m => AsyncT m a -> AsyncT m a
147−async action = AsyncT $ runAsyncTask True (runAsyncT action)
148−
149−makeAsync :: MonadAsync m => ((a -> m ()) -> m ()) -> AsyncT m a
150−makeAsync = AsyncT . makeCont
151−
152−------------------------------------------------------------------------------
153−-- Alternative
154−------------------------------------------------------------------------------
155132
156133instance MonadAsync m => Alternative (AsyncT m) where
157134 {-# SPECIALIZE instance Alternative (AsyncT IO) #-}
@@ -278,6 +255,34 @@ infixr 1 >>|
278255(>>|) :: MonadAsync m => AsyncT m a -> AsyncT m b -> AsyncT m a
279256(>>|) = afterfirst
280257
258+------------------------------------------------------------------------------
259+-- Async primitives
260+------------------------------------------------------------------------------
261+--
262+-- Only those actions that are marked with 'async' are guaranteed to be
263+-- asynchronous. Asyncly is free to run other actions synchronously or
264+-- asynchronously and it should not matter to the semantics of the program, if
265+-- it does then use async to force.
266+--
267+-- Why not make async as default and ask the programmer to use a 'sync'
268+-- primitive to force an action to run synchronously? But then we would not
269+-- have the freedom to convert the async actions to sync dynamically. Note that
270+-- it is safe to convert a sync action to async but vice-versa is not true.
271+-- Converting an async to sync can cause change in semantics if the async
272+-- action was an infinite loop for example.
273+--
274+-- | In an 'Alternative' composition, force the action to run asynchronously.
275+-- The @\<|\>@ operator implies "can be parallel", whereas 'async' implies
276+-- "must be parallel". Note that outside an 'Alternative' composition 'async'
277+-- is not useful and should not be used. Even in an 'Alternative' composition
278+-- 'async' is not useful as the last action as the last action always runs in
279+-- the current thread.
280+async :: MonadAsync m => AsyncT m a -> AsyncT m a
281+async action = AsyncT $ runAsyncTask True (runAsyncT action)
282+
283+makeAsync :: MonadAsync m => ((a -> m ()) -> m ()) -> AsyncT m a
284+makeAsync = AsyncT . makeCont
285+
281286------------------------------------------------------------------------------
282287-- Controlling thread quota
283288------------------------------------------------------------------------------