Multics Technical Bulletin                                MTB-749
IPC Async Channels

To:       Distribution

From:     Richard J.C.  Kissel

Date:     04/02/86

Subject:  A New IPC Channel Type:  The Async Call Channel

1 ABSTRACT

     A  new   type  of  IPC  event  channel   is  described,  the
asynchronous  event call  channel.   The  handlers for  these new
channels  can be  invoked whether  or not  the owning  process is
blocked.  A  new interface is  also described for  creating event
channels.

Comments should be sent to the author:

via Forum:
   >udd>m>rjck>mtgs>Multics_Networking (mnet).

via Multics Mail:
   Kissel.Multics on all systems

via telephone:
   (HVN) 492-9320 or (617) 492-9320

_________________________________________________________________

Multics  project  internal  working  documentation.   Not  to  be
reproduced or distributed outside the Multics project without the
consent of the author or the author's management.

Multics Technical Bulletin                                MTB-749
IPC Async Channels

2 INTRODUCTION

     This  MTB describes  a new  type of  IPC event  channel, the
asynchronous  event call channel.   A new interface  for creating
event channels is also described in Appendix A.

3 A PROBLEM WITH THE CURRENT IPC

     During  the implementation  of DSA  software on  Multics the
following   problem   arose    with   respect   to   interprocess
communication  (IPC).   A  Daemon  process  receives  input  data
destined for a  user process.  This data indicates  that the user
process  should take  some immediate  action.  For  instance, the
data might indicate that the user  has pressed the "break" key on
his terminal,  and therefore, "quit"  should be signalled  in the
user's process.  With current  IPC mechanisms, the Daemon process
can send  a wakeup to  the user's process.   However, this wakeup
will  be received only  when the user's  process is blocked  (has
called ipc_$block).   If the process  is wedged in  some way, and
the user is trying to make it stop with the "quit" signal, it may
not  go  blocked  at  a  convenient  time  (maybe it never blocks
because it is looping).

     A possible solution, in this particular case, is to give the
Daemon  access to  hphcs_ so  that it  could send  an IPS  "quit"
signal  directly to  the user's   process.  This  solution has  a
number of problems.  The Daemon must analyze the data it is going
to give to the user's process  to determine exactly what it means
(in  this  case  it  means  "quit",  but  it  might  mean  almost
anything).  We  would then need  an IPS signal  for each possible
meaning  of the  data (there   are only  35 possible  IPS signals
allowed),  and  a  handler  in  the  user's  process for each IPS
signal.  Finally, the Daemon needs access to hphcs_.

     What is  needed is a more general,  extensible mechanism for
asynchronously  signalling  a  user's  process  without having to
define new IPS signals and having to give out access to hphcs_ to
use them.

4 A SOLUTION

     The  proposed  solution  is  to  define  a  new  type of IPC
channel,  the   asynchronous  call  event  channel   (async  call
channel).   This channel  is just   like the  current call  event
channel  except that sending  a wakeup on  an async call  channel
(using hcs_$wakeup) sends an IPS "wkp_" signal to the destination
process as well as sending a normal IPC wakeup.

MTB-749                                Multics Technical Bulletin
                                               IPC Async Channels

     The IPS signal  causes the handler for the  "wkp_" signal to
be  invoked   in  the  destination  user's   process  immediately
(assuming the  "wkp_" signal is  not masked)), regardless  of the
process' state with  respect to IPC.  The handler  for the "wkp_"
IPS signal can then look through  the list of async call channels
and cause the  handlers (for any with pending IPC  wakeups) to be
run.

     This solution  allows the user  process to set  up IPC event
channels  with  handlers  for  any  sort  of  special  processing
required.  Only one IPS signal  is needed, the "wkp_" signal, and
no special access is needed by a process to send an IPC wakeup to
the user's process.

5 THE IMPLEMENTATION

     There are two key parts to the implementation.  The first is
