
"Simon Marlow"
One high-priority problem we also have is that a program which calls System.exitWith from inside GHCi will shut down the whole system. [...] we currently don't implement any kind of process hierarchy, and there is no requirement for child threads to complete before the program exits, for example.
The approach we've taken here in Utah (in the context of Java operating systems) is to apply the following (standard) distinction between threads and processes: o Threads provide multiple concurrent streams of execution (and nothing else). Threads are not strongly isolated from each other so killing a thread can fatally wound another thread, redirecting stdout will affect other threads, etc. o Processes are sets of threads which are isolated from each other. In particular, you can kill one process without affecting the integrity of other processes and you can redirect stdout in one process independently of other processes. Processes are usually implemented using memory protection and often implies separate address spaces in OSs like Unix and Windows but, in the OS research community, that is viewed as an implementation technique rather than being part of the definition. (For example, there are a number of single address space operating systems (SASOS) and early JavaOSs tried to use strong typechecking in place of memory protection.) [Isolation may mean different things in different systems. For example, you might want to enforce some resource limits to protect processes against memory, cpu or bandwidth hogs.] Translating this into the GHCi situation, it seems that you want to treat GHCi and the user's program as two separate processes and we can imagine that anyone else writing an interpreter in Haskell would want to do so too. (e.g., it might be a useful way of structuring my graphics library too). When you come to implement this model, another useful concept from operating systems is the notion of a "red line". This is the border between "untrusted" user code and "trusted" system code. In a conventional OS, this line is the user-kernel boundary and is implemented using system calls, hardware traps, file descriptor tables, etc. but the concept is useful even if it is implemented using a combination of type safety, careful programming and exception handlers. In the current system, most of the IO library should lie beneath the red line. If a notion of process were added, then some parts of process creation/killing, running of finalizers, locking, etc. would lie beneath the red line. The value of this concept is: 1) Having a word for it. 2) As long as you have a clear statement of what level of "isolation" you want to achieve, you have a clear definition of what you have to protect against when you cross the red line. This is useful for answering questions like: Is it enough to add an exception handler? Should you add a timeout mechanism too? What resources have to be revocable? What resources need an extra layer of indirection so that you can implement different namespaces (e.g., file descriptors in Unix allow different processes to define stdout differently) Godmar Back (http://www.cs.utah.edu/~gback/) has explored this in detail (it will form part of his forthcoming PhD thesis): http://www.cs.utah.edu/flux/papers/redline-hotos7-base.html http://www.cs.utah.edu/flux/papers/kaffeos-osdi00-base.html Matthew Flatt (http://www.cs.utah.edu/~mflatt/) has encountered similar issues in MrEd/DrScheme/MzScheme (which is more or less GHCi for Scheme): http://www.cs.rice.edu/CS/PLT/Publications/icfp99-ffkf.pdf Godmar emphasises the OS side of things whereas Matthew comes at the same issues from a language point of view. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/