
On Tue, Apr 04, 2006 at 02:25:11PM +0100, Simon Marlow wrote:
On 31 March 2006 22:15, John Meacham wrote:
On Fri, Mar 31, 2006 at 04:21:26PM +0100, Simon Marlow wrote:
Great. Apart from my misgivings about allowing cooperative scheduling at all, here's a few comments on the proposal:
much much preferable to a standard that not everyone can implement. :)
- I wouldn't include threadWaitRead, threadWaitWrite, or threadDelay at all. These can all be implemented using FFI, so don't belong in the concurrency library. Their presence is largely historical.
They all have special implementations on a 'epoll' based system. threadDelay turns into the timeout parameter to select, waitread/write turn into the basic building blocks of your epoll wait-list. We definitly want these in the interface as primitves.
Still not convinced. Most applications can use the standard IO library in a multithreaded program to get I/O multiplexing. The library might be implemented by using a clever epoll/kqueue/whatever interface underneath, but I don't see a reason to expose that as a standard library. And it's perfectly reasonable to implement concurrent IO without doing any clever epoll stuff: GHC on Windows does just that.
IMHO, concurrency gives you a way to *avoid* needing an event interface in your language.
Oh, it was always my plan to expose the epoll/Event library, it is something lacking in haskell currently which is a pain. Often, an EDSM loop is the best way to express an algorithm. Concurrency is great, but it is far from a panacea.
In particular, foregin concurrent calls will most likely be implemented in _terms_ of threadWaitRead on cooperative systems.
By all means, but that still doesn't mean that threadWaitRead needs to be in the standard.
Here are a couple of uses. We need waiting routines for every interesting event, they are darn useful, and they admit a very optimized implementation. A C library which reads a file descriptor, calling threadWaitRead beforehand and then the call is much more efficient than calling the library directly. A consumer-producer set up, you don't want to read into core memory the producers data until you are sure you have somewhere to write it to, so you have a 'threadWaitWrite-read-write' loop. UI design, a common issue is displaying continuously updating information on the screen. You communicate with the X11 server via a pipe, so it is possible to just completely fill the X11 buffer with drawing requests and get a backlog killing your apps responsibility. also, by the time these backloged events actually get to the screeen they may be out of date and your app quickly crashes and burns if your incoming data rate exceeds the speed at which you can draw to the screen. Concurrency admits a nice solution, you have your thread that generates the interesting info, (say, reading data from a DSP), continually updating a shared location. your drawing routine is in a 'threadWaitWrite-readlocation-drawit' loop. notice that threadWaitWrite is needed because otherwise you would be forced to send outdated data to the screen if you couldn't separate what you write from when you write it. A C call that uses a file, but expects some precondition to be set before it can be run. One that I ran into is a curses library that waited for user input, but wanted the screen to be cleared before it could be run. clearing the screen right away would have left the user sitting staring at a blank screen with no instructions until they pressed a key, the right thing to do was to do a threadWaitRead, clear the screen, then call the routine. Efficient scheduling is another use. you might want to wait for several clients to become ready before deciding which one to actually service. Basically, they are needed any time the data you are processing is time-dependent. any time you need to decide what to read or write on the current conditions rather than what they were when you started the read or write. John -- John Meacham - ⑆repetae.net⑆john⑈