Newsgroups: comp.sys.amiga.programmer
From: dnavas@oracle.uucp (David Navas)
Subject: Re: IPC and shared memory
Organization: Oracle Corporation, Redwood Shores CA
Date: Fri, 8 Jan 1993 22:24:18 GMT
X-Disclaimer: This message was written by an unauthenticated user
              at Oracle Corporation.  The opinions expressed are those
              of the user and not necessarily those of Oracle.

In article <1iihaaINN7fv@swrinde.nde.swri.edu> kent@stanley.nde.swri.edu (Kent D. Polk) writes:
>In our case, a module master process which (as Dave described earlier)
>manages pretty much everything that the modules have in common.  Such
>activities are transparent to the modules unless the module needs to do
>something special with an attribute.  I.e. each module's simply defines a few
>attribute and method structures and then calls the DoShadow function.  Signal
>processing 'events' are managed via assigned processes. These processes run
>the designated module instances' functions in its own process space while the
>UI stuff, etc. is run in the module process space (I think :^)

Well....  Not quite ;)

Many of the module's methods actually do run in the traveller's process (for
those of you not savvy with WEB DA&A, the traveller is responsible for
traversing the data path as built by the user.  Typically, travellers
are sent to a 'source', data is attached to the traveller's message, and then
the traveller hops down the path, sending the message to each module.  However,
the message need not be sent to an IPCPort, a function address does just as
well -- hence the module method ends up running in the traveller's process).

So here is what really happens.  The module invokes a method on its own
process -- DoShadow(CurrentProcessObject(), NULL, METH_PROC_HANDLER, ....);
This method is actually located in the Module_Services program -- the
'server' in the discussion that Gregory has himself attached to.
It is responsible for the receiving of IPCMessages through the process'
IPCPorts.

Now let's say the user adds an element (where an element can be thought of as
an instance of the module under discussion, although this does not strictly
mean a new process is created -- in fact, so far it never means that).
Eventually, a traveller with a bunch of data arrives at the module's
data-function-manipulation-method.

If the method is defined as being INVOKE_CALL, then the method is invoked
under the traveller's process.  If the method is defined as INVOKE_SYNC,
then the method is invoked under the module's process (or whatever process
you stick into the mtag_procObject, but let's stick to the module's
that have been written thus far).  If we have the latter case, a message
is sent by the method  invocator (DSM()) to the module process.  Remember,
though, that the module process is -actually- executing code in the
Module_Services program!  The message is passed back into the shadow.library,
and the method gets called by shadow.library by ParseShadowMessage().

So you're partially right -- sometimes the traveller does handle data in its
own process.  Often, especially with more complex data manipulation functions
like play, filesave, etc., the method is run in the module's process.  The
former, however, does dramtically cut the overhead of the call
(no IPC/context switching involved).

[See below discussion about why GUI process != module process]

It's completely possible, of course, to create a totally new process to
handle the data-manipulation method, and with SHADOW V it's even easy to
get one module -program- to create several different processes where each
process defines a "module" to WEB.  [Now you understand why I'm holding
up documenting all of this -- I don't have sample code that does all of
these things yet!  :)]

>So, multiple instance issues (as in multiple instances of a game monster
>process), UI issues, configuration file loading and saving and lots more
>aren't even hinted at in the module source except for the attribute
>declarations.  Virtually all of the nasty and difficult ipc and
>process-handling issues that I struggled with before SHADOW pretty much
>disappeared. What was left was that I could concentrate on writing the real
>module software.

Let's take UI issues.  Under WEB DA&A, I receive an IPCMessage in my
module's process-context (within the Module_Services program, remember),
to open an element's parameter window.

This is converted into a SHADOW method to instantiate the module's
parameter window.  This method in turn sends a method to the GUI, requesting
a window, some gadgets, plus whatever else is necessary (after all, each
module create's a subclass, potentially adding new functionality to this
method -- more later).

