Standards Update, IEEE 1003.4: Real-time Extensions

Donn Terry donn at hpfcrn.fc.hp.com
Tue Oct 2 02:26:18 AEST 1990


Submitted-by: donn at hpfcrn.fc.hp.com (Donn Terry)

I've been following this discussion on the issues of filesystem namespace.

I'd like to step back from the details and look at it a little 
more philosophically.  I think that that may lead to a resolution of the
issues (or at least some progress) (or a decrease in the shrillness)
(or something).

UNIX was designed to simplify the programmer's life.  In particular, 
anything that could be reasonably generalized, was.  This generalization
is not an easy task, and not easy to explain.  The genius of Ritchie and
Thompson was both because they acheived the generalization, and because
they got others to beleive in it.

The generalization is more difficult to deal with when you are "used to" some
other model.  (I see folks using various propietary systems griping about
UNIX because it doesn't do everything just the way they are used to.)
As Dijkstra once observed about BASIC (I paraphrase, not having the quote).
"The teaching of BASIC should be forbidden because it forever ruins 
students from being able to use better languages."

I think that (although he exaggerates) that Dijkstra's comment also applies
in this case.  We all are contaminated to some degree or other by the 
preconceptions we bring with us from other training (be it experience with
other OSs or something else).

I have some personal concerns about some of the functionality in 1003.4
because it appears to be based upon models from other, successful, 
implementations, but ones that may not have been through the process of
generalization.  It was R&T's thought that having lots of processes would
solve such problems, and for the day, it did.  Now it doesn't because of
tightly coupled activities (tasks?) needing "fast" switch time. 

To me, threads is the generalization that follows the original philosophy, 
not bringing up the OS-like functions similar to select() to the user. 
(I didn't like threads at first, like many don't; I may still not like the
details, but they do seem to provide the generalization needed for 
that class of task, without the application writer having to write a
mini-dispatcher of his/her own.)

The broad context of namespace is similar, to me.  What's the
generalization?  I don't really know.  My (UNIX flavored) biases say
that it's the filesystem.  However, a generalization, not a statement
that "my problem is different so must be treated differently", is the
right answer. 

Let me try something for the readers of this group to think about.

The "UNIX Filesystem" really consists of two parts:  a heirarchical
namespace mechanism that currently names objects which are at least
files, devices, file stores (mounted volumes), and data stream IPC
mechanisms (OK, FIFOs!).  Some systems add other IPC mechanisms
(Streams, Sockets), and the process space (/proc.)  I could go on.

One of the class of objects named in the namespace is ordinary files.
The set of ordinary files is a collection of flat namespaces, where
the names are (binary) numbers.  (Each mounted volume is an element
of the collection, and each i-number is a filename.  The "real names"
of files are the volume and i-number pair; that's how you tell if two
files are identical, not by their names in the namespace, of which
they may have zero or more.)  (The fact that the other object types
also usually have i-numbers is an accident of implementation.)

Open() is a means to translate from the namespace to a handle on an object.
It may be that the handle is for an ordinary file, or for some other 
object (as I listed above).  Historically, files were the most common
concept, and the namespace becomes the "filesystem".  (The volume/inode
namespace isn't, and shouldn't be, accessible, because the gateway
functions that Doug Gwyn mentions are necessary and valuable.)

Given the above three paragraphs, one could consciously separate the 
namespace from the file system further, and then the arguments that 
"a connection is not a file" seems weaker.  A "connection" is an object
in the namespace, and open() gives you a handle on it.  Given that you
know what the object is, you may have to perform additional operations
on it, or avoid them.  (E.g., many programs operate differently based on the 
nature of the object they open; if it's a tty it does ioctl() calls on
it, if not, it doesn't.)

I'm not yet sure that the "filesystem" namespace is (or is not) the
right generalization, but a generalization is useful so that we don't
end up were we were when R&T started out with a bunch of unrelated
namespaces where, by relating them, common functions could be combined,
and common operations could be performed commonly.  For example, it
would be a shame if we find that some network objects that were not put
in the generic namespace could reasonably have the
open()/read()/write()/close() model applied to them, and because they
were in a different namespace, this could not be done (easily).

Many exisiting proprietary systems (and even more historical ones) left
you in the state that a program that sequentially read an ordinary file
couldn't simply do the same thing to a device (without extra programming,
anyway).  Not looking for the generalization could lead us to the same
state again for the "newer" technologies.

Donn Terry
Speaking only for myself.

Volume-Number: Volume 21, Number 161



More information about the Comp.std.unix mailing list