
On Wed, Dec 22, 2010 at 4:55 PM, Duncan Coutts
On 22 December 2010 11:41, Simon Marlow
wrote: Ticket:
http://hackage.haskell.org/trac/ghc/ticket/4859
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'.
While Int is clearly enough for a multi-processors single node system, I wonder if there is something slightly more general that would give us a common API with the Eden / distributed Haskell people. For example in MPI the identification of a node is rather more complex than a single integer. Perhaps some more abstract identifier for a capability would be useful. Closely related of course is how one discovers the available capabilities.
Such a design would probably look something like this: newtype Capability = Capability Int -- abstract getCapabilities :: IO [Capability] -- or should this be: getCapabilities :: IO (Capability, [Capability]) -- to make it clear there's always at least one capability. forkOnIO :: Capability -> IO () -> IO ThreadId forkOnIOWithUnmask :: Capability -> ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId threadIsPinned :: ThreadId -> IO (Maybe Capability) I don't really like the name "Capability". "Processing Unit" is more descriptive but a bit long. Maybe shorten that to "PU". However I'm not sure yet if such a design provides much benefits over the current one. Bas