Subversion Repositories HelenOS-doc

Rev

Rev 38 | Rev 99 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9 bondari 1
<?xml version="1.0" encoding="UTF-8"?>
85 palkovsky 2
<chapter id="ipc">
3
  <?dbhtml filename="ipc.html"?>
9 bondari 4
 
85 palkovsky 5
  <title>IPC</title>
9 bondari 6
 
85 palkovsky 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>
38 bondari 16
 
85 palkovsky 17
  <section>
18
    <title>Services provided by kernel</title>
9 bondari 19
 
85 palkovsky 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>