module Ki.Internal.ThreadAffinity
  ( ThreadAffinity (..),
    forkWithAffinity,
  )
where

import Control.Concurrent (ThreadId, forkOS)
import Ki.Internal.IO (forkIO, forkOn)

-- | What, if anything, a thread is bound to.
data ThreadAffinity
  = -- | Unbound.
    Unbound
  | -- | Bound to a capability.
    Capability Int
  | -- | Bound to an OS thread.
    OsThread
  deriving stock (ThreadAffinity -> ThreadAffinity -> Bool
(ThreadAffinity -> ThreadAffinity -> Bool)
-> (ThreadAffinity -> ThreadAffinity -> Bool) -> Eq ThreadAffinity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ThreadAffinity -> ThreadAffinity -> Bool
== :: ThreadAffinity -> ThreadAffinity -> Bool
$c/= :: ThreadAffinity -> ThreadAffinity -> Bool
/= :: ThreadAffinity -> ThreadAffinity -> Bool
Eq, Int -> ThreadAffinity -> ShowS
[ThreadAffinity] -> ShowS
ThreadAffinity -> String
(Int -> ThreadAffinity -> ShowS)
-> (ThreadAffinity -> String)
-> ([ThreadAffinity] -> ShowS)
-> Show ThreadAffinity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ThreadAffinity -> ShowS
showsPrec :: Int -> ThreadAffinity -> ShowS
$cshow :: ThreadAffinity -> String
show :: ThreadAffinity -> String
$cshowList :: [ThreadAffinity] -> ShowS
showList :: [ThreadAffinity] -> ShowS
Show)

-- forkIO/forkOn/forkOS, switching on affinity
forkWithAffinity :: ThreadAffinity -> IO () -> IO ThreadId
forkWithAffinity :: ThreadAffinity -> IO () -> IO ThreadId
forkWithAffinity = \case
  ThreadAffinity
Unbound -> IO () -> IO ThreadId
forkIO
  Capability Int
n -> Int -> IO () -> IO ThreadId
forkOn Int
n
  ThreadAffinity
OsThread -> IO () -> IO ThreadId
forkOS