From: tom@flood.com (Tom Chatt)
Subject: Re: Ada multitasking with X-windows
Organization: The Flood Group, Inc.  Torrance, Ca.
Date: Fri, 10 Apr 92 02:03:31 GMT

kettering@addvax.llnl.gov (Brett 'Volleyball Is My Game' Kettering) writes:
| From Tom's message:
| 
| >Well, yes, it *is* that simple, *because* you would have a different version
| >of Xlib. You would be using some sort of Ada bindings to Xlib, and any
| >decent set of bindings would have to be doing quite a bit more than just
| >making sure the arguments pass correctly to the equivalent 'C' library
| >routines.
| 
| I guess we have a difference of interpretation as to what a binding is.  I
| interpret a binding to be something that allows me to call code, written
| in a foreign language (non Ada that is here), in my Ada program.  That means
| a spec with a bunch of "pragma IMPORT_VALUED_PROCEDURE", "pragma INTERFACE",
| etc.  What you describe is another implementation, according to my definition
| of implementation vs. binding.  I have only used the X implementations on
| DEC/VMS and the Sun SPARC.  I have only used Ada on the DEC/VMS platform
| with DEC's binding.  I know that if you call XNextEvent or XtAppMainLoop with
| DEC`s binding your process delays forever (well until another X event comes
| along) and does not allow the Ada RTS to take over and schedule another task
| because the process never gets back on the CPU.

Let's call this a "strict binding", a binding which is nothing more than
the bare minimum (pragma interface, or the like) to patch one compiler's
routine-calling and argument-passing mechanisms to the other. And let's
call what I was describing "nice binding", which is a layer of glue
that preserves the semantics of the foreign language package but at
times does some significant massaging inside the glue to make the
package conveniently useable in Ada. (I would note that a layer of
glue, even a significant amount of glue, is not the same thing as
a complete reimplementation.)

Strict bindings are close to useless for almost any non-trivial package.

On the simplest level, there is the matter of the different types
between C and Ada. In tons of C routines, things are tossed around
as char* and char**, using the convention of the null-terminated
string. Now you can just "punt" this system.address thing up to
the application (how rude!), or you can let it be arbitrarily
unchecked-converted to some pointer type (in which case you either
get garbage, or something that has to be massaged by the application
to be workable). Alternatively, you can provide some "glue" in
your binding which transparently massages the parameter into
something conveniently Ada-consumable. And this is just a fairly
trivial example of the type-matching problems you encounter in
order to create a "nice" binding. 

On the larger level, there is the matter of making the package work
*as a package*, the way that it was meant to work, while also not
disturbing the semantics of the way that Ada (including tasking)
is supposed to work. This may require some more significant glue,
so that the user of the package does not have to worry about such
problems as you are running into.

To make an analogy with translation between natural languages (say,
between Chinese and English), a "strict binding" would be like a
very literal word-for-word translation of some work of literature
without regard to its larger meaning. A "package binding" would be
something that would "translate" the overall meaning of the work
into the other language, while not always being a completely
literal translation. Which would you rather read?

It sounds to me like those DEC bindings you are using are a pretty
lousy "translation". I have heard there are better ones out there
(someone else has posted about his Ada bindings even allowing
multiple tasks in the same process to be doing X stuff -- now
*that* is *good* glue!). I have not been involved with this stuff
for quite a while, so I can't give you specific product names to
chase down. (In fact, when I was involved, nothing was available,
so I had to *write* the bindings. Sounds like mine were better
than DECs...)

| >And in an Ada binding to "XNextEvent", a similar
| >thing would occur. The Ada RTS is in some ways a mini-kernel. And,
| >as such, it must be "between" X and Unix, just as X must be between
| >the application and Unix.
| 
| The problem is that the X implementation in C does not talk to the Ada
| RTS to tell it that its task wants to "delay".  The binding only allows
| one to call the C implementation from an Ada program.
| 
| Like I said, to me the word binding does not imply recoding the function.
| To me that's an implementation.  I agree, if someone reimplements XNextEvent
| and thus XtAppMainLoop to not put the process to sleep then you could use
| tasks.

As I have said, I don't think that you have to completely reimplement
X in order to provide some decent bindings. You just have to make sure
that the Ada RTS gets in *between* X and Unix. Probably the best way
to do this would be to replace at least part of libc, such that when
you linked your program, the X calls to, e.g., select(2), would be
getting the Ada RTS version of select, and not the "real" Unix one
(at least not directly).

Doing it "right" would probably entail something like:

    application
    -------------
    X Ada bindings (massages data, then calls C routines)
    -------------
    libXt, libX, etc. (C routines, off the shelf from MIT or wherever)
    -------------
    Ada RTS libc emulations / real libc
    -------------
    Unix kernel

Not a reimplementation. Not a "strict binding". Rather, an Ada
package for X that allows its applications users to worry about
their own problems rather than those of the package. That's my
idea of a good binding.

-- 
Tom Chatt                        \   Don't take offense, take action.
Internet: tom@flood.com           \    Speak up. When we remain silent,
UUCP: ...!uunet!flood!tom        / \     we oppress ourselves.