comp.lang.ada
 help / color / mirror / Atom feed
* Thoughts on the ADaOS user program interface
@ 2001-09-06 18:18 Kenneth Almquist
  2001-09-07  8:24 ` Dmitry Kazakov
  2001-09-07 16:48 ` Warren W. Gay VE3WWG
  0 siblings, 2 replies; 5+ messages in thread
From: Kenneth Almquist @ 2001-09-06 18:18 UTC (permalink / raw)


I've been thinking about what the system call architecture for an
Ada OS might look like.  I would want the interface to be specified
in a collection of packages, all descendents of a package named
AdaOS or somthing similar.

The Intel x86 architecture supports procedure calls across protection
boundaries (so that user code can invoke procedures in the kernel),
but the design is not secure if you have multiple tasks because the
kernel mode procedure runs on the same stack as its caller, which
allows another task running concurrently to alter the stack frame of
the kernel mode procedure.  So calling a system procedure requires a
trap to allow us to switch to a kernel stack.  We could generate a
stub for each call which executes a trap instruction (that is what
Linux does), or we could tell the linker that the system procedures
are at addresses which are not actually mapped, and have the trap
handler invoke the actual kernel routine.

Some things are best modelled using tagged types; the obvious example
being the AdaOS analogue to UNIX file descriptors.  These will be
implemented as tagged types inside the kernel, but we also want them
to appear as tagged types to applications.  One idea is to have the
compiler implement

	pragma Separate_Tag(Tagged_Type);

which specifies that the named tagged type doesn't contain a tag
field.  Instead, pointers to Tagged_Type'Class are "fat pointers"
containing both the address of an object and its associated tag.
This allows user code to transparently use pointers to objects
which are not in the user's address space.  An alterative is to
create a "proxy" object in user space for each kernel object that
a program uses.  This complicates the interface to the kernel but
avoids compiler changes.

(Note: In addition to the use suggested here, pragma Separate_Tag
would improve the performance of types like Ada.Strings.Unbounded,
where a tagged type is required but the tag is rarely used.  When this
pragma is applied to a type, it is not possible to redispatch in the
primitive subprograms for that type, because that would require using
the tag in a context where there is no class-wide pointer to the
object.)

The UNIX ioctl system call bypasses the C type system.  Using tagged
types lets us provide similar functionality while staying within the
Ada type system.  Code that operates on tty devices might look like:

	if F in Tty_Devices then
	    Tty = Tty_Devices(F);
	    Get_Terminal_Modes(Tty, Modes);
	    ...
	end if;

Furthermore, users can implement their own data types which have the
same interface as system types, and use their types interchangably
with system types.  So you can write versions of the "file" data
type that do things like perform compression or read/write to
in-memory data structures rather than files, without involving
the operating system.  Contrast this to UNIX, where a file descriptor
can refer to a variety of entities, but extending this set requires
kernel modifications.

Error reporting should be done by throwing exceptions with a descriptive
error message attached.  My experience is that more often than not,
if a system call fails the program logic doesn't care why it fails.
Once the error is reported or logged, the recovery action is the same.
Therefore, I would suggest that exceptions be defined which relate to
the type of operation which failed, rather than the reason the operation
failed.  The exception message associated with the exception should
consist of an error code followed by descriptive text.  The error code
allows a program to take actions that depend on the precise reason
that an operation failed, when this is necessary.  It also simplifies
the task of converting error messages to a language other than English.

There should be a stub generator to create the linkage code to allow
kernel subroutines to be called from user mode.  The linkage code
needs to handle arguments as follows:

 *  Parameters passed by value (e.g. integers) need to be copied
    into kernel space.

 *  Parameters passed by reference do not need to be copied
    (assuming that the address mapping is set up appropriately
    so that user data can be read and written from kernel mode),
    but the address of the data has to be validated to ensure
    that it actually is used data and not kernel data.  Also,
    the bounds of an array or string need to be copied into
    kernel space so that they don't change after address validation
    is performed.

 *  Pointers to kernel data structures need to be validated to
    ensure that they actually point to an object of the appropriate
    type.  It is probably most efficient to make the pointer value
    used in user space actually be an index into a table of kernel
    objects.  The validation process would look up the actual kernel
    address in this table.

