Proposal: add forkOnIO and friends to Control.Concurrent:

Simon Marlow marlowsd at
Wed Dec 22 12:41:50 CET 2010


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 

{- |
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

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)


More information about the Libraries mailing list