Poll: System.exitWith behaviour
Alastair David Reid
reid@cs.utah.edu
30 May 2001 14:29:32 -0600
"Simon Marlow" <simonmar@microsoft.com> writes:
> 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/