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
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"
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:
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'.
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.
138 function initializes a message.
141 argument identifies the reply port which will be used for asynchronous replies.
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
149 .Fn lwkt_initmsg_abortable
150 function is similar to
152 but it takes an additional parameter
154 which defines the abort function for this message.
158 function requests an asynchronous reply, sends the message and returns
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.
164 argument defines the target port to which the
166 message will be sent to.
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
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.
178 argument defines the target port to which the
180 message will be sent to.
184 function replies to a message that was processed asynchronously by the target
186 This function is used by the thread on the receiving side.
189 argument is the message being replied to and the
191 argument is the actual response to send back.
195 simply forwards a message to another port.
198 argument defines the target port to which the
200 message will be sent to.
202 If a message has been initialized as abortable, you can use the
204 function to try to abort it.
207 passed upon the initialisation with
208 .Fn lwkt_initmsg_abortable
209 will be called by this function.
213 will dequeue the specified message from the target port it was sent to and makes
214 it look like it was never sent.
217 .Fn lwkt_initport_thread
218 initializes the specified
220 with the default 'thread' port type handlers.
223 argument defines the owner thread of the port and only that thread is allowed to
224 receive messages on it.
227 .Fn lwkt_initport_spin
228 initializes the specified
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.
235 .Fn lwkt_initport_serialize
236 function initializes the specified
238 with the default 'serializer' port type handlers.
239 The subsequent port access will be protected by the passed
245 function checks the specified
247 for available messages, dequeues the first one and returns it.
248 If no messages are available then
251 This function is used by threads on the receiving side.
255 function checks the specified
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.
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
266 .Fn lwkt_initport_replyonly
267 function initializes a
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
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.
278 .Fn lwkt_initport_replyonly_null
279 function initializes a
281 which is used only as reply port.
282 The reply port handler will simply mark the message as being done and will not
284 All the other handlers will panic the system if they are called.
287 .Fn lwkt_initport_putonly
288 function initializes a
290 which is used only as target port.
291 The putport handler is specified with the
294 All the other handlers will panic the system if they are called.
297 .Fn lwkt_initport_panic
298 function initializes a
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.
310 function simply calls the target port's putport handler.
311 This function is only called by the
316 The putport handler returns
318 for messages processed asynchronously or any other value for messages processed
320 That return value of the putport handler is propagated by this function.
323 argument defines the target port to which the
325 message will be sent to.
329 function puts the caller to sleep until the specified
331 message has been replied to.
334 argument defines the flags used for the sleep.
336 The LWKT msgport implementation resides in
337 .Pa sys/kern/lwkt_msgport.c .
341 * Example 1: per CPU threads.
345 #include <sys/thread.h>
346 #include <sys/msgport.h>
347 #include <sys/msgport2.h>
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);
354 /* Array of per-CPU target ports */
355 struct lwkt_port *my_service_ports[MAXCPU];
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.
363 my_per_cpu_service_init(void)
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;
376 * This is the routine executed by the service threads on each CPU.
379 my_service_loop(void *dummy __unused)
382 thread_t td = curthread;
383 int cpu = curthread->td_gd->gd_cpuid;
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);
389 /* And finally reply to the message. */
390 lwkt_replymsg(msg, 0);
395 * Given a CPU id, return our respective service port.
398 my_service_portfn(int cpu)
400 return my_service_ports[cpu];
404 * Send an asynchronous message to the service thread on a specific CPU.
407 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
409 KKASSERT(cpu < ncpus);
410 lwkt_sendmsg(my_service_portfn(cpu), lmsg);
414 * Send a synchronous message to the service thread on a specific CPU.
417 my_service_domsg(lwkt_msg_t lmsg, int cpu)
419 KKASSERT(cpu < ncpus);
420 return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
424 * Example use case. Initialize the service threads and send each one a
431 lwkt_port_t builtin_port = &curthread->td_msgport;
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);
443 * Example 2: Dynamic allocated message passing with automatic free.
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.
451 #include <sys/thread.h>
452 #include <sys/msgport.h>
453 #include <sys/msgport2.h>
455 void my_service_queue(void *arg);
457 lwkt_port my_autofree_rport;
458 lwkt_port_t my_service_port;
461 * Use this function to send messages with a void * argument to our
465 my_service_queue(void *arg)
469 msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
471 /* Set reply port to autofree. */
472 lwkt_initmsg(msg, &my_autofree_rport, 0);
474 /* Attach the argument to the message. */
475 msg->u.ms_resultp = arg;
478 lwkt_sendmsg(my_service_port, msg);
482 * This is the routine executed by our service thread.
485 my_service_loop(void *dummy __unused)
488 thread_t td = curthread;
490 while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
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.
496 char *arg = msg->u.ms_resultp;
497 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm, arg);
499 /* And finally reply to the message. */
500 lwkt_replymsg(msg, 0);
505 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
507 kfree(msg->u.ms_resultp, M_TEMP);
512 my_service_init(void)
516 /* Initialize our auto free reply port. */
517 lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
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;
525 * Example use case. Initialize the service and send the current thread name
526 * to the service thread.
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);
543 All the default putport handlers (used when a message is sent) currently
544 implement asynchronous putports only, i.e.\& all *_putport() handlers return
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
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
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.
565 function works differently depending on the original message request.
567 message was originally an asynchronous request, the reply will be queued to the
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
576 As is the case with putport handler, the replyport handler can also be
578 You override the default replyport handler by using the
579 .Fn lwkt_initport_replyonly
581 .Fn lwkt_initport_replyonly_null
582 port initializers, or by manipulating the mp_replyport handler pointer directly
583 on the lwkt_port structure.
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.
592 The LWKT msgport interface first appeared in
598 message passing interface implementation was written by
600 This manual page was written by