Proposal: add forkOnIO and friends to Control.Concurrent:

Thomas Schilling nominolo at
Fri Dec 24 02:57:27 CET 2010

I agree with that a more descriptive type than Int would be better
(even if it's just a newtype).

I also find the name 'forkOnIO' extremely confusing.  Without reading
the docs it seems to imply that a thread is created on IO, i.e., if
I/O happens.  This makes no sense, and is of course not what's
happening.  However, I assume you chose it because forkIOOn looks a
bit weird.  In that case, why not use forkThreadOn, and in a separate
proposal change forkIO to forkThread (or just fork).

Other than that, I agree that the implementation seems likely portable
(and can easily be made to work in single-threaded systems).

On 22 December 2010 11:41, Simon Marlow <marlowsd at> wrote:
> Ticket:
> I think these functions are implementation-independent enough to add to the
> main `Control.Concurrent` API:
> {{{
> {- |
> Like 'forkIO', but lets you specify on which CPU the thread is
> created.  Unlike a `forkIO` thread, a thread created by `forkOnIO`
> will stay on the same CPU for its entire lifetime (`forkIO` threads
> can migrate between CPUs according to the scheduling policy).
> `forkOnIO` is useful for overriding the scheduling policy when you
> know in advance how best to distribute the threads.
> The `Int` argument specifies the CPU number; it is interpreted modulo
> the value returned by 'getNumCapabilities'.
> -}
> forkOnIO :: Int -> IO () -> IO ThreadId
> -- | Like 'forkIOWithUnmask', but the child thread is pinned to the
> -- given CPU, as with 'forkOnIO'.
> forkOnIOWithUnmask :: Int -> ((forall a . IO a -> IO a) -> IO ()) -> IO
> ThreadId
> {- |
> Returns the number of Haskell threads that can run truly
> simultaneously (on separate physical processors) at any given time.
> The CPU number passed to `forkOnIO` is interpreted modulo this
> value.
> An implementation in which Haskell threads are mapped directly to
> OS threads might return the number of physical processor cores in
> the machine, and 'forkOnIO' would be implemented using the OS's
> affinity facilities.  An implementation that schedules Haskell
> threads onto a smaller number of OS threads (like GHC) would return
> the number of such OS threads that can be running simultaneously.
> GHC notes: this returns the number passed as the argument to the
> @+RTS -N@ flag.  In current implementations, the value is fixed
> when the program starts and never changes, but it is possible that
> in the future the number of capabilities might vary at runtime.
> -}
> getNumCapabilities :: IO Int
> -- | returns @Just x@ if the given thread was created with either
> -- @forkOnIO x@ or @forkOnIOWithUnmask@, or @Nothing@ otherwise.
> threadIsPinned :: ThreadId -> IO (Maybe Int)
> }}}
> In base (GHC 7.0.1) we currently have `forkOnIO` and
> `forkOnIOUnmasked`, available from `GHC.Conc`.  I am about to add the other
> functions to `GHC.Conc`, and deprecate `forkOnIOUnmasked` (see
>  This proposal is to
> export the above functions from`Control.Concurrent` too.
> A feature request for `threadIsPinned` was submitted as
> Naming is up for grabs: I'm not at all sure that "capabilities" is a good
> word here, but I can't think of any better ideas.  "processors" or "CPUs"
> don't seem quite right.
> Discussion period: 4 weeks (until 19 Jan 2011)
> Cheers,
>        Simon
> _______________________________________________
> Libraries mailing list
> Libraries at

Push the envelope. Watch it bend.

More information about the Libraries mailing list