Bound Threads

Simon Marlow simonmar at
Fri Mar 14 06:16:02 EST 2003

> I have just spend some time reading through all the 
> discussions and the
> new "threads" document and I would like to propose the 
> addition of a new library function.
> > forkOS :: IO () -> IO ThreadID
> The function "forkOS" forks a new Haskell thread that runs in 
> a new OS (or
> native) thread. With this, I also propose that "forkIO" 
> always runs a Haskell thread in the same OS thread that the 
> current Haskell thread runs in.
> (i.e. "forkIO": same OS thread, "forkOS": new OS thread)

I'd like to point out a concept that I think is being missed here:

   We never want to specify what OS thread is running a particular
   Haskell thread.

why not?  Because (a) it doesn't matter: the programmer can never tell,
and (b) we want to give the implementation freedom to spread Haskell
threads across multiple OS threads to make use of multiple real CPUs.

But the programmer CAN tell, you scream!  How can the programmer tell?
Only by calling foreign functions.  The point is that you want to
specify which OS thread is used to invoke a foreign function, NOT which
OS thread is used to execute Haskell code.  The semantics that Simon & I
wrote make this clear.

If we keep thinking like this, then implementations like Hugs can be
single-threaded internally but switch OS threads to call out to foreign
functions, and implementations like GHC can be multi-threaded internally
and avoid switching threads when calling out to foreign functions.

> Using the new primitive, we can view the new "threadsafe" keyword as
> syntactic sugar:
> > foreign import threadsafe foo :: Int -> IO Int
> ===>
> > foo :: Int -> IO Int
> > foo i = threadSafe (primFoo i)
> >
> > foreign import "foo" primFoo :: IO Int
> where
> > threadSafe :: IO a -> IO a
> > threadSafe io
> > = do result <-newEmptyMVarforkOS (do{ x <-io; putMVar result x })
> > getMVar result

This forces a thread switch when calling a threadsafe foreign function,
which is something I think we want to avoid.  

I'm basing this on two assumptions: (a) switching OS threads is
expensive and (b) threadsafe foreign calls are common.  I could
potentially be wrong on either of these, and I'm prepared to be
persuaded.  But if both (a) and (b) turn out to be true, then worse is
worse in this case.


More information about the FFI mailing list