2 .\" Copyright (c) 2012 The DragonFly Project. All rights reserved.
4 .\" This code is derived from software contributed to The DragonFly Project
5 .\" by Nuno Antunes <nuno.antunes@gmail.com>.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
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
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.
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
34 .Dd September 17, 2012
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 ,
50 .Nm lwkt_initmsg_abortable ,
58 .Nd LWKT message passing interface
62 .Fn lwkt_initport_thread "lwkt_port_t port" "struct thread *td"
64 .Fn lwkt_initport_spin "lwkt_port_t port" "struct thread *td"
66 .Fn lwkt_initport_serialize "lwkt_port_t port" "struct lwkt_serialize *slz"
68 .Fn lwkt_initport_panic "lwkt_port_t port"
70 .Fn lwkt_initport_replyonly_null "lwkt_port_t port"
72 .Fn lwkt_initport_replyonly "lwkt_port_t port" "void (*rportfn)(lwkt_port_t, lwkt_msg_t)"
74 .Fn lwkt_initport_putonly "lwkt_port_t port" "int (*pportfn)(lwkt_port_t, lwkt_msg_t)"
76 .Fn lwkt_sendmsg "lwkt_port_t port" "lwkt_msg_t msg"
78 .Fn lwkt_domsg "lwkt_port_t port" "lwkt_msg_t msg" "int flags"
80 .Fn lwkt_forwardmsg "lwkt_port_t port" "lwkt_msg_t msg"
82 .Fn lwkt_abortmsg "lwkt_msg_t msg"
85 .Fn lwkt_initmsg "lwkt_msg_t msg" "lwkt_port_t rport" "int flags"
87 .Fn lwkt_initmsg_abortable "lwkt_msg_t msg" "lwkt_port_t rport" "int flags" "void (*abortfn)(lwkt_msg_t)"
89 .Fn lwkt_beginmsg "lwkt_port_t port" "lwkt_msg_t msg"
91 .Fn lwkt_replymsg "lwkt_msg_t msg" "int error"
93 .Fn lwkt_getport "lwkt_port_t port"
95 .Fn lwkt_waitport "lwkt_port_t port" "int flags"
97 .Fn lwkt_waitmsg "lwkt_msg_t msg" "int flags"
99 .Fn lwkt_checkmsg "lwkt_msg_t msg"
101 .Fn lwkt_dropmsg "lwkt_msg_t msg"
103 Light weight kernel threads in
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:
121 are owned by a single light weight kernel thread.
122 When a message is sent to a port of type
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
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
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.
145 function initializes a message.
148 argument identifies the reply port which will be used for asynchronous replies.
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
156 .Fn lwkt_initmsg_abortable
157 function is similar to
159 but it takes an additional parameter
161 which defines the abort function for this message.
165 function requests an asynchronous reply, sends the message and returns
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.
171 argument defines the target port to which the
173 message will be sent.
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
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.
185 argument defines the target port to which the
187 message will be sent.
191 function replies to a message that was processed asynchronously by the target
193 This function is used by the thread on the receiving side.
196 argument is the message being replied to and the
198 argument is the actual response to send back.
202 simply forwards a message to another port.
205 argument defines the target port to which the
207 message will be sent.
209 If a message has been initialized as abortable, you can use the
211 function to try to abort it.
214 passed upon the initialisation with
215 .Fn lwkt_initmsg_abortable
216 will be called by this function.
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.
225 .Fn lwkt_initport_thread
226 initializes the specified
233 argument defines the owner thread of the port and only that thread is allowed to
234 receive messages on it.
237 .Fn lwkt_initport_spin
238 initializes the specified
245 argument defines the owner thread of the port, for cases where thread built-in
246 ports are initialized as
251 is passed, then the port will not have a defined owner, so functions like
253 will not be available for this port.
254 This function will also initialize the embedded spinlock within the
256 structure which will protect subsequent port access.
259 .Fn lwkt_initport_serialize
260 function initializes the specified
265 The subsequent port access will be protected by the passed
271 function checks the specified
273 for available messages, dequeues the first one and returns it.
274 If no messages are available then
277 This function is used by threads on the receiving side.
281 function checks the specified
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.
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
292 .Fn lwkt_initport_replyonly
293 function initializes a
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
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.
304 .Fn lwkt_initport_replyonly_null
305 function initializes a
307 which is used only as reply port.
308 The reply port handler will simply mark the message as being done and will not
310 All the other handlers will panic the system if they are called.
313 .Fn lwkt_initport_putonly
314 function initializes a
316 which is used only as target port.
317 The putport handler is specified with the
320 All the other handlers will panic the system if they are called.
323 .Fn lwkt_initport_panic
324 function initializes a
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.
336 function simply calls the target port's putport handler.
337 This function is only called by the
342 The putport handler returns
344 for messages processed asynchronously or any other value for messages processed
346 That return value of the putport handler is propagated by this function.
349 argument defines the target port to which the
351 message will be sent.
355 function puts the caller to sleep until the specified
357 message has been replied to.
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
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
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
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.
387 function works differently depending on the original message request.
389 message was originally an asynchronous request, the reply will be queued to the
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
398 As is the case with putport handler, the replyport handler can also be
400 You override the default replyport handler by using the
401 .Fn lwkt_initport_replyonly
403 .Fn lwkt_initport_replyonly_null
404 port initializers, or by manipulating the mp_replyport handler pointer directly
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.
413 The LWKT msgport implementation resides in
414 .Pa sys/kern/lwkt_msgport.c .
418 * Example 1: per CPU threads.
422 #include <sys/thread.h>
423 #include <sys/msgport.h>
424 #include <sys/msgport2.h>
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);
431 /* Array of per-CPU target ports */
432 struct lwkt_port *my_service_ports[MAXCPU];
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.
440 my_per_cpu_service_init(void)
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;
453 * This is the routine executed by the service threads on each CPU.
456 my_service_loop(void *dummy __unused)
459 thread_t td = curthread;
460 int cpu = curthread->td_gd->gd_cpuid;
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);
466 /* And finally reply to the message. */
467 lwkt_replymsg(msg, 0);
472 * Given a CPU id, return our respective service port.
475 my_service_portfn(int cpu)
477 return my_service_ports[cpu];
481 * Send an asynchronous message to the service thread on a specific CPU.
484 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
486 KKASSERT(cpu < ncpus);
487 lwkt_sendmsg(my_service_portfn(cpu), lmsg);
491 * Send a synchronous message to the service thread on a specific CPU.
494 my_service_domsg(lwkt_msg_t lmsg, int cpu)
496 KKASSERT(cpu < ncpus);
497 return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
501 * Example use case. Initialize the service threads and send each one a
508 lwkt_port_t builtin_port = &curthread->td_msgport;
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);
520 * Example 2: Dynamic allocated message passing with automatic free.
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
529 #include <sys/thread.h>
530 #include <sys/msgport.h>
531 #include <sys/msgport2.h>
533 void my_service_queue(void *arg);
535 lwkt_port my_autofree_rport;
536 lwkt_port_t my_service_port;
539 * Use this function to send messages with a void * argument to our
543 my_service_queue(void *arg)
547 msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
549 /* Set reply port to autofree. */
550 lwkt_initmsg(msg, &my_autofree_rport, 0);
552 /* Attach the argument to the message. */
553 msg->u.ms_resultp = arg;
556 lwkt_sendmsg(my_service_port, msg);
560 * This is the routine executed by our service thread.
563 my_service_loop(void *dummy __unused)
566 thread_t td = curthread;
568 while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
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.
574 char *arg = msg->u.ms_resultp;
575 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm,
578 /* And finally reply to the message. */
579 lwkt_replymsg(msg, 0);
584 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
586 kfree(msg->u.ms_resultp, M_TEMP);
591 my_service_init(void)
595 /* Initialize our auto free reply port. */
596 lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
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;
604 * Example use case. Initialize the service and send the current thread
605 * name to the service thread.
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);
626 The LWKT msgport interface first appeared in
632 message passing interface implementation was written by
634 This manual page was written by