7aab32b158e1db3daf3cd24e50618d2c8de904d7
[dragonfly.git] / share / man / man9 / msgport.9
1 .\"
2 .\" Copyright (c) 2012 The DragonFly Project.  All rights reserved.
3 .\"
4 .\" This code is derived from software contributed to The DragonFly Project
5 .\" by Nuno Antunes <nuno.antunes@gmail.com>.
6 .\"
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
9 .\" are met:
10 .\"
11 .\" 1. Redistributions of source code must retain the above copyright
12 .\"    notice, this list of conditions and the following disclaimer.
13 .\" 2. Redistributions in binary form must reproduce the above copyright
14 .\"    notice, this list of conditions and the following disclaimer in
15 .\"    the documentation and/or other materials provided with the
16 .\"    distribution.
17 .\" 3. Neither the name of The DragonFly Project nor the names of its
18 .\"    contributors may be used to endorse or promote products derived
19 .\"    from this software without specific, prior written permission.
20 .\"
21 .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 .\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25 .\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 .\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 .\" SUCH DAMAGE.
33 .\"
34 .Dd August 12, 2012
35 .Dt MSGPORT 9
36 .Os
37 .Sh NAME
38 .Nm lwkt_initport_thread ,
39 .Nm lwkt_initport_spin ,
40 .Nm lwkt_initport_serialize ,
41 .Nm lwkt_initport_panic ,
42 .Nm lwkt_initport_replyonly_null ,
43 .Nm lwkt_initport_replyonly ,
44 .Nm lwkt_initport_putonly ,
45 .Nm lwkt_sendmsg ,
46 .Nm lwkt_domsg ,
47 .Nm lwkt_forwardmsg ,
48 .Nm lwkt_abortmsg ,
49 .Nm lwkt_initmsg ,
50 .Nm lwkt_initmsg_abortable ,
51 .Nm lwkt_beginmsg ,
52 .Nm lwkt_replymsg ,
53 .Nm lwkt_getport ,
54 .Nm lwkt_waitport ,
55 .Nm lwkt_waitmsg ,
56 .Nm lwkt_checkmsg ,
57 .Nm lwkt_dropmsg
58 .Nd LWKT message passing interface
59 .Sh SYNOPSIS
60 .In sys/msgport.h
61 .Ft void
62 .Fn lwkt_initport_thread "lwkt_port_t port" "struct thread *td"
63 .Ft void
64 .Fn lwkt_initport_spin "lwkt_port_t port"
65 .Ft void
66 .Fn lwkt_initport_serialize "lwkt_port_t port" "struct lwkt_serialize *slz"
67 .Ft void
68 .Fn lwkt_initport_panic "lwkt_port_t port"
69 .Ft void
70 .Fn lwkt_initport_replyonly_null "lwkt_port_t port"
71 .Ft void
72 .Fn lwkt_initport_replyonly "lwkt_port_t port" "void (*rportfn)(lwkt_port_t, lwkt_msg_t)"
73 .Ft void
74 .Fn lwkt_initport_putonly "lwkt_port_t port" "int (*pportfn)(lwkt_port_t, lwkt_msg_t)"
75 .Ft void
76 .Fn lwkt_sendmsg "lwkt_port_t port" "lwkt_msg_t msg"
77 .Ft int
78 .Fn lwkt_domsg "lwkt_port_t port" "lwkt_msg_t msg" "int flags"
79 .Ft int
80 .Fn lwkt_forwardmsg "lwkt_port_t port" "lwkt_msg_t msg"
81 .Ft void
82 .Fn lwkt_abortmsg "lwkt_msg_t msg"
83 .In sys/msgport2.h
84 .Ft void
85 .Fn lwkt_initmsg "lwkt_msg_t msg" "lwkt_port_t rport" "int flags"
86 .Ft void
87 .Fn lwkt_initmsg_abortable "lwkt_msg_t msg" "lwkt_port_t rport" "int flags" "void (*abortfn)(lwkt_msg_t)"
88 .Ft int
89 .Fn lwkt_beginmsg "lwkt_port_t port" "lwkt_msg_t msg"
90 .Ft void
91 .Fn lwkt_replymsg "lwkt_msg_t msg" "int error"
92 .Ft void *
93 .Fn lwkt_getport "lwkt_port_t port"
94 .Ft void *
95 .Fn lwkt_waitport "lwkt_port_t port" "int flags"
96 .Ft int
97 .Fn lwkt_waitmsg "lwkt_msg_t msg" "int flags"
98 .Ft int
99 .Fn lwkt_checkmsg "lwkt_msg_t msg"
100 .Ft void
101 .Fn lwkt_dropmsg "lwkt_msg_t msg"
102 .Sh DESCRIPTION
103 Light weight kernel threads in
104 .Dx
105 may use a message passing interface to communicate with each other.
106 Messages are sent to message ports.
107 All light weight kernel threads have a built-in message port, but you may create
108 additional ports if necessary.
109 The following types of message ports are available:
110 .Bl -bullet
111 .It
112 thread ports
113 .It
114 spin ports
115 .It
116 serializer ports
117 .El
118 .Pp
119 Ports of type 'thread' are owned by a single light weight kernel thread.
120 When a message is sent to a port of type 'thread', only the owner of that port
121 is allowed to retrieve the message from it.
122 When a message is sent to a port of type 'spin' or to a port of
123 type 'serializer', multiple threads are allowed to check that port for new
124 messages and compete to retrieve them.
125 You define the port type when you initialize the port.
126 By default, the built-in port of every light weight kernel thread is
127 automatically initialized to type 'thread'.
128 .Pp
129 When a message is sent, the receiver should normally send back a reply.
130 The reply is sent to the reply port that is registered on the original message.
131 Messages can be replied to synchronously or asynchronously.
132 The sender may request a synchronous or asynchronous reply to the message,
133 however the target port will ultimately decide how the message will be treated.
134 .Sh MESSAGE FUNCTIONS
135 Messages must be initialized before being used.
136 The
137 .Fn lwkt_initmsg
138 function initializes a message.
139 The
140 .Fa rport
141 argument identifies the reply port which will be used for asynchronous replies.
142 The
143 .Fa flags
144 argument sets any required flags for this message.
145 Flags passed this way will simply be or'ed to any already existing flags on the
146 message.
147 .Pp
148 The
149 .Fn lwkt_initmsg_abortable
150 function is similar to
151 .Fn lwkt_initmsg
152 but it takes an additional parameter
153 .Fa abortfn
154 which defines the abort function for this message.
155 .Pp
156 The
157 .Fn lwkt_sendmsg
158 function requests an asynchronous reply, sends the message and returns
159 immediately.
160 Under normal circumstances, users of this function may always expect the reply
161 to be queued to the reply port registered on the message.
162 The
163 .Fa port
164 argument defines the target port to which the
165 .Fa msg
166 message will be sent to.
167 .Pp
168 The
169 .Fn lwkt_domsg
170 function requests a synchronous reply, sends the message and does not return
171 until the message has been replied to.
172 If the target port supports synchronous reply, this function will return that
173 reply immediately.
174 If not, and this is the most common case, this function will block and wait for the
175 reply to arrive and then return it.
176 The
177 .Fa port
178 argument defines the target port to which the
179 .Fa msg
180 message will be sent to.
181 .Pp
182 The
183 .Fn lwkt_replymsg
184 function replies to a message that was processed asynchronously by the target
185 port.
186 This function is used by the thread on the receiving side.
187 The
188 .Fa msg
189 argument is the message being replied to and the
190 .Fa error
191 argument is the actual response to send back.
192 .Pp
193 The
194 .Fn lwkt_forwardmsg
195 simply forwards a message to another port.
196 The
197 .Fa port
198 argument defines the target port to which the
199 .Fa msg
200 message will be sent to.
201 .Pp
202 If a message has been initialized as abortable, you can use the
203 .Fn lwkt_abortmsg
204 function to try to abort it.
205 The
206 .Fa abortfn
207 passed upon the initialisation with
208 .Fn lwkt_initmsg_abortable
209 will be called by this function.
210 .Pp
211 The
212 .Fn lwkt_dropmsg
213 will dequeue the specified message from the target port it was sent to and makes
214 it look like it was never sent.
215 .Sh PORT FUNCTIONS
216 The
217 .Fn lwkt_initport_thread
218 initializes the specified
219 .Fa port
220 with the default 'thread' port type handlers.
221 The
222 .Fa td
223 argument defines the owner thread of the port and only that thread is allowed to
224 receive messages on it.
225 .Pp
226 The
227 .Fn lwkt_initport_spin
228 initializes the specified
229 .Fa port
230 with the default 'spin' port type handlers.
231 It will also initialize the embedded spinlock within the
232 lwkt_port structure which will protect subsequent port access.
233 .Pp
234 The
235 .Fn lwkt_initport_serialize
236 function initializes the specified
237 .Fa port
238 with the default 'serializer' port type handlers.
239 The subsequent port access will be protected by the passed
240 .Fa slz
241 serializer lock.
242 .Pp
243 The
244 .Fn lwkt_getport
245 function checks the specified
246 .Fa port
247 for available messages, dequeues the first one and returns it.
248 If no messages are available then
249 .Dv NULL
250 is returned instead.
251 This function is used by threads on the receiving side.
252 .Pp
253 The
254 .Fn lwkt_waitport
255 function checks the specified
256 .Fa port
257 for available messages, dequeues the first one and returns it.
258 If no messages are available then the caller thread will sleep until a message
259 arrives on the specified port.
260 The
261 .Fa flags
262 argument defines the flags used for the sleep.
263 This function is used by threads on the receiving side.
264 .Sh SPECIAL PORT INITIALIZERS
265 The
266 .Fn lwkt_initport_replyonly
267 function initializes a
268 .Fa port
269 which is used only as reply port and may have a custom reply port handler.
270 The reply port handler is specified with the
271 .Fa rportfn
272 argument.
273 All the other handlers will panic the system if they are called.
274 This initializer is normally used on ports for freeing resources after the
275 messages have fulfilled their purpose.
276 .Pp
277 The
278 .Fn lwkt_initport_replyonly_null
279 function initializes a
280 .Fa port
281 which is used only as reply port.
282 The reply port handler will simply mark the message as being done and will not
283 attempt to queue it.
284 All the other handlers will panic the system if they are called.
285 .Pp
286 The
287 .Fn lwkt_initport_putonly
288 function initializes a
289 .Fa port
290 which is used only as target port.
291 The putport handler is specified with the
292 .Fa pportfn
293 argument.
294 All the other handlers will panic the system if they are called.
295 .Pp
296 The
297 .Fn lwkt_initport_panic
298 function initializes a
299 .Fa port
300 which will panic the system if any of its handlers are called.
301 This function is sometimes used to initialize a reply-only port which does not
302 expect the messages to be replied to, e.g.\& when the messages should be
303 consumed by the receiving thread and never replied back.
304 .Sh INTERNAL MESSAGE FUNCTIONS
305 The following functions are used only by the infrastructure, you should not
306 need to use them directly unless in very rare cases.
307 .Pp
308 The
309 .Fn lwkt_beginmsg
310 function simply calls the target port's putport handler.
311 This function is only called by the
312 .Fn lwkt_sendmsg
313 and
314 .Fn lwkt_replymsg
315 functions.
316 The putport handler returns
317 .Er EASYNC
318 for messages processed asynchronously or any other value for messages processed
319 synchronously.
320 That return value of the putport handler is propagated by this function.
321 The
322 .Fa port
323 argument defines the target port to which the
324 .Fa msg
325 message will be sent to.
326 .Pp
327 The
328 .Fn lwkt_waitmsg
329 function puts the caller to sleep until the specified
330 .Fa msg
331 message has been replied to.
332 The
333 .Fa flags
334 argument defines the flags used for the sleep.
335 .Sh FILES
336 The LWKT msgport implementation resides in
337 .Pa sys/kern/lwkt_msgport.c .
338 .Sh EXAMPLES
339 .Bd -literal
340 /*
341  * Example 1: per CPU threads.
342  *
343  */
344
345 #include <sys/thread.h>
346 #include <sys/msgport.h>
347 #include <sys/msgport2.h>
348
349 static void my_service_loop(void *dummy);
350 lwkt_port_t my_service_portfn(int cpu);
351 void my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
352 int my_service_domsg(lwkt_msg_t lmsg, int cpu);
353
354 /* Array of per-CPU target ports */
355 struct lwkt_port *my_service_ports[MAXCPU];
356
357 /*
358  * Create per-cpu threads for handling msg processing.  Remember that built-in
359  * lwkt ports are automatically initialized to type 'thread' so we don't need
360  * to initialize them explicitly.
361  */
362 static void
363 my_per_cpu_service_init(void)
364 {
365         int i;
366         thread_t td;
367
368         for (i = 0; i < ncpus; ++i) {
369                 lwkt_create(my_service_loop, NULL, &td,
370                             NULL, 0, i, "myservice_cpu %d", i);
371                 my_service_ports[i] = &td->td_msgport;
372         }
373 }
374
375 /*
376  * This is the routine executed by the service threads on each CPU.
377  */
378 static void
379 my_service_loop(void *dummy __unused)
380 {
381         lwkt_msg_t msg;
382         thread_t td = curthread;
383         int cpu = curthread->td_gd->gd_cpuid;
384
385         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
386                 /* Do some work in the receiver thread context. */
387                 kprintf("Received message on CPU %d.\en", cpu);
388
389                 /* And finally reply to the message. */
390                 lwkt_replymsg(msg, 0);
391         }
392 }
393
394 /*
395  * Given a CPU id, return our respective service port.
396  */
397 __inline lwkt_port_t
398 my_service_portfn(int cpu)
399 {
400         return my_service_ports[cpu];
401 }
402
403 /*
404  * Send an asynchronous message to the service thread on a specific CPU.
405  */
406 void
407 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
408 {
409         KKASSERT(cpu < ncpus);
410         lwkt_sendmsg(my_service_portfn(cpu), lmsg);
411 }
412
413 /*
414  * Send a synchronous message to the service thread on a specific CPU.
415  */
416 int
417 my_service_domsg(lwkt_msg_t lmsg, int cpu)
418 {
419         KKASSERT(cpu < ncpus);
420         return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
421 }
422
423 /*
424  * Example use case. Initialize the service threads and send each one a
425  * message.
426  */
427 static void
428 mod_load(void)
429 {
430         lwkt_msg        lmsg;
431         lwkt_port_t     builtin_port = &curthread->td_msgport;
432         int             i;
433
434         my_per_cpu_service_init();
435         for (i=0; i<ncpus; ++i) {
436                 kprintf("Sending msg to CPU %d.\en", i);
437                 lwkt_initmsg(&lmsg, builtin_port, 0);
438                 my_service_domsg(&lmsg, i);
439         }
440 }
441
442 /*
443  * Example 2: Dynamic allocated message passing with automatic free.
444  *
445  * This scenario is used when resources need to be freed after the message
446  * has been replied to. Features:
447  * - An argument is passed within the message.
448  * - Messages are allocated with kmalloc(). Replying to the msg, kfree()s it.
449  */
450
451 #include <sys/thread.h>
452 #include <sys/msgport.h>
453 #include <sys/msgport2.h>
454
455 void my_service_queue(void *arg);
456
457 lwkt_port my_autofree_rport;
458 lwkt_port_t my_service_port;
459
460 /*
461  * Use this function to send messages with a void * argument to our
462  * service thread.
463  */
464 void
465 my_service_queue(void *arg)
466 {
467         lwkt_msg_t msg;
468
469         msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
470
471         /* Set reply port to autofree. */
472         lwkt_initmsg(msg, &my_autofree_rport, 0);
473
474         /* Attach the argument to the message. */
475         msg->u.ms_resultp = arg;
476
477         /* Send it. */
478         lwkt_sendmsg(my_service_port, msg);
479 }
480
481 /*
482  * This is the routine executed by our service thread.
483  */
484 static void
485 my_service_loop(void *dummy __unused)
486 {
487         lwkt_msg_t msg;
488         thread_t td = curthread;
489
490         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
491                 /*
492                  * Do some work in the receiver thread context.  In this
493                  * example, the sender wrote his name in the argument he
494                  * sent us.  We print it here.
495                  */
496                 char *arg = msg->u.ms_resultp;
497                 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm, arg);
498
499                 /* And finally reply to the message. */
500                 lwkt_replymsg(msg, 0);
501         }
502 }
503
504 static void
505 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
506 {
507         kfree(msg->u.ms_resultp, M_TEMP);
508         kfree(msg, M_TEMP);
509 }
510
511 static void
512 my_service_init(void)
513 {
514         thread_t tdp;
515
516         /* Initialize our auto free reply port. */
517         lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
518
519         /* Create our service thread on CPU 0. */
520         lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
521         my_service_port = &tdp->td_msgport;
522 }
523
524 /*
525  * Example use case. Initialize the service and send the current thread name
526  * to the service thread.
527  */
528 static void
529 mod_load(void)
530 {
531         void *arg;
532         int len;
533
534         my_service_init();
535         len = strlen(curthread->td_comm);
536         arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
537         bcopy(curthread->td_comm, arg, len + 1);
538         kprintf("%s: Sending message.\en", curthread->td_comm);
539         my_service_queue(arg);
540 }
541 .Ed
542 .Sh NOTES
543 All the default putport handlers (used when a message is sent) currently
544 implement asynchronous putports only, i.e.\& all *_putport() handlers return
545 .Er EASYNC .
546 You can still have synchronous putport handlers (which are run in the sender's
547 context) but you have to implement the function yourself and then override the
548 default.
549 .Pp
550 Port handler functions can be overridden with custom functions if required.
551 You can override the default putport handler by either using the
552 .Fn lwkt_initport_putonly
553 initializer, or by manipulating the mp_putport handler pointer directly on the
554 lwkt_port structure.
555 .Pp
556 There is one such case where the putport handler is overridden in
557 .Pa sys/kern/netisr.c .
558 In that case, the putport handler is overridden to detect a loopback message
559 (when the target port belongs to the sending thread).
560 This special putport handler turns the sent message into a direct function call
561 instead of queueing it to the port.
562 .Pp
563 The
564 .Fn lwkt_replymsg
565 function works differently depending on the original message request.
566 If the
567 message was originally an asynchronous request, the reply will be queued to the
568 sender's reply port.
569 If the message was originally a synchronous request, then
570 this function will just write the error response on the message and wake up the
571 waiter without queueing the message to the reply port.
572 There is no need to queue in the synchronous request case because the original
573 sender had blocked waiting on this specific message with
574 .Fn lwkt_domsg .
575 .Pp
576 As is the case with putport handler, the replyport handler can also be
577 overridden.
578 You override the default replyport handler by using the
579 .Fn lwkt_initport_replyonly
580 or the
581 .Fn lwkt_initport_replyonly_null
582 port initializers, or by manipulating the mp_replyport handler pointer directly
583 on the lwkt_port structure.
584 .Pp
585 The sent message structure is reused for replies.
586 When a message is replied to, the error response is written on the message
587 which is subsequently sent to the reply port.
588 .Sh SEE ALSO
589 .Xr serializer 9 ,
590 .Xr sleep 9 ,
591 .Xr spinlock 9
592 .Sh HISTORY
593 The LWKT msgport interface first appeared in
594 .Dx 1.0 .
595 .Sh AUTHORS
596 .An -nosplit
597 The
598 .Nm msgport
599 message passing interface implementation was written by
600 .An Matthew Dillon .
601 This manual page was written by
602 .An Nuno Antunes .