2 .\" Copyright (c) 2012-2014 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
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" "boolean_t fixed_cpuid"
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.
256 port is accessed exclusively by threads on a single CPU, we can set the
258 argument to true, which will prevent the occurrence of unnecessary IPIs trying
259 to wake up threads on other CPUs.
260 This function will also initialize the embedded spinlock within the
262 structure which will protect subsequent port access.
265 .Fn lwkt_initport_serialize
266 function initializes the specified
271 The subsequent port access will be protected by the passed
277 function checks the specified
279 for available messages, dequeues the first one and returns it.
280 If no messages are available then
283 This function is used by threads on the receiving side.
287 function checks the specified
289 for available messages, dequeues the first one and returns it.
290 If no messages are available then the caller thread will sleep until a message
291 arrives on the specified port.
294 argument defines the flags used for the sleep.
295 This function is used by threads on the receiving side.
296 .Sh SPECIAL PORT INITIALIZERS
298 .Fn lwkt_initport_replyonly
299 function initializes a
301 which is used only as reply port and may have a custom reply port handler.
302 The reply port handler is specified with the
305 All the other handlers will panic the system if they are called.
306 This initializer is normally used on ports for freeing resources after the
307 messages have fulfilled their purpose.
310 .Fn lwkt_initport_replyonly_null
311 function initializes a
313 which is used only as reply port.
314 The reply port handler will simply mark the message as being done and will not
316 All the other handlers will panic the system if they are called.
319 .Fn lwkt_initport_putonly
320 function initializes a
322 which is used only as target port.
323 The putport handler is specified with the
326 All the other handlers will panic the system if they are called.
329 .Fn lwkt_initport_panic
330 function initializes a
332 which will panic the system if any of its handlers are called.
333 This function is sometimes used to initialize a reply-only port which does not
334 expect the messages to be replied to, e.g.\& when the messages should be
335 consumed by the receiving thread and never replied back.
336 .Sh INTERNAL MESSAGE FUNCTIONS
337 The following functions are used only by the infrastructure, you should not
338 need to use them directly unless in very rare cases.
342 function simply calls the target port's putport handler.
343 This function is only called by the
348 The putport handler returns
350 for messages processed asynchronously or any other value for messages processed
352 That return value of the putport handler is propagated by this function.
355 argument defines the target port to which the
357 message will be sent.
361 function puts the caller to sleep until the specified
363 message has been replied to.
366 argument defines the flags used for the sleep.
367 .Sh IMPLEMENTATION NOTES
368 All the default putport handlers (used when a message is sent) currently
369 implement asynchronous putports only, i.e.\& all
373 You can still have synchronous putport handlers (which are run in the sender's
374 context) but you have to implement the function yourself and then override the
377 Port handler functions can be overridden with custom functions if required.
378 You can override the default putport handler by either using the
379 .Fn lwkt_initport_putonly
380 initializer, or by manipulating the mp_putport handler pointer directly on the
384 There is one such case where the putport handler is overridden in
385 .Pa sys/net/netisr.c .
386 In that case, the putport handler is overridden to detect a loopback message
387 (when the target port belongs to the sending thread).
388 This special putport handler turns the sent message into a direct function call
389 instead of queueing it to the port.
393 function works differently depending on the original message request.
395 message was originally an asynchronous request, the reply will be queued to the
397 If the message was originally a synchronous request, then
398 this function will just write the error response on the message and wake up the
399 waiter without queueing the message to the reply port.
400 There is no need to queue in the synchronous request case because the original
401 sender had blocked waiting on this specific message with
404 As is the case with putport handler, the replyport handler can also be
406 You override the default replyport handler by using the
407 .Fn lwkt_initport_replyonly
409 .Fn lwkt_initport_replyonly_null
410 port initializers, or by manipulating the mp_replyport handler pointer directly
415 The sent message structure is reused for replies.
416 When a message is replied to, the error response is written on the message
417 which is subsequently sent to the reply port.
419 The LWKT msgport implementation resides in
420 .Pa sys/kern/lwkt_msgport.c .
424 * Example 1: per CPU threads.
428 #include <sys/thread.h>
429 #include <sys/msgport.h>
430 #include <sys/msgport2.h>
432 static void my_service_loop(void *dummy);
433 lwkt_port_t my_service_portfn(int cpu);
434 void my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
435 int my_service_domsg(lwkt_msg_t lmsg, int cpu);
437 /* Array of per-CPU target ports */
438 struct lwkt_port *my_service_ports[MAXCPU];
441 * Create per-cpu threads for handling msg processing. Remember that
442 * built-in lwkt ports are automatically initialized to type 'thread'
443 * so we don't need to initialize them explicitly.
446 my_per_cpu_service_init(void)
451 for (i = 0; i < ncpus; ++i) {
452 lwkt_create(my_service_loop, NULL, &td,
453 NULL, 0, i, "myservice_cpu %d", i);
454 my_service_ports[i] = &td->td_msgport;
459 * This is the routine executed by the service threads on each CPU.
462 my_service_loop(void *dummy __unused)
465 thread_t td = curthread;
466 int cpu = curthread->td_gd->gd_cpuid;
468 while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
469 /* Do some work in the receiver thread context. */
470 kprintf("Received message on CPU %d.\en", cpu);
472 /* And finally reply to the message. */
473 lwkt_replymsg(msg, 0);
478 * Given a CPU id, return our respective service port.
481 my_service_portfn(int cpu)
483 return my_service_ports[cpu];
487 * Send an asynchronous message to the service thread on a specific CPU.
490 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
492 KKASSERT(cpu < ncpus);
493 lwkt_sendmsg(my_service_portfn(cpu), lmsg);
497 * Send a synchronous message to the service thread on a specific CPU.
500 my_service_domsg(lwkt_msg_t lmsg, int cpu)
502 KKASSERT(cpu < ncpus);
503 return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
507 * Example use case. Initialize the service threads and send each one a
514 lwkt_port_t builtin_port = &curthread->td_msgport;
517 my_per_cpu_service_init();
518 for (i=0; i<ncpus; ++i) {
519 kprintf("Sending msg to CPU %d.\en", i);
520 lwkt_initmsg(&lmsg, builtin_port, 0);
521 my_service_domsg(&lmsg, i);
526 * Example 2: Dynamic allocated message passing with automatic free.
528 * This scenario is used when resources need to be freed after the
529 * message has been replied to. Features:
530 * - An argument is passed within the message.
531 * - Messages are allocated with kmalloc(). Replying to the message
535 #include <sys/thread.h>
536 #include <sys/msgport.h>
537 #include <sys/msgport2.h>
539 void my_service_queue(void *arg);
541 lwkt_port my_autofree_rport;
542 lwkt_port_t my_service_port;
545 * Use this function to send messages with a void * argument to our
549 my_service_queue(void *arg)
553 msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
555 /* Set reply port to autofree. */
556 lwkt_initmsg(msg, &my_autofree_rport, 0);
558 /* Attach the argument to the message. */
559 msg->u.ms_resultp = arg;
562 lwkt_sendmsg(my_service_port, msg);
566 * This is the routine executed by our service thread.
569 my_service_loop(void *dummy __unused)
572 thread_t td = curthread;
574 while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
576 * Do some work in the receiver thread context. In this
577 * example, the sender wrote his name in the argument he
578 * sent us. We print it here.
580 char *arg = msg->u.ms_resultp;
581 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm,
584 /* And finally reply to the message. */
585 lwkt_replymsg(msg, 0);
590 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
592 kfree(msg->u.ms_resultp, M_TEMP);
597 my_service_init(void)
601 /* Initialize our auto free reply port. */
602 lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
604 /* Create our service thread on CPU 0. */
605 lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
606 my_service_port = &tdp->td_msgport;
610 * Example use case. Initialize the service and send the current thread
611 * name to the service thread.
620 len = strlen(curthread->td_comm);
621 arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
622 bcopy(curthread->td_comm, arg, len + 1);
623 kprintf("%s: Sending message.\en", curthread->td_comm);
624 my_service_queue(arg);
632 The LWKT msgport interface first appeared in
638 message passing interface implementation was written by
640 This manual page was written by