An initial implementation of these ideas could be done by adding
code to Linux or BSD.  This would allow an initial implementation
to be put together fairly quickly, allowing experience to be gained.
				Kenneth Almquist



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thoughts on the ADaOS user program interface
  2001-09-06 18:18 Thoughts on the ADaOS user program interface Kenneth Almquist
@ 2001-09-07  8:24 ` Dmitry Kazakov
  2001-09-07 16:48 ` Warren W. Gay VE3WWG
  1 sibling, 0 replies; 5+ messages in thread
From: Dmitry Kazakov @ 2001-09-07  8:24 UTC (permalink / raw)


On 6 Sep 2001 14:18:04 -0400, ka@sorry.no.email (Kenneth Almquist)
wrote:

>(Note: In addition to the use suggested here, pragma Separate_Tag
>would improve the performance of types like Ada.Strings.Unbounded,
>where a tagged type is required but the tag is rarely used.  When this
>pragma is applied to a type, it is not possible to redispatch in the
>primitive subprograms for that type, because that would require using
>the tag in a context where there is no class-wide pointer to the
>object.)

Not only that. If tag is separate, one could make *all* types tagged.
Class-wide values would consist of tag + specific value. Pointers to
class-wides would be tag + pointer to a specific value.

This way one could make Boolean, Integer etc tagged and most of type
attributes ['Value, 'Image ...] dispatching.

Sorry for off-topic, but I could not resist (:-))

Regards,
Dmitry Kazakov



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thoughts on the ADaOS user program interface
  2001-09-06 18:18 Thoughts on the ADaOS user program interface Kenneth Almquist
  2001-09-07  8:24 ` Dmitry Kazakov
@ 2001-09-07 16:48 ` Warren W. Gay VE3WWG
  2001-09-07 19:35   ` David Starner
  2001-09-08 11:42   ` Florian Weimer
  1 sibling, 2 replies; 5+ messages in thread
From: Warren W. Gay VE3WWG @ 2001-09-07 16:48 UTC (permalink / raw)


Kenneth Almquist wrote:

> I've been thinking about what the system call architecture for an
> Ada OS might look like.  I would want the interface to be specified
> in a collection of packages, all descendents of a package named
> AdaOS or somthing similar.


I like this idea.


> The Intel x86 architecture supports procedure calls across protection
> boundaries (so that user code can invoke procedures in the kernel),
> but the design is not secure if you have multiple tasks because the
> kernel mode procedure runs on the same stack as its caller, which
> allows another task running concurrently to alter the stack frame of
> the kernel mode procedure.  So calling a system procedure requires a
> trap to allow us to switch to a kernel stack.  We could generate a
> stub for each call which executes a trap instruction (that is what
> Linux does), or we could tell the linker that the system procedures
> are at addresses which are not actually mapped, and have the trap
> handler invoke the actual kernel routine.


I suspect that in the interest of portability, you'll want to use the
library technique to interface to the O/S. This way, you have a normal
procedure call to the library routine, and then the O/S specific
library routine can issue the trap or whatever is appropriate for the
current hardware. I personally like the idea of calling some address
directly, but for portability reasons and others that you have pointed
out may work against this idea.

The Prime-50 series used to "snap" links to O/S routines. The pointer
was initially set to point to the string name of the O/S service in
such a way that a fault would occur. The O/S then would patch the
pointer to another value that would directly invoke the ring-0
routine (this is "snapping" the link). Thereby only invoking the
name lookup the on the first call.  I don't know if this would
work well on an Intel machine (for stack reasons, it sounds doubtful).


...

> Error reporting should be done by throwing exceptions with a descriptive
> error message attached.  My experience is that more often than not,
> if a system call fails the program logic doesn't care why it fails.


I have to disagree here. This may often be the case in some class of
applications, but servers and other more system-level software _do_
indeed care, and often must take appropriate action. One issue that
comes up in UNIX/BSD is the EINTR/EAGAIN error, that occurs when
a system call is interrupted due to the handling of a signal. Now
this could be handled at the O/S level differently in AdaOS, but it
may not always be simple (i.e. do you proceed with the system call
that is in progress, save its interrupted state, or back out the
system call as UNIX often does - returining EINTR/EAGAIN?)