Each module's class description has a pointer which is initialized to
point to the module's default gadget layout structure (this can be changed
on an element-by-element basis (where element = instance of module), but
this is never done in practice).  This structure informs the GUI (where the
GUI is a separate process from the Module_Services' process -and- the
module's process) where to place the gadgets, what the gadgets are, and what
state variables within the element that that gadget controls.  The window
is created, the gadgets layed out, and the window resized as appropriate.
The gadget's states are also updated from the state variables within the
element's instance data.

Let's take, as an example, a simple fileread module.  You would like to
be able to create a fileread which not only opens the parameter window, but
an ASL filerequester as well.  So, along with your usual data_method,
you create an EditParam_method (I forget what these methods are actually
called :().  The EditParam_method is the method that Module_Services calls
when it receives the request to open the parameter window.  The first thing
this method would do is to invoke its superclass' method using the
CallSuper() macro.  Once that returns, the window is verified as being opened
and the ASLObject is created (as necessary) and then opened.

What's interesting is that even though the METH_ASL_OPEN  is invoked like
any other method (DoShadow(aslObject, NULL, METH_ASL_OPEN, ....);), the
DSM() function actually -creates- a new, asynchronous process context for the
ASL filerequester, thus allowing asynchronous ASL behaviour and window
behaviour WITHOUT much fuss.  [There actually is some fuss because you
end up passing filename strings to this new process, and there's
actually another method which deals with the synchronous resource tracking
issues that this involves, but this is all within the gui.o file that's
linked into the Module_Services program, so it's at least twice removed
from consideration by module authors.]

We won't even get into the multi-level default filename/dirname code that
this approach allows us to use, except to say that there is a lot of
effort to assure users of the modules that directory access-defaults
update in a reasonable manner during program execution.

Of course, as all of these classes and instances are PUBLICALLY ACCESSIBLE,
there's no reason why Joe Shmoe can't write a program to traverse the class
list, and then traverse each class' instance list, and invoke the
parameter window method on EACH AND EVERY instance currently running in the
WEB, or patch all of the methods defined in each of the modules for use
in debugging, or many other things that can only be dreamt of at this
time.

Great opportunities for environment building, as far as I'm concerned.

>As far as I am concerned, this is THE easiest way to handle these types of
>issues (and others I won't go into here). And I know next to nothing about
>object-oriented programming much less SHADOWV! (did I get everything correct
>Dave?)

The paragraph, the article, or just that last sentence?  :) :) :)

Just kidding!  You hit it pretty close, although what's really nice to hear is
that it's UNNECESSARY to understand all of the intricacies (sp?) of the code
to actually use the interface.  First, because that's one of the objectives,
and second because documenting all of this is going to take some time, as you
can see!  500k of SHADOW docs are just the beginning as far as the WEB is
concerned ;)

Plus, I realize that you figure the only way you're going to get a decent
explanation of all of this is baiting me here  :)  You're right too, although
I have finally read and deleted the mid-October discussion about the
file layout issues you were concerned about ;)

>Yes, I was sampling stereo at 12.5 kHz, delaying the second channel by about
>500 samples, playing back the results in audio and plotting the waveforms AND
>writing the results to my Quantum 52MB drive throught the FFS filesystem (the
>one that came with my A3000) in realtime. (I can go up to about 17kHz if I
>turn off the waveform plotting and still write to disk in realtime.)

Was this on the A4000?  Just curious as to your hardware.  I don't have
a sampler to play with :(
BTB -- I'm bringing my Fujitsu 500M, I decided against the computer as well.
I expect to get some of those samples!

>a 12MB stereo sample). Didn't miss a detectable beat in the whole sample and
>quality was very impressive for an 8 bit sampler.  Once I had the file, many

Hey, that reminds me that I owe the net an article about bashing the audio
hardware correctly....  Seeing as how I do seem to have that module up
and running correctly ;)

>more realtime effects were possible as the system didn't have to be servicing
>that sampler interrupt every 80 us.

Eek!  What, I can't play missile-command in the background anymore?  :)

>Go for SHADOW V. It's fun!
>(Now how about that kickback Dave?)

Okay, okay, I'll REALLY try to change duration to frequency now --
unfortunately, at least on first pass, it's going to make calculations more
difficult, rather than easier (because the GTONE duration has to be
calculated using both the relative frequency differences AND the relative
length differences.  Sigh ;))

I hope this is actually useful to the topic at hand, as opposed to just a
long note to Kent [not that he hasn't gotten his fair share in the past] :)

David C. Navas						dnavas@oracle.com
Working for, but not speaking on behalf of, Oracle Corp.
Newsgroups: comp.sys.amiga.programmer