Subversion Repositories HelenOS-doc

Rev

Rev 85 | Rev 112 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <chapter id="ipc">
  3.   <?dbhtml filename="ipc.html"?>
  4.  
  5.   <title>IPC</title>
  6.  
  7.   <para>Due to the high intertask communication traffic, IPC becomes critical
  8.   subsystem for microkernels, putting high demands on the speed, latency and
  9.   reliability of IPC model and implementation. Although theoretically the use
  10.   of asynchronous messaging system looks promising, it is not often
  11.   implemented because of a problematic implementation of end user
  12.   applications. HelenOS implements a fully asynchronous messaging system but
  13.   with a special layer providing a user application developer a reasonably
  14.   synchronous multithreaded environment sufficient to develop complex
  15.   protocols.</para>
  16.  
  17.   <section>
  18.     <title>Services provided by kernel</title>
  19.  
  20.     <para>Every message consists of 4 numeric arguments (32-bit and 64-bit on
  21.     the corresponding platforms), from which the first one is considered a
  22.     method number on message receipt and a return value on answer receipt. The
  23.     received message contains identification of the incoming connection, so
  24.     that the receiving application can distinguish the messages between
  25.     different senders. Internally the message contains pointer to the
  26.     originating task and to the source of the communication channel. If the
  27.     message is forwarded, the originating task identifies the recipient of the
  28.     answer, the source channel identifies the connection in case of a hangup
  29.     response.</para>
  30.  
  31.     <para>Every message must be eventually answered. The system keeps track of
  32.     all messages, so that it can answer them with appropriate error code
  33.     should one of the connection parties fail unexpectedly. To limit buffering
  34.     of the messages in the kernel, every process is has a limited account of
  35.     asynchronous messages it can send simultanously. If the limit is reached,
  36.     the kernel refuses to send any other message, until some active message is
  37.     answered.</para>
  38.  
  39.     <para>To facilitate kernel-to-user communication, the IPC subsystem
  40.     provides notification messages. The applications can subscribe to a
  41.     notification channel and receive messages directed to this channel. Such
  42.     messages can be freely sent even from interrupt context as they are
  43.     primarily destined to deliver IRQ events to userspace device drivers.
  44.     These messages need not be answered, there is no party that could receive
  45.     such response.</para>
  46.  
  47.     <section>
  48.       <title>Low level IPC</title>
  49.  
  50.       <para>The whole IPC subsystem consists of one-way communication
  51.       channels. Each task has one associated message queue (answerbox). The
  52.       task can open connections (identified by phone id) to other tasks, send
  53.       and forward messages through these connections and answer received
  54.       messages. Every sent message is identified by a unique number, so that
  55.       the response can be later matched against it. The message is sent over
  56.       the phone to the target answerbox. Server application periodically
  57.       checks the answerbox and pulls messages from several queues associated
  58.       with it. After completing the requested action, server sends a reply
  59.       back to the answerbox of the originating task. If a need arises, it is
  60.       possible to <emphasis>forward</emphasis> a recevied message throught any
  61.       of the open phones to another task. This mechanism is used e.g. for
  62.       opening new connections.</para>
  63.  
  64.       <para>The arguments contained in the message are completely arbitrary
  65.       and decided by the user. The low level part of kernel IPC fills in
  66.       appropriate error codes if there is an error during communication. It is
  67.       ensured that the applications are correctly notified about communication
  68.       state. If the outgoing connection is closed with the hangup message, the
  69.       target answerbox receives a hangup message. The connection
  70.       identification is not reused, until the hangup message is acknowledged
  71.       and all other pending messages are answered.</para>
  72.  
  73.       <para>If the server side decides to hangup an incoming connection, it
  74.       does it by responding to any incoming message with an EHANGUP error
  75.       code. The connection is then immediately closed. The client connection
  76.       identification (phone id) is not reused, until the client issues hangup
  77.       system call to close the outgoing connection.</para>
  78.  
  79.       <para>When a task dies (whether voluntarily or by being killes), cleanup
  80.       process is started which performs following tasks.</para>
  81.  
  82.       <orderedlist>
  83.         <listitem>
  84.           <para>Hangs up all outgoing connections and sends hangup messages to
  85.           all target answerboxes.</para>
  86.         </listitem>
  87.  
  88.         <listitem>
  89.           <para>Disconnects all incoming connections.</para>
  90.         </listitem>
  91.  
  92.         <listitem>
  93.           <para>Disconnects from all notification channels.</para>
  94.         </listitem>
  95.  
  96.         <listitem>
  97.           <para>Answers all unanswered messages from answerbox queues with
  98.           appropriate error code.</para>
  99.         </listitem>
  100.  
  101.         <listitem>
  102.           <para>Waits until all outgoing messages are answered and all
  103.           remaining answerbox queues are empty.</para>
  104.         </listitem>
  105.       </orderedlist>
  106.     </section>
  107.  
  108.     <section>
  109.       <title>System call IPC layer</title>
  110.  
  111.       <para>On top of this simple protocol the kernel provides special
  112.       services closely related to the inter-process communication. A range of
  113.       method numbers is allocated and protocol is defined for these functions.
  114.       The messages are interpreted by the kernel layer and appropriate actions
  115.       are taken depending on the parameters of message and answer. </para>
  116.  
  117.       <para>The kernel provides the following services:</para>
  118.  
  119.       <itemizedlist>
  120.         <listitem>
  121.           <para>Creating new outgoing connection</para>
  122.         </listitem>
  123.  
  124.         <listitem>
  125.           <para>Creating a callback connection</para>
  126.         </listitem>
  127.  
  128.         <listitem>
  129.           <para>Sending an address space area</para>
  130.         </listitem>
  131.  
  132.         <listitem>
  133.           <para>Asking for an address space area</para>
  134.         </listitem>
  135.       </itemizedlist>
  136.     </section>
  137.   </section>
  138.  
  139.   <section>
  140.     <title>Userspace view</title>
  141.  
  142.     <para>The conventional design of the asynchronous api seems to produce
  143.     applications with one event loop and several big switch statements.
  144.     However, by intensive utilization of user-space threads, it was possible
  145.     to create an environment that is not necesarilly restricted to this type
  146.     of event-driven programming and allows for more fluent expression of
  147.     application programs.</para>
  148.  
  149.     <section>
  150.       <title>Single point of entry</title>
  151.  
  152.       <para>Each tasks is associated with only one answerbox. If a
  153.       multi-threaded application needs to communicate, it must be not only
  154.       able to send a message, but it should be able to retrieve the answer as
  155.       well. If several threads pull messages from task answerbox, it is a
  156.       matter of fortune, which thread receives which message. If a particular
  157.       thread needs to wait for a message answer, an idle
  158.       <emphasis>manager</emphasis> task is found or a new one is created and
  159.       control is transfered to this manager task. The manager tasks pops
  160.       messages from the answerbox and puts them into appropriate queues of
  161.       running tasks. If a task waiting for a message is not running, the
  162.       control is transferred to it.</para>
  163.  
  164.       <para>Very similar situation arises when a task decides to send a lot of
  165.       messages and reaches kernel limit of asynchronous messages. In such
  166.       situation 2 remedies are available - the userspace liberary can either
  167.       cache the message locally and resend the message when some answers
  168.       arrive, or it can block the thread and let it go on only after the
  169.       message is finally sent to the kernel layer. With one exception HelenOS
  170.       uses the second approach - when the kernel responds that maximum limit
  171.       of asynchronous messages was reached, control is transferred to manager
  172.       thread. The manager thread then handles incoming replies and when space
  173.       is available, sends the message to kernel and resumes application thread
  174.       execution.</para>
  175.  
  176.       <para>If a kernel notification is received, the servicing procedure is
  177.       run in the context of the manager thread. Although it wouldn't be
  178.      impossible to allow recursive calling, it could potentially lead to an
  179.      explosion of manager threads. Thus, the kernel notification procedures
  180.      are not allowed to wait for a message result, they can only answer
  181.      messages and send new ones without waiting for their results. If the
  182.      kernel limit for outgoing messages is reached, the data is automatically
  183.      cached within the application. This behaviour is enforced automatically
  184.      and the decision making is hidden from developers view.</para>
  185.    </section>
  186.  
  187.    <section>
  188.      <title>Synchronization problem</title>
  189.  
  190.      <para>Unfortunately, in the real world is is never so easy. E.g. if a
  191.      server handles incoming requests and as a part of it's response sends
  192.       asynchronous messages, it can be easily prempted and other thread may
  193.       start intervening. This can happen even if the application utilizes only
  194.       1 kernel thread. Classical synchronization using semaphores is not
  195.       possible, as locking on them would block the thread completely and the
  196.       answer couldn't be ever processed. The IPC framework allows a developer
  197.      to specify, that the thread should not be preempted to any other thread
  198.      (except notification handlers) while still being able to queue messages
  199.      belonging to other threads and regain control when the answer
  200.      arrives.</para>
  201.  
  202.      <para>This mechanism works transparently in multithreaded environment,
  203.      where classical locking mechanism (futexes) should be used. The IPC
  204.      framework ensures that there will always be enough free threads to
  205.      handle the threads requiring correct synchronization and allow the
  206.      application to run more user-space threads inside the kernel threads
  207.      without the danger of locking all kernel threads in futexes.</para>
  208.    </section>
  209.  
  210.    <section>
  211.      <title>The interface</title>
  212.  
  213.      <para></para>
  214.    </section>
  215.  </section>
  216. </chapter>