From: jones@pyrite.cs.uiowa.edu (Douglas W. Jones)
Newsgroups: comp.os.research
Subject: Re: A challenge
Date: 10 Apr 92 17:00:37 GMT
Originator: osr@ftp


I can't resist commenting on Tannenbaum's list.

In article <32507@darkstar.ucsc.edu>, by ast@cs.vu.nl (Andy Tanenbaum):

> 
>                               THE TOP FIVE
> 
> 1. Microkernels are the way to go.

  Indeed!  I fully agree.
> 
> 2. Synchronous (blocking) communication is easier to use than asynchronous.
> 3. RPC is a good idea to base your system on.
> 4. Atomic group communication (broadcast or multicast) is highly useful.
> 5. Distributed shared memory in one form or another is a convenient model.

  Indeed, these may be true, but here's my quibble.  If you put these in
  your kernel, it'll be too fat to call a microkernel!  One of the biggest
  things I've learned in the past 20 years is that system designers
  shouldn't insist that programmers use the primitives they've come up
  with!  I've seen this over and over at many levels, but here are some
  examples:

  a) Distributed system designers who insist that, because RPC communication
     is a good idea, I must use it, no matter how ill suited it is to my
     application.

  b) Language designers who insiste that because X is formally sufficient
     for writing any program, that is all they will allow.  (Substitute
     "while loops", and note Knuth's well known paper about structured
     programming with GOTOs, or substitute the Ada rendezvous construct
     and try implementing the concurrent priority queue implementation I
     wrote up in CACM a few years ago.)

  So, if you use Tannenbaum's list to guide the construction of a new system,
  please don't forget an earlier lesson from the 1960's -- make your design
  hierarchical!  Let your microkernel support efficient datagrams or some
  other trivial to implement interprocess communication primitive like
  datagrams, and then provide standard tools built on this kernel to support
  RPC, reliable blocking message passing, atomic group communication, and
  all that stuff.  Of course, to make an efficient hierarchic design, the
  low level should be tuned to provide efficient support for the primitives
  that most users are expected to use!

  Finally, another lesson from the 1960's applies.  Make your hierarchy
  transparent (see Parnas's old paper on transparency and opacity in
  hierarchically designed systems).  Let me use datagrams or some other
  low level primitive on those occasions when the high level primitives
  you've supplied don't match my application's needs!

  Finally, I offer the following addition to the list of lessons:

  ?. The primary responsibility for fault tolerance must rest on the
     application program.  Lamport's end-to-end arguments are at the
     heart of this lesson.  These arguments lead to the conclusion that
     low-level fault tolerance mechanisms need not strive for perfection,
     but rather, they serve to enhance performance by limiting the extent
     to which user level fault handling comes into play.  This, in turn,
     allows the use of relatively trivial brute force fault tolerance at
     the user level.

					Doug Jones
					jones@cs.uiowa.edu