Export the affinity API from Control.Concurrent: forkOn and friends.
authorSimon Marlow <marlowsd@gmail.com>
Wed, 30 Mar 2011 10:05:04 +0000 (10:05 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Wed, 30 Mar 2011 10:05:04 +0000 (10:05 +0000)
forkOn             :: Int -> IO () -> IO ThreadId
forkOnWithUnmask   :: Int -> ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId
getNumCapabilities :: IO Int
threadCapability   :: ThreadId -> IO (Int, Bool)

Following discussion on the libraries list, I renamed forkOnIO to
forkOn.  In due course we might want to also rename forkIO to fork.

I left the Int argument as it is, it's quite useful to be able to
specify a number to be interpreted modulo the actual number of
processors.

I also used the term "capability" consistently.  It might not be the
best choice, but we have to pick something.

Control/Concurrent.hs
GHC/Conc.lhs
GHC/Conc/Sync.lhs

index 732255b..62a30b4 100644 (file)
@@ -40,6 +40,12 @@ module Control.Concurrent (
         throwTo,
 #endif
 
         throwTo,
 #endif
 
+        -- ** Threads with affinity
+        forkOn,
+        forkOnWithUnmask,
+        getNumCapabilities,
+        threadCapability,
+
         -- * Scheduling
 
         -- $conc_scheduling     
         -- * Scheduling
 
         -- $conc_scheduling     
index 11a9324..de96b2c 100644 (file)
@@ -32,9 +32,10 @@ module GHC.Conc
         , forkIO        -- :: IO a -> IO ThreadId
         , forkIOUnmasked
         , forkIOWithUnmask
         , forkIO        -- :: IO a -> IO ThreadId
         , forkIOUnmasked
         , forkIOWithUnmask
+        , forkOn
         , forkOnIO      -- :: Int -> IO a -> IO ThreadId
         , forkOnIOUnmasked
         , forkOnIO      -- :: Int -> IO a -> IO ThreadId
         , forkOnIOUnmasked
-        , forkOnIOWithUnmask
+        , forkOnWithUnmask
         , numCapabilities -- :: Int
         , getNumCapabilities -- :: IO Int
         , numSparks       -- :: IO Int
         , numCapabilities -- :: Int
         , getNumCapabilities -- :: IO Int
         , numSparks       -- :: IO Int
index 027744b..af69a63 100644 (file)
@@ -41,9 +41,10 @@ module GHC.Conc.Sync
         , forkIO        -- :: IO a -> IO ThreadId
         , forkIOUnmasked
         , forkIOWithUnmask
         , forkIO        -- :: IO a -> IO ThreadId
         , forkIOUnmasked
         , forkIOWithUnmask
-        , forkOnIO      -- :: Int -> IO a -> IO ThreadId
+        , forkOn      -- :: Int -> IO a -> IO ThreadId
+        , forkOnIO    -- DEPRECATED
         , forkOnIOUnmasked
         , forkOnIOUnmasked
-        , forkOnIOWithUnmask
+        , forkOnWithUnmask
         , numCapabilities -- :: Int
         , getNumCapabilities -- :: IO Int
         , numSparks      -- :: IO Int
         , numCapabilities -- :: Int
         , getNumCapabilities -- :: IO Int
         , numSparks      -- :: IO Int
@@ -222,35 +223,50 @@ forkIOWithUnmask :: ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId
 forkIOWithUnmask io = forkIO (io unsafeUnmask)
 
 {- |
 forkIOWithUnmask io = forkIO (io unsafeUnmask)
 
 {- |
-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'.
+Like 'forkIO', but lets you specify on which processor the thread
+should run.  Unlike a `forkIO` thread, a thread created by `forkOn`
+will stay on the same processor for its entire lifetime (`forkIO`
+threads can migrate between processors according to the scheduling
+policy).  `forkOn` is useful for overriding the scheduling policy when
+you know in advance how best to distribute the threads.
+
+The `Int` argument specifies a /capability number/ (see
+'getNumCapabilities').  Typically capabilities correspond to physical
+processors, but the exact behaviour is implementation-dependent.  The
+value passed to 'forkOn' is interpreted modulo the total number of
+capabilities as returned by 'getNumCapabilities'.
+
+GHC note: the number of capabilities is specified by the @+RTS -N@
+option when the program is started.  Capabilities can be fixed to
+actual processor cores with @+RTS -qa@ if the underlying operating
+system supports that, although in practice this is usually unnecessary
+(and may actually degrade perforamnce in some cases - experimentation
+is recommended).
 -}
 -}
-forkOnIO :: Int -> IO () -> IO ThreadId
-forkOnIO (I# cpu) action = IO $ \ s ->
+forkOn :: Int -> IO () -> IO ThreadId
+forkOn (I# cpu) action = IO $ \ s ->
    case (forkOn# cpu action_plus s) of (# s1, tid #) -> (# s1, ThreadId tid #)
  where
   action_plus = catchException action childHandler
 
    case (forkOn# cpu action_plus s) of (# s1, tid #) -> (# s1, ThreadId tid #)
  where
   action_plus = catchException action childHandler
 
-{-# DEPRECATED forkOnIOUnmasked "use forkOnIOWithUnmask instead" #-}
--- | This function is deprecated; use 'forkOnIOWIthUnmask' instead
+{-# DEPRECATED forkOnIO "renamed to forkOn" #-}
+-- | This function is deprecated; use 'forkOn' instead
+forkOnIO :: Int -> IO () -> IO ThreadId
+forkOnIO = forkOn
+
+{-# DEPRECATED forkOnIOUnmasked "use forkOnWithUnmask instead" #-}
+-- | This function is deprecated; use 'forkOnWIthUnmask' instead
 forkOnIOUnmasked :: Int -> IO () -> IO ThreadId
 forkOnIOUnmasked :: Int -> IO () -> IO ThreadId
-forkOnIOUnmasked cpu io = forkOnIO cpu (unsafeUnmask io)
+forkOnIOUnmasked cpu io = forkOn cpu (unsafeUnmask io)
 
 -- | Like 'forkIOWithUnmask', but the child thread is pinned to the
 
 -- | 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
-forkOnIOWithUnmask cpu io = forkOnIO cpu (io unsafeUnmask)
+-- given CPU, as with 'forkOn'.
+forkOnWithUnmask :: Int -> ((forall a . IO a -> IO a) -> IO ()) -> IO ThreadId
+forkOnWithUnmask cpu io = forkOn cpu (io unsafeUnmask)
 
 -- | the value passed to the @+RTS -N@ flag.  This is the number of
 -- Haskell threads that can run truly simultaneously at any given
 
 -- | the value passed to the @+RTS -N@ flag.  This is the number of
 -- Haskell threads that can run truly simultaneously at any given
--- time, and is typically set to the number of physical CPU cores on
+-- time, and is typically set to the number of physical processor cores on
 -- the machine.
 -- 
 -- Strictly speaking it is better to use 'getNumCapabilities', because
 -- the machine.
 -- 
 -- Strictly speaking it is better to use 'getNumCapabilities', because
@@ -262,12 +278,12 @@ numCapabilities = unsafePerformIO $ getNumCapabilities
 {- |
 Returns the number of Haskell threads that can run truly
 simultaneously (on separate physical processors) at any given time.
 {- |
 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
+The number passed to `forkOn` 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
 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
+the machine, and 'forkOn' 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.
 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.
@@ -470,7 +486,7 @@ threadStatus (ThreadId t) = IO $ \s ->
 -- | returns the number of the capability on which the thread is currently
 -- running, and a boolean indicating whether the thread is locked to
 -- that capability or not.  A thread is locked to a capability if it
 -- | returns the number of the capability on which the thread is currently
 -- running, and a boolean indicating whether the thread is locked to
 -- that capability or not.  A thread is locked to a capability if it
--- was created with @forkOnIO@.
+-- was created with @forkOn@.
 threadCapability :: ThreadId -> IO (Int, Bool)
 threadCapability (ThreadId t) = IO $ \s ->
    case threadStatus# t s of
 threadCapability :: ThreadId -> IO (Int, Bool)
 threadCapability (ThreadId t) = IO $ \s ->
    case threadStatus# t s of