Hi all,

I was thinking of implementing an epoll based event loop for GHC's
threaded RTS, but I've been having some problems with circular
dependencies in GHC.Conc, and before I do too much major surgery (this
is my first time touching GHC's internals after all...) I'd like to
get some advice on the best way to go.

First off, although in ticket #635 there's talk of libev, I suspect it
might be better to directly use epoll, as it'd be possible then to
register file descriptors for watching without needing to do
user-level locking or waking up the IO manager thread in most cases.
As such, initially I'd like to focus my efforts on generalizing the
infastructure to support more than one IO manager per platform, and
implementing epoll as an initial test.

My initial plan was to break up the mingw and select() based event
loops, and place each into its own module (GHC.IOMgr.Select etc). Each
would have an initialization function (init :: IO IOMgr) to either
initialize the IO manager, or break and toss an exception; the
GHC.IOMgr module would then have a list of supported IO managers and
try each in turn. This allows us to fall back from epoll to select
when GHC is built against a libc with epoll, but run on an old kernel
which does not support epoll; it also paves the way for other IO
managers in the future (kqueue, libev, etc...)

However, since the existing IO managers depend on MVar, TVar, forkIO,
and other primitives implemented in GHC.Conc, this isn't easy as-is.
My initial thought is to break up the GHC.Conc module into individual
modules such as GHC.Conc.Threading, GHC.Conc.STM, etc to help resolve
this - is there anything I should be aware of before I dive in?

Also, I'm tempted to make the primitives for requesting a timer
callback be along the lines of
ioReadEvent :: Fd -> IO () -> IO ()
rather than
ioReadEvent :: Fd -> MVar () -> IO ()
or
ioWaitForRead :: Fd -> MVar () -> IO ()

This I would allow later for asynchronous IO high-level operations
without needing extra user threads, as in:
notifyOnRead :: Fd -> IO () -> IO ()
notifyOnRead fd callback
 | threaded = ioReadEvent fd (forkIO callback)
 | otherwise =
    error "Asynchronous IO callbacks not supported in the non-threaded RTS"

I do note that the current IOReq and Delay structures are very careful
to strictify and unpack their members, though, so is there a known
major cost associated with this?

Thanks,

Bryan Donlan

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to