| Yes, it definitely helps. It seems to be equivalent to "P1, but all | foreign exports are bound". Stupid me -- so it is! Yet you disliked P1 enough to put forward P2. Was the 'main thread' thing the only reason? | *) forkOS needn't be a primitive, it can be implemented via the FFI (cf | Section 3.2, first Proposal). True, but clumsy; I think it should be in the spec. | *) The semantics should probably have an (END) rule that specifies that | a thread created using forkIO can just end (without returning anywhere). Yes, I agree. | *) We should perhaps add a primitive for querying whether the current | thread is bound or not. | This can be used for writing combinators that use forkOS only when | necessary to make sure that we can access a foreign API that uses | thread-local state. | *) I don't think that a bindToOS primitive is really necessary, | emulating it using forkIO shouldn't be noticably slower, IMO. | *) We might sacrifice a little performance by making all foreign | exports "bound". That should be paid back in simplicity. Hardcore | hackers can always use forkIO to move work to a lightweight thread. All good points -- would you like to add them to the document? We seem to be converging! | One issue remains however (and that's the topic of the rest of this | e-mail); what to do about broken libraries that treat the "main" OS | thread (i.e. the one that static initializers are run in) as special? | This really happens; in fact both of Apple's GUI APIs are that | brain-dead in the current version of Mac OS X. I guess we can agree that we don't want to mess up the design for this reason alone. We just need some workaround. | So, our options seem to be | | 1) bind the "main" Haskell thread to the "main" OS thread | 2) don't bind the "main" Haskell thread to the "main" OS thread | 2a) complicate the system by adding a way to access the "main" OS | thread | 2b) keep the system simple, use the hack I described above for GHC | programs that use Apple's libraries, and hope that Apple fixes it's | libraries before people want to use them with other implementations of | proposal4 where the hack doesn't work. One might also add We might add (3): on MacOS, arrange the GHC runtime so that it spawns a thread to start and run Haskell, and then (in the main thread) calls in to the Haskell export 'mainMacOs'... which will then be guaranteed to be the main thread. Ugly though. for (1), the main-thread binding could be on MacOS only; and that is equivalent, but much less fragile, to your hack. So perhaps it'd do? Simon
Simon Peyton-Jones wrote:
| Yes, it definitely helps. It seems to be equivalent to "P1, but all | foreign exports are bound".
Stupid me -- so it is! Yet you disliked P1 enough to put forward P2. Was the 'main thread' thing the only reason?
... and the protests against extending the FFI syntax. I hadn't thought of just making all foreign exports "bound" before, mostly due to performance concerns... In the beginning, People seemed to be concerned about any performance impact on "normal use", and, perhaps more importantly, I had slightly different plans for the GHC implementation where the cost would have been greater. After spending some time thinking about how to implement P2, I think the cost can be neglected. P2 seems to be a proposal that solves all issues that we are interested in, except for one issue: complexity. Compared to P1, it removes an extra keyword and solves the main-thread issue. P4 makes two small tradeoffs to achieve simplicity: all foreign exports require bound-thread-scheduling (small performance cost), and the main-thread issue has to be addressed by a separate workaround. You've convinced me that the gain in simplicity is worth that.
| *) forkOS needn't be a primitive, it can be implemented via the FFI (cf | Section 3.2, first Proposal).
True, but clumsy; I think it should be in the spec.
OK, then let's just add a remark... OTOH, it seems like it makes the formal semantics more complicated; bound threads now have two distinct ways of ending --- returning to a native thread and returning to nirvana. If we don't model forkOS, then we'd have a rule (END) that says that unbound threads just cease to exist, and a rule (HRET) that says that bound threads return to the native thread they're bound to.
All good points -- would you like to add them to the document?
OK.
We seem to be converging!
Yes! :-)
We might add (3): on MacOS, arrange the GHC runtime so that it spawns a thread to start and run Haskell, and then (in the main thread) calls in to the Haskell export 'mainMacOs'... which will then be guaranteed to be the main thread. Ugly though.
So that we would have one "main" action running in an unbound thread, and a "mainBound" action bound to the main OS thread? Yes that's ugly... (and I'm afraid of the linker tricks that will be necessary to make "mainBound" really optional).
for (1), the main-thread binding could be on MacOS only; and that is equivalent, but much less fragile, to your hack. So perhaps it'd do?
Perhaps a RTS option, which perhaps defaults to "bound" on MacOS and to "unbound" everywhere else, so we can avoid slowing down non-GUI programs on MacOS and so that we can use broken libraries on other platforms, if there are any. Programs that require the main thread to be bound could use a runtime assertion to be sure that wrong settings are noticed immediately; something like main = assert currentThreadBound $ do ... I think I like the RTS option best. Cheers, Wolfgang
participants (2)
-
Simon Peyton-Jones -
Wolfgang Thaller