Subversion Repositories HelenOS-doc

Rev

Rev 38 | Rev 99 | 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 it can distinguish the messages between different senders. Internally
  25.     the message contains pointer to the originating task and to the source of
  26.     the communication channel. If the message is forwarded, the originating
  27.     task identifies the recipient of the answer, the source channel identifies
  28.     connection in case of a hangup message.</para>
  29.  
  30.     <para>Every message must be eventually answered. The system keeps track of
  31.     all messages, so that it can answer them with appropriate error code
  32.     should one of the connection parties fail unexpectedly. To limit buffering
  33.     of messages in the kernel, every process is limited in a number of
  34.     asynchronous messages it may have unanswered simultanously. If the limit
  35.     is reached, the kernel refuses to send any other message, until some of
  36.     the active messages are answered.</para>
  37.  
  38.     <section>
  39.       <title>Low level IPC</title>
  40.  
  41.       <para>The whole IPC subsystem consists of one-way communication
  42.       channels. Each task has one associated message queue (answerbox). The
  43.       task can open connections (identified by phone id) to other tasks, send
  44.       and forward messages through these connections and answer received
  45.       messages. Every sent message is identified by a unique number, so that
  46.       the response can be later matched against it. The message is sent over
  47.       the phone to the target answerbox. Server application periodically
  48.       checks the answerbox and pulls messages from several queues associated
  49.       with it. After completing the requested action, server sends a reply
  50.       back to the answerbox of the originating task. </para>
  51.  
  52.       <para>If a need arises, it is possible to <emphasis>forward</emphasis> a
  53.       recevied message throught any of the open phones to another task. This
  54.       mechanism is used e.g. for opening new connections.</para>
  55.     </section>
  56.  
  57.     <section>
  58.       <title>Services for user application</title>
  59.  
  60.       <para>On top of this simple protocol the kernel provides special
  61.       services including opening new connection to other tasks, offering
  62.       callback connections and sending and receiving address space areas.
  63.       </para>
  64.     </section>
  65.   </section>
  66.  
  67.   <section>
  68.     <title>Userspace view</title>
  69.  
  70.     <para>The conventional design of the asynchronous api seems to produce
  71.     applications with one event loop and several big switch statements.
  72.     However, by intensive utilization of user-space threads, it was possible
  73.     to create an environment that is not necesarilly restricted to this type
  74.     of event-driven programming and allows for more fluent expression of
  75.     application programs. </para>
  76.  
  77.     <section>
  78.       <title>Single point of entry</title>
  79.  
  80.       <para>Each tasks is associated with only one answerbox. If a
  81.       multi-threaded application needs to communicate, it must be not only
  82.       able to send a message, but it should be able to retrieve the answer as
  83.       well. If several threads pull messages from task answerbox, it is a
  84.       matter of fortune, which thread receives which message. If a particular
  85.       thread needs to wait for a message answer, an idle
  86.       <emphasis>manager</emphasis> task is found or a new one is created and
  87.       control is transfered to this manager task. The manager tasks pops
  88.       messages from the answerbox and puts them into appropriate queues of
  89.       running tasks. If a task waiting for a message is not running, the
  90.       control is transferred to it. </para>
  91.  
  92.       <para>Very similar situation arises when a task decides to send a lot of
  93.       messages and reaches kernel limit of asynchronous messages. In such
  94.       situation 2 remedies are available - the userspace liberary can either
  95.       cache the message locally and resend the message when some answers
  96.       arrive, or it can block the thread and let it go on only after the
  97.       message is finally sent to the kernel layer. With one exception HelenOS
  98.       uses the second approach - when the kernel responds that maximum limit
  99.       of asynchronous messages was reached, control is transferred to manager
  100.       thread. The manager thread then handles incoming replies and when space
  101.       is available, sends the message to kernel and resumes application thread
  102.       execution.</para>
  103.  
  104.       <para>If a kernel notification is received, the servicing procedure is
  105.       run in the context of the manager thread. Although it wouldn't be
  106.      impossible to allow recursive calling, it could potentially lead to an
  107.      explosion of manager threads. Thus, the kernel notification procedures
  108.      are not allowed to wait for a message result, they can only answer
  109.      messages and send new ones without waiting for their results. If the
  110.      kernel limit for outgoing messages is reached, the data is automatically
  111.      cached within the application. This behaviour is enforced automatically
  112.      and the decision making is hidden from developers view.</para>
  113.    </section>
  114.  
  115.    <section>
  116.      <title>Synchronization problem</title>
  117.  
  118.      <para>Unfortunately, in the real world is is never so easy. E.g. if a
  119.      server handles incoming requests and as a part of it's response sends
  120.       asynchronous messages, it can be easily prempted and other thread may
  121.       start intervening. This can happen even if the application utilizes only
  122.       1 kernel thread. Classical synchronization using semaphores is not
  123.       possible, as locking on them would block the thread completely and the
  124.       answer couldn't be ever processed. The IPC framework allows a developer
  125.      to specify, that the thread should not be preempted to any other thread
  126.      (except notification handlers) while still being able to queue messages
  127.      belonging to other threads and regain control when the answer arrives.
  128.      </para>
  129.  
  130.      <para>This mechanism works transparently in multithreaded environment,
  131.      where classical locking mechanism (futexes) should be used. The IPC
  132.      framework ensures that there will always be enough free threads to
  133.      handle the threads requiring correct synchronization and allow the
  134.      application to run more user-space threads inside the kernel threads
  135.      without the danger of locking all kernel threads in futexes.</para>
  136.    </section>
  137.  
  138.    <section>
  139.      <title>The interface</title>
  140.  
  141.      <para></para>
  142.    </section>
  143.  </section>
  144. </chapter>