7c89a29d6b571c5c739bf8e848a75423b5a2ac74
[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 September 17, 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" "struct thread *td"
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 int
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
120 .Sq thread
121 are owned by a single light weight kernel thread.
122 When a message is sent to a port of type
123 .Sq thread ,
124 only the owner of that port is allowed to retrieve the message from it.
125 When a message is sent to a port of type
126 .Sq spin
127 or to a port of type
128 .Sq serializer ,
129 multiple threads are allowed to check that port for new
130 messages and compete to retrieve them.
131 You define the port type when you initialize the port.
132 By default, the built-in port of every light weight kernel thread is
133 automatically initialized to type
134 .Sq thread .
135 .Pp
136 When a message is sent, the receiver should normally send back a reply.
137 The reply is sent to the reply port that is registered on the original message.
138 Messages can be replied to synchronously or asynchronously.
139 The sender may request a synchronous or asynchronous reply to the message,
140 however the target port will ultimately decide how the message will be treated.
141 .Sh MESSAGE FUNCTIONS
142 Messages must be initialized before being used.
143 The
144 .Fn lwkt_initmsg
145 function initializes a message.
146 The
147 .Fa rport
148 argument identifies the reply port which will be used for asynchronous replies.
149 The
150 .Fa flags
151 argument sets any required flags for this message.
152 Flags passed this way will simply be or'ed to any already existing flags on the
153 message.
154 .Pp
155 The
156 .Fn lwkt_initmsg_abortable
157 function is similar to
158 .Fn lwkt_initmsg
159 but it takes an additional parameter
160 .Fa abortfn
161 which defines the abort function for this message.
162 .Pp
163 The
164 .Fn lwkt_sendmsg
165 function requests an asynchronous reply, sends the message and returns
166 immediately.
167 Under normal circumstances, users of this function may always expect the reply
168 to be queued to the reply port registered on the message.
169 The
170 .Fa port
171 argument defines the target port to which the
172 .Fa msg
173 message will be sent.
174 .Pp
175 The
176 .Fn lwkt_domsg
177 function requests a synchronous reply, sends the message and does not return
178 until the message has been replied to.
179 If the target port supports synchronous reply, this function will return that
180 reply immediately.
181 If not, and this is the most common case, this function will block and wait for the
182 reply to arrive and then return it.
183 The
184 .Fa port
185 argument defines the target port to which the
186 .Fa msg
187 message will be sent.
188 .Pp
189 The
190 .Fn lwkt_replymsg
191 function replies to a message that was processed asynchronously by the target
192 port.
193 This function is used by the thread on the receiving side.
194 The
195 .Fa msg
196 argument is the message being replied to and the
197 .Fa error
198 argument is the actual response to send back.
199 .Pp
200 The
201 .Fn lwkt_forwardmsg
202 simply forwards a message to another port.
203 The
204 .Fa port
205 argument defines the target port to which the
206 .Fa msg
207 message will be sent.
208 .Pp
209 If a message has been initialized as abortable, you can use the
210 .Fn lwkt_abortmsg
211 function to try to abort it.
212 The
213 .Fa abortfn
214 passed upon the initialisation with
215 .Fn lwkt_initmsg_abortable
216 will be called by this function.
217 .Pp
218 The
219 .Fn lwkt_dropmsg
220 will dequeue the specified message from the target port it was sent to and makes
221 it look like it was never sent.
222 This function can only be used by the thread that owns the target port.
223 .Sh PORT FUNCTIONS
224 The
225 .Fn lwkt_initport_thread
226 initializes the specified
227 .Fa port
228 with the default
229 .Sq thread
230 port type handlers.
231 The
232 .Fa td
233 argument defines the owner thread of the port and only that thread is allowed to
234 receive messages on it.
235 .Pp
236 The
237 .Fn lwkt_initport_spin
238 initializes the specified
239 .Fa port
240 with the default
241 .Sq spin
242 port type handlers.
243 The
244 .Fa td
245 argument defines the owner thread of the port, for cases where thread built-in
246 ports are initialized as
247 .Sq spin
248 ports.
249 If
250 .Dv NULL
251 is passed, then the port will not have a defined owner, so functions like
252 .Fn lwkt_dropmsg
253 will not be available for this port.
254 This function will also initialize the embedded spinlock within the
255 .Vt lwkt_port
256 structure which will protect subsequent port access.
257 .Pp
258 The
259 .Fn lwkt_initport_serialize
260 function initializes the specified
261 .Fa port
262 with the default
263 .Sq serializer
264 port type handlers.
265 The subsequent port access will be protected by the passed
266 .Fa slz
267 serializer lock.
268 .Pp
269 The
270 .Fn lwkt_getport
271 function checks the specified
272 .Fa port
273 for available messages, dequeues the first one and returns it.
274 If no messages are available then
275 .Dv NULL
276 is returned instead.
277 This function is used by threads on the receiving side.
278 .Pp
279 The
280 .Fn lwkt_waitport
281 function checks the specified
282 .Fa port
283 for available messages, dequeues the first one and returns it.
284 If no messages are available then the caller thread will sleep until a message
285 arrives on the specified port.
286 The
287 .Fa flags
288 argument defines the flags used for the sleep.
289 This function is used by threads on the receiving side.
290 .Sh SPECIAL PORT INITIALIZERS
291 The
292 .Fn lwkt_initport_replyonly
293 function initializes a
294 .Fa port
295 which is used only as reply port and may have a custom reply port handler.
296 The reply port handler is specified with the
297 .Fa rportfn
298 argument.
299 All the other handlers will panic the system if they are called.
300 This initializer is normally used on ports for freeing resources after the
301 messages have fulfilled their purpose.
302 .Pp
303 The
304 .Fn lwkt_initport_replyonly_null
305 function initializes a
306 .Fa port
307 which is used only as reply port.
308 The reply port handler will simply mark the message as being done and will not
309 attempt to queue it.
310 All the other handlers will panic the system if they are called.
311 .Pp
312 The
313 .Fn lwkt_initport_putonly
314 function initializes a
315 .Fa port
316 which is used only as target port.
317 The putport handler is specified with the
318 .Fa pportfn
319 argument.
320 All the other handlers will panic the system if they are called.
321 .Pp
322 The
323 .Fn lwkt_initport_panic
324 function initializes a
325 .Fa port
326 which will panic the system if any of its handlers are called.
327 This function is sometimes used to initialize a reply-only port which does not
328 expect the messages to be replied to, e.g.\& when the messages should be
329 consumed by the receiving thread and never replied back.
330 .Sh INTERNAL MESSAGE FUNCTIONS
331 The following functions are used only by the infrastructure, you should not
332 need to use them directly unless in very rare cases.
333 .Pp
334 The
335 .Fn lwkt_beginmsg
336 function simply calls the target port's putport handler.
337 This function is only called by the
338 .Fn lwkt_sendmsg
339 and
340 .Fn lwkt_replymsg
341 functions.
342 The putport handler returns
343 .Er EASYNC
344 for messages processed asynchronously or any other value for messages processed
345 synchronously.
346 That return value of the putport handler is propagated by this function.
347 The
348 .Fa port
349 argument defines the target port to which the
350 .Fa msg
351 message will be sent.
352 .Pp
353 The
354 .Fn lwkt_waitmsg
355 function puts the caller to sleep until the specified
356 .Fa msg
357 message has been replied to.
358 The
359 .Fa flags
360 argument defines the flags used for the sleep.
361 .Sh IMPLEMENTATION NOTES
362 All the default putport handlers (used when a message is sent) currently
363 implement asynchronous putports only, i.e.\& all
364 .Fn *_putport
365 handlers return
366 .Er EASYNC .
367 You can still have synchronous putport handlers (which are run in the sender's
368 context) but you have to implement the function yourself and then override the
369 default.
370 .Pp
371 Port handler functions can be overridden with custom functions if required.
372 You can override the default putport handler by either using the
373 .Fn lwkt_initport_putonly
374 initializer, or by manipulating the mp_putport handler pointer directly on the
375 .Vt lwkt_port
376 structure.
377 .Pp
378 There is one such case where the putport handler is overridden in
379 .Pa sys/net/netisr.c .
380 In that case, the putport handler is overridden to detect a loopback message
381 (when the target port belongs to the sending thread).
382 This special putport handler turns the sent message into a direct function call
383 instead of queueing it to the port.
384 .Pp
385 The
386 .Fn lwkt_replymsg
387 function works differently depending on the original message request.
388 If the
389 message was originally an asynchronous request, the reply will be queued to the
390 sender's reply port.
391 If the message was originally a synchronous request, then
392 this function will just write the error response on the message and wake up the
393 waiter without queueing the message to the reply port.
394 There is no need to queue in the synchronous request case because the original
395 sender had blocked waiting on this specific message with
396 .Fn lwkt_domsg .
397 .Pp
398 As is the case with putport handler, the replyport handler can also be
399 overridden.
400 You override the default replyport handler by using the
401 .Fn lwkt_initport_replyonly
402 or the
403 .Fn lwkt_initport_replyonly_null
404 port initializers, or by manipulating the mp_replyport handler pointer directly
405 on the
406 .Vt lwkt_port
407 structure.
408 .Pp
409 The sent message structure is reused for replies.
410 When a message is replied to, the error response is written on the message
411 which is subsequently sent to the reply port.
412 .Sh FILES
413 The LWKT msgport implementation resides in
414 .Pa sys/kern/lwkt_msgport.c .
415 .Sh EXAMPLES
416 .Bd -literal
417 /*
418  * Example 1: per CPU threads.
419  *
420  */
421
422 #include <sys/thread.h>
423 #include <sys/msgport.h>
424 #include <sys/msgport2.h>
425
426 static void my_service_loop(void *dummy);
427 lwkt_port_t my_service_portfn(int cpu);
428 void my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
429 int my_service_domsg(lwkt_msg_t lmsg, int cpu);
430
431 /* Array of per-CPU target ports */
432 struct lwkt_port *my_service_ports[MAXCPU];
433
434 /*
435  * Create per-cpu threads for handling msg processing.  Remember that
436  * built-in lwkt ports are automatically initialized to type 'thread'
437  * so we don't need to initialize them explicitly.
438  */
439 static void
440 my_per_cpu_service_init(void)
441 {
442         int i;
443         thread_t td;
444
445         for (i = 0; i < ncpus; ++i) {
446                 lwkt_create(my_service_loop, NULL, &td,
447                             NULL, 0, i, "myservice_cpu %d", i);
448                 my_service_ports[i] = &td->td_msgport;
449         }
450 }
451
452 /*
453  * This is the routine executed by the service threads on each CPU.
454  */
455 static void
456 my_service_loop(void *dummy __unused)
457 {
458         lwkt_msg_t msg;
459         thread_t td = curthread;
460         int cpu = curthread->td_gd->gd_cpuid;
461
462         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
463                 /* Do some work in the receiver thread context. */
464                 kprintf("Received message on CPU %d.\en", cpu);
465
466                 /* And finally reply to the message. */
467                 lwkt_replymsg(msg, 0);
468         }
469 }
470
471 /*
472  * Given a CPU id, return our respective service port.
473  */
474 __inline lwkt_port_t
475 my_service_portfn(int cpu)
476 {
477         return my_service_ports[cpu];
478 }
479
480 /*
481  * Send an asynchronous message to the service thread on a specific CPU.
482  */
483 void
484 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
485 {
486         KKASSERT(cpu < ncpus);
487         lwkt_sendmsg(my_service_portfn(cpu), lmsg);
488 }
489
490 /*
491  * Send a synchronous message to the service thread on a specific CPU.
492  */
493 int
494 my_service_domsg(lwkt_msg_t lmsg, int cpu)
495 {
496         KKASSERT(cpu < ncpus);
497         return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
498 }
499
500 /*
501  * Example use case. Initialize the service threads and send each one a
502  * message.
503  */
504 static void
505 mod_load(void)
506 {
507         lwkt_msg        lmsg;
508         lwkt_port_t     builtin_port = &curthread->td_msgport;
509         int             i;
510
511         my_per_cpu_service_init();
512         for (i=0; i<ncpus; ++i) {
513                 kprintf("Sending msg to CPU %d.\en", i);
514                 lwkt_initmsg(&lmsg, builtin_port, 0);
515                 my_service_domsg(&lmsg, i);
516         }
517 }
518
519 /*
520  * Example 2: Dynamic allocated message passing with automatic free.
521  *
522  * This scenario is used when resources need to be freed after the
523  * message has been replied to. Features:
524  * - An argument is passed within the message.
525  * - Messages are allocated with kmalloc(). Replying to the message
526  *   kfree()s it.
527  */
528
529 #include <sys/thread.h>
530 #include <sys/msgport.h>
531 #include <sys/msgport2.h>
532
533 void my_service_queue(void *arg);
534
535 lwkt_port my_autofree_rport;
536 lwkt_port_t my_service_port;
537
538 /*
539  * Use this function to send messages with a void * argument to our
540  * service thread.
541  */
542 void
543 my_service_queue(void *arg)
544 {
545         lwkt_msg_t msg;
546
547         msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
548
549         /* Set reply port to autofree. */
550         lwkt_initmsg(msg, &my_autofree_rport, 0);
551
552         /* Attach the argument to the message. */
553         msg->u.ms_resultp = arg;
554
555         /* Send it. */
556         lwkt_sendmsg(my_service_port, msg);
557 }
558
559 /*
560  * This is the routine executed by our service thread.
561  */
562 static void
563 my_service_loop(void *dummy __unused)
564 {
565         lwkt_msg_t msg;
566         thread_t td = curthread;
567
568         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
569                 /*
570                  * Do some work in the receiver thread context.  In this
571                  * example, the sender wrote his name in the argument he
572                  * sent us.  We print it here.
573                  */
574                 char *arg = msg->u.ms_resultp;
575                 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm,
576                     arg);
577
578                 /* And finally reply to the message. */
579                 lwkt_replymsg(msg, 0);
580         }
581 }
582
583 static void
584 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
585 {
586         kfree(msg->u.ms_resultp, M_TEMP);
587         kfree(msg, M_TEMP);
588 }
589
590 static void
591 my_service_init(void)
592 {
593         thread_t tdp;
594
595         /* Initialize our auto free reply port. */
596         lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
597
598         /* Create our service thread on CPU 0. */
599         lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
600         my_service_port = &tdp->td_msgport;
601 }
602
603 /*
604  * Example use case. Initialize the service and send the current thread
605  * name to the service thread.
606  */
607 static void
608 mod_load(void)
609 {
610         void *arg;
611         int len;
612
613         my_service_init();
614         len = strlen(curthread->td_comm);
615         arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
616         bcopy(curthread->td_comm, arg, len + 1);
617         kprintf("%s: Sending message.\en", curthread->td_comm);
618         my_service_queue(arg);
619 }
620 .Ed
621 .Sh SEE ALSO
622 .Xr serializer 9 ,
623 .Xr sleep 9 ,
624 .Xr spinlock 9
625 .Sh HISTORY
626 The LWKT msgport interface first appeared in
627 .Dx 1.0 .
628 .Sh AUTHORS
629 .An -nosplit
630 The
631 .Nm msgport
632 message passing interface implementation was written by
633 .An Matthew Dillon .
634 This manual page was written by
635 .An Nuno Antunes .