[unios] Generic Design

Anders Petersson anders.petersson@mbox320.swipnet.se
Wed, 09 Dec 1998 23:37:33 +0100


From: Anders Petersson <anders.petersson@mbox320.swipnet.se>

I want to share with you my idea of how UniOS should be made generic, and
what I mean with the word 'generic'. Beholder will recognize some of this,
but I'm explaining the essential parts more in detail now, and I try to
make this in a more structured way.
I think that after some discussion, modification and clarification, this
paper could maybe be added as a document to the site. (It's up to you, of
course.)



'Generic design' model
======================

The base is an object-oriented system. With object-oriented I don't mean
that the OS has to be written in a OO language, but that the things that
the OS is concerned with are generalized to be different kinds of the same
concept, objects. Everything in the system is an object. Also many objects
that are usually implemented as compile-time objects or external files
should be made as system objects, giving other objects, including
authorized users, the ability to modify it's value independent of the
application itself.

Interfaces
----------
An interface is as the methods in classes, but only the public ones.
Private methods are not interesting for the OS. All objects conform to
defined interfaces, depending on the nature of the particular object. All
access to an object is done via these interfaces. What an object type can
do is defined by what interfaces it supports.
Interfaces are declared to the system, and they never change. If new
features are introduced, they have to be added in an add-on interface.

Object characteristics
----------------------
Objects indeed differ from traditional compile-time objects. They don't
support inheritance. Variables are not modifiable directly, and not even
visible to the world. Changes have to be made throu calls to the interfaces.
Actually, the only definition of an object is that it is registered with
the OS and conform to the object rules. It also is backed up by a OH
(explained later), and supports at least one interface.
Every object has a unique (on that system) id, short called OID. The only
thing that OIDs does is to identify each object, and separate them from
each other. It is uncertain if OIDs will exist in the final version of the
system.

Object handlers
---------------
Something that corresponds to the actual code that performs the methods of
traditional objects is needed. I call the constructions that does this
'object handlers', OHs. These are the very things that brings the system to
life. Whenever an object need to do something, it's the OH of that object
type that does it. What the objects really are, is up to the OHs. The
objects themselves does *not* contain any data, except for maybe some small
attributes that all objects have. Otherwise data is all handled by the OHs.
Object types are not statically bounded to a specific OH. They can be
"reassociated" with another OH, just as file extensions are associated with
a program.

Hardware
--------
Each piece of hardware is represented as just another object, with the same
rules regarding use. There are some differences to ordinary objects, thou.
Hardware objects might be impossible to move (if not working with symbolic
links to the objects), and support some interfaces that ordinary objects
rarely support.
There are exceptions to the rule that hardware is objects. One is storage,
which isn't used in the same way, and should be protected from being used
up in some other way. CPUs aren't objects either. Objects shouldn't deal
with the CPU(s) at all. Their only worry is to get enough processing time,
which is handled as concrete things that can be possessed. Realtime
processes get a real value, whilst usual processes get a percentage of the
availible processing power. Processing power is delegated down the system
tree. The root owns all time. Each user maybe owns an equal percentage of
the time. The users may then give their respective time shares to processes
as they like. The same method could be used for all kinds of storage.
Otherwise I can't think of any hardware device that shouldn't be an object.