Other classes of errors that are often examined are EACCESS, ENOENT,
ECHLD, EEXIST, ENOSPC, ENAMETOOLONG to name a few.

I think the deciding point for exceptions may be the frequency/cost
of the exception, and the nature of the error. Then again, I'd
be inclined to probably side with exceptions even in the case
of overhead, only because CPU
hardware is getting so much faster each year.

I have wondered if errors should be classified into a few
major categories, and then the classification of the error be the
exception that is raised. Then after catching the error, you
then examine the error code and decide upon the specific action.
I havn't decided myself, if this is necessarily a good thing, but
perhaps something to consider.


> There should be a stub generator to create the linkage code to allow
> kernel subroutines to be called from user mode.  The linkage code
> needs to handle arguments as follows:


I still like package library support between the app and the kernel
better. Then there is no difference between calling a kernel service
or any other library routine.


> An initial implementation of these ideas could be done by adding
> code to Linux or BSD.  This would allow an initial implementation
> to be put together fairly quickly, allowing experience to be gained.
> 				Kenneth Almquist


Absolutely.

-- 
Warren W. Gay VE3WWG
http://members.home.net/ve3wwg




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thoughts on the ADaOS user program interface
  2001-09-07 16:48 ` Warren W. Gay VE3WWG
@ 2001-09-07 19:35   ` David Starner
  2001-09-08 11:42   ` Florian Weimer
  1 sibling, 0 replies; 5+ messages in thread
From: David Starner @ 2001-09-07 19:35 UTC (permalink / raw)


On Fri, 07 Sep 2001 16:48:37 GMT, Warren W. Gay VE3WWG <ve3wwg@home.com> wrote:
> indeed care, and often must take appropriate action. One issue that
> comes up in UNIX/BSD is the EINTR/EAGAIN error, that occurs when
> a system call is interrupted due to the handling of a signal. Now
> this could be handled at the O/S level differently in AdaOS, but it
> may not always be simple (i.e. do you proceed with the system call
> that is in progress, save its interrupted state, or back out the
> system call as UNIX often does - returining EINTR/EAGAIN?)

I thought that was fixed with BSD 4.2, over a decade ago.
 
-- 
David Starner - dstarner98@aasaa.ofe.org
Pointless website: http://dvdeug.dhis.org
"I don't care if Bill personally has my name and reads my email and 
laughs at me. In fact, I'd be rather honored." - Joseph_Greg



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Thoughts on the ADaOS user program interface
  2001-09-07 16:48 ` Warren W. Gay VE3WWG
  2001-09-07 19:35   ` David Starner
@ 2001-09-08 11:42   ` Florian Weimer
  1 sibling, 0 replies; 5+ messages in thread
From: Florian Weimer @ 2001-09-08 11:42 UTC (permalink / raw)


"Warren W. Gay VE3WWG" <ve3wwg@home.com> writes:

>> Error reporting should be done by throwing exceptions with a descriptive
>> error message attached.  My experience is that more often than not,
>> if a system call fails the program logic doesn't care why it fails.

> I have to disagree here. This may often be the case in some class of
> applications, but servers and other more system-level software _do_
> indeed care, and often must take appropriate action.

You can have the best of both worlds.  I call this "parameterized
exceptions": The exception message contains a machine-readable error
code at the beginning (which can be something converted to a
human-readable string, too), and exception handlers can retrieve this
kind of information easily.  As a side effect, throwing exceptions
becomes more expensive, but I think that this is not a problem.

I'm going to use this approach to get rid of thread-specific state
(and the alternative, a myriad of different exceptions) for my
low-level Ada binding for POSIX-like operating systems.

IMHO, the possibility to pass a value of a discrete type as a
parameter along with exceptions would be nice addition to the language
(passing values of any type creates too much problems).



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-09-08 11:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-06 18:18 Thoughts on the ADaOS user program interface Kenneth Almquist
2001-09-07  8:24 ` Dmitry Kazakov
2001-09-07 16:48 ` Warren W. Gay VE3WWG
2001-09-07 19:35   ` David Starner
2001-09-08 11:42   ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox