Subversion Repositories HelenOS-doc

Rev

Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 169 Rev 171
Line 15... Line 15...
15
  protocols.</para>
15
  protocols.</para>
16
 
16
 
17
  <section>
17
  <section>
18
    <title>Kernel Services</title>
18
    <title>Kernel Services</title>
19
 
19
 
20
    <para>Every message consists of four numeric arguments (32-bit and 64-bit on
20
    <para>Every message consists of four numeric arguments (32-bit and 64-bit
21
    the corresponding platforms), from which the first one is considered a
21
    on 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
22
    method number on message receipt and a return value on answer receipt. The
23
    received message contains identification of the incoming connection, so
23
    received message contains identification of the incoming connection, so
24
    that the receiving application can distinguish the messages between
24
    that the receiving application can distinguish the messages between
25
    different senders. Internally the message contains pointer to the
25
    different senders. Internally the message contains pointer to the
26
    originating task and to the source of the communication channel. If the
26
    originating task and to the source of the communication channel. If the
Line 99... Line 99...
99
        </mediaobject>
99
        </mediaobject>
100
      </figure>
100
      </figure>
101
 
101
 
102
      <para>The communication between task A, that is connected to task B
102
      <para>The communication between task A, that is connected to task B
103
      looks as follows: task A sends a message over its phone to the target
103
      looks as follows: task A sends a message over its phone to the target
104
      asnwerbox. The message is saved in task B's incoming call queue. When task
104
      asnwerbox. The message is saved in task B's incoming call queue. When
105
      B fetches the message for processing, it is automatically moved into the
105
      task B fetches the message for processing, it is automatically moved
106
      dispatched call queue. After the server decides to answer the message,
106
      into the dispatched call queue. After the server decides to answer the
107
      it is removed from dispatched queue and the result is moved into the
107
      message, it is removed from dispatched queue and the result is moved
108
      answer queue of task A.</para>
108
      into the answer queue of task A.</para>
109
 
109
 
110
      <para>The arguments contained in the message are completely arbitrary
110
      <para>The arguments contained in the message are completely arbitrary
111
      and decided by the user. The low level part of kernel IPC fills in
111
      and decided by the user. The low level part of kernel IPC fills in
112
      appropriate error codes if there is an error during communication. It is
112
      appropriate error codes if there is an error during communication. It is
113
      assured that the applications are correctly notified about communication
113
      assured that the applications are correctly notified about communication
Line 117... Line 117...
117
      are answered.</para>
117
      are answered.</para>
118
 
118
 
119
      <para>Closing an incoming connection is done by responding to any
119
      <para>Closing an incoming connection is done by responding to any
120
      incoming message with an EHANGUP error code. The connection is then
120
      incoming message with an EHANGUP error code. The connection is then
121
      immediately closed. The client connection identification (phone id) is
121
      immediately closed. The client connection identification (phone id) is
122
      not reused, until the client closes its own side of the
122
      not reused, until the client closes its own side of the connection
123
      connection ("hangs his phone up").</para>
123
      ("hangs his phone up").</para>
124
 
124
 
125
      <para>When a task dies (whether voluntarily or by being killed), cleanup
125
      <para>When a task dies (whether voluntarily or by being killed), cleanup
126
      process is started.</para>
126
      process is started.</para>
127
 
127
 
128
      <orderedlist>
128
      <orderedlist>
Line 155... Line 155...
155
      <title>System Call IPC Layer</title>
155
      <title>System Call IPC Layer</title>
156
 
156
 
157
      <para>On top of this simple protocol the kernel provides special
157
      <para>On top of this simple protocol the kernel provides special
158
      services closely related to the inter-process communication. A range of
158
      services closely related to the inter-process communication. A range of
159
      method numbers is allocated and protocol is defined for these functions.
159
      method numbers is allocated and protocol is defined for these functions.
160
      These messages are interpreted by the kernel layer and appropriate actions
160
      These messages are interpreted by the kernel layer and appropriate
161
      are taken depending on the parameters of the message and the answer.</para>
161
      actions are taken depending on the parameters of the message and the
-
 
162
      answer.</para>
162
 
163
 
163
      <para>The kernel provides the following services:</para>
164
      <para>The kernel provides the following services:</para>
164
 
165
 
165
      <itemizedlist>
166
      <itemizedlist>
166
        <listitem>
167
        <listitem>
Line 180... Line 181...
180
        </listitem>
181
        </listitem>
181
      </itemizedlist>
182
      </itemizedlist>
182
 
183
 
183
      <para>On startup, every task is automatically connected to a
184
      <para>On startup, every task is automatically connected to a
184
      <emphasis>naming service task</emphasis>, which provides a switchboard
185
      <emphasis>naming service task</emphasis>, which provides a switchboard
185
      functionality. In order to open a new outgoing connection, the client sends a
186
      functionality. In order to open a new outgoing connection, the client
186
      <constant>CONNECT_ME_TO</constant> message using any of his phones. If
187
      sends a <constant>CONNECT_ME_TO</constant> message using any of his
187
      the recepient of this message answers with an accepting answer, a new
188
      phones. If the recepient of this message answers with an accepting
188
      connection is created. In itself, this mechanism would allow only
189
      answer, a new connection is created. In itself, this mechanism would
189
      duplicating existing connection. However, if the message is forwarded,
190
      allow only duplicating existing connection. However, if the message is
190
      the new connection is made to the final recipient.</para>
191
      forwarded, the new connection is made to the final recipient.</para>
191
 
192
 
192
      <para>In order for a task to be able to forward a message, it
193
      <para>In order for a task to be able to forward a message, it must have
193
      must have a phone connected to the destination task.
194
      a phone connected to the destination task. The destination task
194
      The destination task establishes such connection by sending the <constant>CONNECT_TO_ME</constant>
195
      establishes such connection by sending the
195
      message to the forwarding task. A callback connection is opened afterwards.
196
      <constant>CONNECT_TO_ME</constant> message to the forwarding task. A
196
      Every service that wants to receive connections
197
      callback connection is opened afterwards. Every service that wants to
197
      has to ask the naming service to create the callback connection via this mechanism.</para>
198
      receive connections has to ask the naming service to create the callback
-
 
199
      connection via this mechanism.</para>
198
 
200
 
199
      <para>Tasks can share their address space areas using IPC messages. The
201
      <para>Tasks can share their address space areas using IPC messages. The
200
      two message types - <constant>AS_AREA_SEND</constant> and <constant>AS_AREA_RECV</constant> are used for sending and
202
      two message types - <constant>AS_AREA_SEND</constant> and
-
 
203
      <constant>AS_AREA_RECV</constant> are used for sending and receiving an
201
      receiving an address space area respectively. The shared area can be accessed
204
      address space area respectively. The shared area can be accessed as soon
202
      as soon as the message is acknowledged.</para>
205
      as the message is acknowledged.</para>
203
    </section>
206
    </section>
204
  </section>
207
  </section>
205
 
208
 
206
  <section>
209
  <section>
207
    <title>Userspace View</title>
210
    <title>Userspace View</title>
208
 
211
 
209
    <para>The conventional design of the asynchronous API seems to produce
212
    <para>The conventional design of the asynchronous API seems to produce
210
    applications with one event loop and several big switch statements.
213
    applications with one event loop and several big switch statements.
211
    However, by intensive utilization of userspace pseudo threads, it was possible
214
    However, by intensive utilization of userspace fibrils, it was possible to
212
    to create an environment that is not necessarily restricted to this type
215
    create an environment that is not necessarily restricted to this type of
213
    of event-driven programming and allows for more fluent expression of
216
    event-driven programming and allows for more fluent expression of
214
    application programs.</para>
217
    application programs.</para>
215
 
218
 
216
    <section>
219
    <section>
217
      <title>Single Point of Entry</title>
220
      <title>Single Point of Entry</title>
218
 
221
 
219
      <para>Each task is associated with only one answerbox. If a
222
      <para>Each task is associated with only one answerbox. If a
220
      multithreaded application needs to communicate, it must be not only
223
      multithreaded application needs to communicate, it must be not only able
221
      able to send a message, but it should be able to retrieve the answer as
224
      to send a message, but it should be able to retrieve the answer as well.
222
      well. If several pseudo threads pull messages from task answerbox, it is a
225
      If several fibrils pull messages from task answerbox, it is a matter of
223
      matter of coincidence, which thread receives which message. If a particular
226
      coincidence, which fibril receives which message. If a particular fibril
224
      thread needs to wait for a message answer, an idle
227
      needs to wait for a message answer, an idle <emphasis>manager</emphasis>
225
      <emphasis>manager</emphasis> pseudo thread is found or a new one is created and
228
      fibril is found or a new one is created and control is transfered to
226
      control is transfered to this manager thread. The manager threads pop
229
      this manager fibril. The manager fibrils pop messages from the answerbox
227
      messages from the answerbox and put them into appropriate queues of
230
      and put them into appropriate queues of running fibrils. If a fibril
228
      running threads. If a pseudo thread waiting for a message is not running, the
231
      waiting for a message is not running, the control is transferred to
229
      control is transferred to it.</para>
232
      it.</para>
230
 
233
 
231
      <figure float="1">
234
      <figure float="1">
232
        <title>Single point of entry</title>
235
        <title>Single point of entry</title>
-
 
236
 
233
        <mediaobject id="ipc2">
237
        <mediaobject id="ipc2">
234
          <imageobject role="pdf">
238
          <imageobject role="pdf">
235
            <imagedata fileref="images/ipc2.pdf" format="PDF" />
239
            <imagedata fileref="images/ipc2.pdf" format="PDF" />
236
          </imageobject>
240
          </imageobject>
237
 
241
 
Line 241... Line 245...
241
 
245
 
242
          <imageobject role="fop">
246
          <imageobject role="fop">
243
            <imagedata fileref="images/ipc2.svg" format="SVG" />
247
            <imagedata fileref="images/ipc2.svg" format="SVG" />
244
          </imageobject>
248
          </imageobject>
245
        </mediaobject>
249
        </mediaobject>
246
 
-
 
247
      </figure>
250
      </figure>
248
 
251
 
249
      <para>Very similar situation arises when a task decides to send a lot of
252
      <para>Very similar situation arises when a task decides to send a lot of
250
      messages and reaches the kernel limit of asynchronous messages. In such
253
      messages and reaches the kernel limit of asynchronous messages. In such
251
      situation, two remedies are available - the userspace library can either
254
      situation, two remedies are available - the userspace library can either
252
      cache the message locally and resend the message when some answers
255
      cache the message locally and resend the message when some answers
253
      arrive, or it can block the thread and let it go on only after the
256
      arrive, or it can block the fibril and let it go on only after the
254
      message is finally sent to the kernel layer. With one exception, HelenOS
257
      message is finally sent to the kernel layer. With one exception, HelenOS
255
      uses the second approach - when the kernel responds that the maximum limit
258
      uses the second approach - when the kernel responds that the maximum
256
      of asynchronous messages was reached, the control is transferred to a manager
259
      limit of asynchronous messages was reached, the control is transferred
257
      pseudo thread. The manager thread then handles incoming replies and, when space
260
      to a manager fibril. The manager fibril then handles incoming replies
258
      is available, sends the message to the kernel and resumes the application thread
261
      and, when space is available, sends the message to the kernel and
259
      execution.</para>
262
      resumes the application fibril execution.</para>
260
 
263
 
261
      <para>If a kernel notification is received, the servicing procedure is
264
      <para>If a kernel notification is received, the servicing procedure is
262
      run in the context of the manager pseudo thread. Although it wouldn't be
265
      run in the context of the manager fibril. Although it wouldn't be
263
      impossible to allow recursive calling, it could potentially lead to an
266
      impossible to allow recursive calling, it could potentially lead to an
264
      explosion of manager threads. Thus, the kernel notification procedures
267
      explosion of manager fibrils. Thus, the kernel notification procedures
265
      are not allowed to wait for a message result, they can only answer
268
      are not allowed to wait for a message result, they can only answer
266
      messages and send new ones without waiting for their results. If the
269
      messages and send new ones without waiting for their results. If the
267
      kernel limit for outgoing messages is reached, the data is automatically
270
      kernel limit for outgoing messages is reached, the data is automatically
268
      cached within the application. This behaviour is enforced automatically
271
      cached within the application. This behaviour is enforced automatically
269
      and the decision making is hidden from the developer.</para>
272
      and the decision making is hidden from the developer.</para>
270
 
273
 
271
      <figure float="1">
274
      <figure float="1">
272
        <title>Single point of entry solution</title>
275
        <title>Single point of entry solution</title>
-
 
276
 
273
        <mediaobject id="ipc3">
277
        <mediaobject id="ipc3">
274
          <imageobject role="pdf">
278
          <imageobject role="pdf">
275
            <imagedata fileref="images/ipc3.pdf" format="PDF" />
279
            <imagedata fileref="images/ipc3.pdf" format="PDF" />
276
          </imageobject>
280
          </imageobject>
277
 
281
 
Line 281... Line 285...
281
 
285
 
282
          <imageobject role="fop">
286
          <imageobject role="fop">
283
            <imagedata fileref="images/ipc3.svg" format="SVG" />
287
            <imagedata fileref="images/ipc3.svg" format="SVG" />
284
          </imageobject>
288
          </imageobject>
285
        </mediaobject>
289
        </mediaobject>
286
 
-
 
287
      </figure>
290
      </figure>
288
    </section>
291
    </section>
289
 
292
 
290
    <section>
293
    <section>
291
      <title>Ordering Problem</title>
294
      <title>Ordering Problem</title>
Line 296... Line 299...
296
      start intervening. This can happen even if the application utilizes only
299
      start intervening. This can happen even if the application utilizes only
297
      one userspace thread. Classical synchronization using semaphores is not
300
      one userspace thread. Classical synchronization using semaphores is not
298
      possible as locking on them would block the thread completely so that
301
      possible as locking on them would block the thread completely so that
299
      the answer couldn't be ever processed. The IPC framework allows a
302
      the answer couldn't be ever processed. The IPC framework allows a
300
      developer to specify, that part of the code should not be preempted by
303
      developer to specify, that part of the code should not be preempted by
301
      any other pseudo thread (except notification handlers) while still being able
304
      any other fibril (except notification handlers) while still being able
302
      to queue messages belonging to other pseudo threads and regain control when the
305
      to queue messages belonging to other fibrils and regain control when the
303
      answer arrives.</para>
306
      answer arrives.</para>
304
 
307
 
305
      <para>This mechanism works transparently in multithreaded environment,
308
      <para>This mechanism works transparently in multithreaded environment,
306
      where additional locking mechanism (futexes) should be used. The IPC
309
      where additional locking mechanism (futexes) should be used. The IPC
307
      framework ensures that there will always be enough free userspace threads
310
      framework ensures that there will always be enough free userspace
308
      to handle incoming answers and allow the application to run more
311
      threads to handle incoming answers and allow the application to run more
309
      pseudo threads inside the usrspace threads without the danger of
312
      fibrils inside the userspace threads without the danger of locking all
310
      locking all userspace threads in futexes.</para>
313
      userspace threads in futexes.</para>
311
    </section>
314
    </section>
312
 
315
 
313
    <section>
316
    <section>
314
      <title>The Interface</title>
317
      <title>The Interface</title>
315
 
318
 
Line 319... Line 322...
319
      the kernel limit, the flow of application is stopped until some answers
322
      the kernel limit, the flow of application is stopped until some answers
320
      arrive. On the other hand, server applications are expected to work in a
323
      arrive. On the other hand, server applications are expected to work in a
321
      multithreaded environment.</para>
324
      multithreaded environment.</para>
322
 
325
 
323
      <para>The server interface requires the developer to specify a
326
      <para>The server interface requires the developer to specify a
324
      <function>connection_thread</function> function. When new connection is
327
      <function>connection_fibril</function> function. When new connection is
325
      detected, a new pseudo thread is automatically created and control is
328
      detected, a new fibril is automatically created and control is
326
      transferred to this function. The code then decides whether to accept
329
      transferred to this function. The code then decides whether to accept
327
      the connection and creates a normal event loop. The userspace IPC
330
      the connection and creates a normal event loop. The userspace IPC
328
      library ensures correct switching between several pseudo threads
331
      library ensures correct switching between several threads within the
329
      within the kernel environment.</para>
332
      kernel environment.</para>
330
    </section>
333
    </section>
331
  </section>
334
  </section>
332
</chapter>
335
</chapter>
333
336