Object security and interaction
-------------------------------
If a object wants to gain access to another object that it does not already
have access to, no matter what object or purpose, it asks the OS. If the
security policy permits access, a dependancy is registered; both that the
client uses the object and that the (server) object is used by the client.
The client gets access to a handle to the object. Without a handle (which
BTW can't be traded without interference of the system), access is not
possible.
Access may be given to different degrees. Say that an object supports two
interfaces; the 'read raw data' and the 'write raw data' interfaces... then
access could be restricted to just the 'read' interface, and it might even
be invisible to the client object that it's possible to write to the target
at all.
Objects (which include most resources) can be shared in some different
ways, all very fundamental. This can then be applied to files and other
resources. The same data or code should never have to be loaded twice when
used simultanously by different processes.
An important detail in the resource sharing is that objects can be notified
when a resource they are using is modified. This is good for a great many
purposes. For example, a process is notified when its configuration is
changed, an application is notified when the size of its window is changed,
an email program is notified when a connection is made to the internet, an
object is notified when a file it opened in shared mode is changed, etc, etc.


System tree
-----------
The whole system is made into a single directory structure, where every
object is an own node.
The system tree is very flexible. The OS only keeps track of the system
tree's structure and dependencies. Processes are run by special objects
that implement multitasking. A node can implement its subtree in its own
way, depending on the type of the node. In this way a FS can provide the
whole disk contents as a subtree. Users are mounted on arbitrary (but
well-defined) places in the system tree, and have full control over
everything that branches out from his 'home location' and their children.
This can be customized. The users home directory becomes his root dir, and
he cannot 'travel' outside it, unless he is given access to outside
objects. If he is, he can also travel to the granted objects.
Maybe I should point out specificly that secondary storage is a part of the
tree too. Objects that are on disk - most resembling files - look and act
the same as objects in RAM, except for the storage method. It isn't
important if an object is stored in RAM, on disk, on a network - or all three.
Almost forgot, every object instance has a human-readable name, so you can
browse the whole system tree and actually understand what everything is.
You can even configure the system with no more help than this tree
browser/editor.

OID servers
-----------
OID servers are a corner-stone in the system. They keep track of what
objects there are, their object id (hence the name), and all dependences
regarding the objects, including parent and children (= its place in the
system tree). They have the responsibility to store these data on their own.
There most probably are several OID server on a system. The first one
contains the system tree's root and close objects such as other OID
servers. Each partition - or at least each physical storage unit - should
have an own OID server which controls everything on that unit.
An OID server is also implemented by each network interface, to redirect
object references on the network. These can perform table lookup on OIDs,
to translate them into the correct OIDs on remote system. (OIDs are
system-wide, but not network-wide. This is only for normal use, however. In
distributed systems, OIDs could well be network-wide.)
The only thing that OIDs does is to identify each object, but the system
OID server will use the first part of it to know what other OID server to
call.
It's up to the server to create new OIDs. How they are constructed is only
dealt with by the responsible server.


Let me finish by pointing out some side-effects of this system, good and
bad, intentional and unfortunate. I'll begin with the negative
side-effects, so when you have read all of it throu, you will just have
read the good side-effects, thus remembering them best. :)

Negative side-effects
---------------------
- The space needed increases somewhat.
- The speed degradation could become a problem when many objects that uses
the same resource need to be notified of a change at the same time. It
should be possible to reduce such effects.
- The number of objects could maybe become overwhelming. The same problem
could arise with OHs too, and maybe even with interfaces.
- Programmers may be displeased with the common objects' design. Compare
with the different user interface styles used in different code libraries.
(This specific problem should not arise when using these ideas, it's just
an example.)
- It's an unconventional solution. Developers and users might find it
difficult to migrate to the new OS.
- Performance could suffer when using persistent storage, since it's the
OHs that store the data, which means that logically connected data can be
stored on different places. It maybe is possible to change this,
eliminating the problem.

Positive side-effects
---------------------
- No separate mechanism for file access/sharing is needed.
- Networking introduces no new complications for application programmers,
and can be quite invisible for users too, if desired.
- All flexibility that could possibly be wanted is achieved at no extra
effort.
- No external and possibly bulky security mechanism is needed, and very
detailed security policies can be applied.
- A clean, consistent (and hopefully not too hard to grasp) design that is
not dependant upon any specific hardware.
- The construction with different interfaces and OHs is very powerful,
allowing for an OO access method, where different implementations and
intermediate layers can be used transparently. I could give an infinite
number of examples, so I'll avoid giving any at all, so I don't make the
possibilities look limited. :)
- Developers don't need to do as much peripheral work, since much of what
they otherwise would have to do themselves is implemented system-wide as
objects. A problem today is that programmers have to implement the same
features over and over again.
- Since "links" are maintained, there never arise any dead references. This
means you always know if a file can be deleted, files can be moved with all
references still alive, and the state of the system is easily visualized.
- Small, generic units can be combined to accompish more advanced tasks.
This is practised to some degree in UNIX, but much greater possibilities
arise in this system.
- Custom file attributes can be implemented as children to files.



binEng

------------------------------------------------------------------------
To unsubscribe from this mailing list, or to change your subscription
to digest, go to the ONElist web site, at http://www.onelist.com and
select the User Center link from the menu bar on the left.
------------------------------------------------------------------------
UniOS Group
http://members.xoom.com/unios