Whenever an object wants to export part of its interface to the outer
world it must create one portal per method. To automate the task, each
class with methods being exported should be labeled ENTRY too. In
this way a compiler can generate the glue code between the portals and
the methods being exported. All the method of task are considered to
be exported to the user.
In particular, the compiler will generate automatically the implementation of this method:
<Off private methods for exported objects. >= // Creates portals to access class methods void export(void);
The code generated for export will create one portal per method.
The portal handler will be setup so that methods are invoked
transparently: The program counter will be pointing to the method code
and the maximum expected number of message words will be setup to the
size in the stack of the method arguments. The task of extracting the
arguments is done automatically by the portal invocation mechanism and
the compiler because portal messages are always copied from (caller)
stack to (callee) stack.
Those methods exported are expected to return a non-zero value with
the error code in case the invocation fails, or zero otherwise. This
can be used by user-level wrappers to raise exceptions. That error
code will be returned by delivering a ``system call failed''
(SCERR) event to the shuttle issuing the system call. The handler
for that event may set the error code inside the user application so
that an exception could be raised. The benefit of using events for
error notifying is that we save a register and permit ``optimistic''
system usage where most of the times the system does not need to
return anything to the user.
It should be noted that the object constructor should call export
or nothing will be actually exported.
Portal identifiers are not stored because the order in which exported system objects are created is always the same. Thus, the algorithm used to construct the portal identifiers ensures that given the node identifier, portal numbers will always be the same. This is to say that they are node-wide constants.
Although it is not part of the kernel, we will say that the compiler
mentioned above can generate user wrappers too. These wrappers are
objects with the same signature of the system object being exported
but with just those methods being labeled ENTRY. Each wrapper
method will simply invoke to the kernel portal and raise an exception
on portal return whenever the return code is non-zero.
Note that many of these wrappers are to be built dynamically as users obtain access to system resources. They can cache the identifier of the resource being wrapped and use that identifier to to perform system calls.
To make it clear what system services are being exported to the user,
and also to avoid in-kernel authentication (e.g. unnecessary access
checks when operations are requested by the kernel itself) we will
wrap every object being exported to the user. Those wrappers will be
named with the prefix off_u2.1 and will be described right after the objects they are
wrapping to make it clear which methods are exported to the user.
NOTE: XXX. Iinclude a figure and reference the pattern used to mirror system services with a wrapper hierarchy.