the  IPS "wkp_"  signal.  As   it happens,  this signal  has been
defined  for   a  long  time   and  is  handled   by  default  by
wkp_signal_handler_,  which  currently  does  nothing.   This IPS
signal  was added  to perform  exactly the  function that  is now
being  proposed, although  the previous  implementation was never
completed.  The second key part  of the implementation is the use
of 3 bits  in the IPC channel name that  were introduced in MR11.
These bits are  currently unused, but they were  provided so that
event channel  names could be  given types.  In  this case, these
bits are used  to indicate whether the event channel  is a normal
event  channel (only  an IPC  wakeup is  to be  sent) or an async
event channel(both an IPC wakeup and  an IPS "wkp_" signal are to
be  sent).   Constant  values  for  these  bits  are  declared in
event_channel_name.incl.pl1.   It is   necessary to  indicate the
type of a channel in the name  because the name is the only piece
of data that  is shared between a process  which receives wakeups
on the  event channel and  the processes which  send the wakeups.
That is, at  the time a wakeup is sent,  the sending process does
not  have any good  way of finding  the receiving process'  Event
Channel  Table (ECT)  to determine  what type  of channel  it is.
Thus, this information must be encoded in the channel name.

     The  implementation  involves  the  following  changes.  The
program which actually sends wakeups, hc_ipc, must be modified to
decode the event channel name to find out what type of channel it
is.  If it is a normal channel, it sends an IPC wakeup as before.
If it  is an async  channel, it also  sends an IPS  "wkp_" signal
after sending the IPC wakeup.

     The  wkp_signal_handler_ is changed  to call a  new internal
entry  in ipc_,  run_event_calls  (see  Appendix B).   This entry
performs processing similar to that performed when the ipc_$block
entry is called.  That is, it looks for async call channels which

Multics Technical Bulletin                                MTB-749
IPC Async Channels

have pending wakeups and runs  their handlers.  In the ipc_$block
case,  the same  thing is   done for  normal call  channels.  One
difference is  that ipc_$run_event_calls only copies  out the ITT
once, while ipc_$block checks the ITT after each handler is runs.
The  effect of  this one  time copying  is that  there is  only a
finite  amount  of  work  to  be  done  by  any one invocation of
ipc_$run_event_calls,  and thus,  by wkp_signal_handler_  when it
handles  the IPS  "wkp_" signal.    In the  ipc_$block case,  the
process  can  spend  an  arbitrary  amount  of  time running call
handlers, depending on how other processes are sending wakeups to
it.

     On the calling side, a way is needed to create an async call
channel (see  the next section).  Otherwise,  async call channels
are  just  like  current  call  channels.   They  share  the same
priority numbering space, they can  be masked, they can be turned
into wait channels, etc.  They  cannot be turned into normal call
channels (i.e.  ones for which no IPS signal is sent) because the
fact that an IPS  signal is to be sent is encoded  in the name of
the channel, which  cannot be changed.  Also, this  means that if
an  async call  channel is  turned into  a wait  channel, the IPS
signal is  still sent, but is  a no-op because the  channel is no
longer  a call  channel (i.e.   the wkp_signal_handler_  will not
find it when it calls ipc_$run_event_calls).

6 A NEW INTERFACE FOR CREATING IPC CHANNELS

     Because the type of an event channel is to be encoded in its
name,  the current  two step  mechanism for  creating call  event
channels  cannot  be  used  for  async  call  channels.  With the
current   IPC,  an   event   channel   is  first   created  using
ipc_$create_ev_chn,  and then  it is  turned into  a call channel
using  ipc_$decl_event_call_chn.   At  the  time  the  channel is
created it  is not known that  it will be an  async call channel,
and  so the  correct type  bits cannot  be encoded  in its  name.
Another deficiency  of the current  interface is that  fast event
channels cannot be created with  ipc_, they must be created using
hcs_$assign_channel.   To  solve  the  problem,  and  improve the
current awkward interface, this MTB proposes to finally implement
ipc_$create_event_channel (a name we  have presumably been saving
until  we could  "get it  right").  Subroutine  documentation for
this entry can be found in Appendix A.



               Appendix A - ipc_$create_event_channel

     This  appendix gives  MPM  style  documentation for  the new
entry, create_event_channel, in ipc_.

