Kernel 0.11, [arf1]
Dennis Marer
dmarer@td2cad.intel.com
Wed, 24 Mar 93 10:34:46 PDT
Howdy all!
Some comments on the kernel so far - looks pretty good!
One statement concerns me: "every object is a process..." I'm assuming you
mean every *instance* of an object is a process, which would require a lot of
overhead. (As an estimate, a system might use between 256 bytes and 8k to
represent a single process and its registers, state of the machine, etc.)
*Note* Andreas mentioned using 'objects' to represent an integer, etc. This
is commonly done using a 'concrete object', or one with no virtual methods
and no capability of inheritance -> only concrete methods. The data overhead
to accomplish this is *zero* and most of the functions are inline anyway.
This should be left up to the compiler - creating a regular object to do this
is probably silly anyway because the overhead for an object is usually larger
than the size of an integer anyway. SEP (Somebody Else's Problem).
So most of our objects will be larger than an integer anyway. I think from
the implementation perspective, a task switch is a very expensive operation.
(Again, an estimate on the 386 is about 100 clock cycles!)
Some objects will *need* to be processes: device drivers, applications, etc.
I don't believe every object does though - for example, a spreadsheet might
represent every cell as an object, and no other application would need to
access these objects. Therefore, they are private to the spreadsheet and
dependent entirely on the spreadsheet process, or the instances of the cell
objects are contained within the spreadsheet process. (They occupy this
process' data space.)
Now take a look at a database application: multiple processes would need
access to the same instance of an object (a record in the database) at once.
Each process can change the object, and (possibly) one process changing a
database record notifies all other processes with interests in that record
that a change has been made so they may update themselves accordingly. This
type of object is a 'public' object, stored (most likely) in some shared memory
space, and has some special characteristics allowing it to be shared between
processes and (in a distributed system) between systems. Methods for sharing
these objects between processes and systems are implemented in the next type
of object, which is....
The process object. Descendants of this type of object would be applications,
device drivers, and *possibly* the kernel itself. Processes have some way of
making themselves available to other processes, and if one process knows the
interface to another, they can communicate directly. As mentioned before,
shared object stored in this manner would probably be distributed through this
interface.
So far, this is our object heirarchy:
object
| |
shared object process object
An 'object' is the definition of how an object in this system is structured,
how it behaves, how its attributes (data) are stored, and how its methods
(functions) are accessed. Most languages (C++) do not define an 'object'
object, but in this system *all* objects have a common ancestor. If, for
example, an object were defined in C++ with no ancestors, it would (by the
compiler) be given the 'object' ancestor by default. This ties all objects
together with a single ancestor, closing a major gap in to OOP paradigm.
Maybe it defines some methods...I don't know yet. This kind of object is
created in a private memory area, which must be owned by some process.
Maybe this object defines some virtual methods for loading itself and storing
itself to and from a 'file' object? This way, all objects are given the
interface to load/store, and whether or not this is implemented is up to the
object designer. Also, the 'object' object would be given some method to
identify itself in a system dependent manner, defining which module the object
is found in an what the object is called. (module:object) This I don't know
how to define yet...
A 'shared object' is the next step in this heirarchy, and represents an object
which can be shared between mutlitple processes, or (eventually) between
systems in a distributed system. This object must be able to handle itself
contention of multiple processes through the use of semaphores or other similar
devices. This kind of object is created in a shared memory area, which must
be owned by some process. Some process must manage these - they are not
independent in and of themselves.
A 'process object' is the type of object associated with a task or application.
When a process object is instanciated, it can be made public to other proceses
(or not) through which other processes have access to its methods. These are
managed by the kernel, and access to processes (finding a process object
pointer?) is done via the kernel.
----------------------
An example using this scheme, implementing a database application:
The database process is started for a particular database, placing it in the
system wide table of processes, or giving only a limited subset of processes
access to it. (This access and protection still needs to be ironed out...)
Another process begins, and needs to access the database. It requests the
kernel for a pointer to the database process object. Next, it needs to find
all records in the database with a certain search criteria, and uses the
database process object's methods to perform this search, returning a list of
objects. Each of these objects are instances of shared objects stored in
memory managed by the database process; for all the requesting process knows,
it instanciated these objects itself and should treat them as such. *Note*:
directly modifying the contents of these objects is not allowed... Next,
another process accesses the database and also requests similar records, so
now two processes have pointers to identical objects (the same data, *not*
two instances!). The first process *destroys* its version of the shared
objects (the database records) when it is through, just as it would with any
other object, except instead of freeing memory it only dereferences the object,
and when the reference count reaches zero the object is actually destroyed.
Did I mention the second process existed on another system? :-)
Basically, when processes are created some access protection is set to allow
use by a single user, multiple users, multiple systems, etc. This example
database application would probably allow multiple user access, but only a
limited subset of "installed" users. I.E., the database has complete control
over which users are allowed to access its process (via the kernel) to begin
with.
--------------------------
I envision shared memory being read-only by all processes except the owner.
(The owner can write as well.) Across distributed systems, process should not
even be allowed to read shared memory. This way, all information can be
gathered from an object without a task switch; to modify an object requires a
task switch to the owner's task, so each method in a shared object must be
classified in some way to allow this to happen.
Ok...these thoughts are a little sketchy, but coming together nicely. Let me
know what you think! This is absolutely implementable - I've done my research
there. I think this is our best bet of an object oriented system...
Dennis