04/02/86                       A-1                        MTB-749

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

Name: ipc_

     This  is   the  documentation  for  the   new  user  visible
entrypoint in ipc_.  It should be included in MPM Subroutines.

MTB-749                        A-2                       04/02/86

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

Entry: ipc_$create_event_channel

          This  entry creates an  event channel of  the specified
type with the specified parameters.  This entry should be used as
a  replacement  for:   hcs_$assign_channel  to  create fast event
channels,   the    ipc_$create_ev_chn,   ipc_$decl_event_call_chn
sequence to create normal call  channels.  This entry is the only
way to create an async event call channel.

Usage

     dcl ipc_$create_event_channel entry (ptr, fixed bin (71),
          fixed bin (35));

     call ipc_$create_event_channel (arg_ptr, channel_id, code);

where:

       arg_ptr                      (Input)
            is  a pointer  to ipc_create_arg_structure  described
            below.

       channel_id                   (Output)
            is the identifier of the event channel created.

       code                         (Output)
            is a standard system status code.

04/02/86                       A-3                        MTB-749

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

Notes

     The  following  structure  contains  the  arguments  to  the
create_event_channel entry.   All of the fields  of the structure
are  to be  filled in  on input.   The structure  is declared  in
ipc_create_arg.incl.pl1:

dcl  1 ipc_create_arg_structure      aligned
                      based (ipc_create_arg_structure_ptr),
       2 version                     char (8) unaligned,
       2 channel_type                fixed bin,
       2 call_entry                  variable entry (ptr),
       2 call_data_ptr               ptr,
       2 call_priority               fixed bin (17);

where:

       version                      (Input)
            is the version of the structure.  It should be set to
            the constant:  ipc_create_arg_structure_v1.

       channel_type                 (Input)
            is the type  of event channel that is  to be created.
            Constant  values  for  the   type  can  be  found  in
            event_channel_types.incl.pl1 as follows:

                   1  - FAST_EVENT_CHANNEL_TYPE
                   2  - WAIT_EVENT_CHANNEL_TYPE
                   3  - CALL_EVENT_CHANNEL_TYPE
                   4  - ASYNC_CALL_EVENT_CHANNEL_TYPE

       call_entry                   (Input)
            is  the procedure entry  point invoked when  an event
            occurs on the specified channel.

       call_data_ptr                (Input)
            is a pointer to data  to be passed to and interpreted
            by the procedure entry point.

       call_priority                (Input)
            is a number indicating the  priority of an event call
            channel  as  compared  to  other  event call channels
            declared  by this  process for  this ring.   If, upon
            interrogating   all   the   appropriate   event  call
            channels, more than one is  found to have received an
            event, the lowest-numbered priority is honored first,

MTB-749                        A-4                       04/02/86

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

            and  so   on.   Synchronous  and   asynchronous  call
            channels are the same with respect to this priority.

04/02/86                       A-5                        MTB-749

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

                  Appendix B - ipc_$run_event_calls

     This  appendix gives  PLM  style  documentation for  the new
internal entry, run_event_calls, in ipc_.

04/02/86                       B-1                        MTB-749

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

Name: ipc_

     This is the documentation for the new internal entrypoint in
ipc_.

MTB-749                        B-2                       04/02/86

____                                                         ____

ipc_                                                         ipc_
____                                                         ____

Entry: ipc_$run_event_calls

          This entry causes the handlers of any event channels of
the  specified  type  which  have  pending  wakeups  to be run in
priority order.

Usage

     dcl ipc_$run_event_calls entry (fixed bin, fixed bin (35));

     call ipc_$run_event_calls (channel_type, code);

where:

       channel_type                 (Input)
            is the type of the call event channels whose handlers
            should be run.  Constant values  for the types can be
            found in event_channel_types.incl.pl1 as follows:

                   3  - CALL_EVENT_CHANNEL_TYPE
                   4  - ASYNC_CALL_EVENT_CHANNEL_TYPE
                   10 - ANY_CALL_EVENT_CHANNEL_TYPE

       code                         (Output)
            is a standard system status code.

04/02/86                       B-3                        MTB-749