xref: /dflybsd-src/share/man/man9/msgport.9 (revision c6e8b6c15bcace495c5c80fb97509bcc7adaee4c)
194a4cc0bSNuno Antunes.\"
294a4cc0bSNuno Antunes.\" Copyright (c) 2012 The DragonFly Project.  All rights reserved.
394a4cc0bSNuno Antunes.\"
494a4cc0bSNuno Antunes.\" This code is derived from software contributed to The DragonFly Project
594a4cc0bSNuno Antunes.\" by Nuno Antunes <nuno.antunes@gmail.com>.
694a4cc0bSNuno Antunes.\"
794a4cc0bSNuno Antunes.\" Redistribution and use in source and binary forms, with or without
894a4cc0bSNuno Antunes.\" modification, are permitted provided that the following conditions
994a4cc0bSNuno Antunes.\" are met:
1094a4cc0bSNuno Antunes.\"
1194a4cc0bSNuno Antunes.\" 1. Redistributions of source code must retain the above copyright
1294a4cc0bSNuno Antunes.\"    notice, this list of conditions and the following disclaimer.
1394a4cc0bSNuno Antunes.\" 2. Redistributions in binary form must reproduce the above copyright
1494a4cc0bSNuno Antunes.\"    notice, this list of conditions and the following disclaimer in
1594a4cc0bSNuno Antunes.\"    the documentation and/or other materials provided with the
1694a4cc0bSNuno Antunes.\"    distribution.
1794a4cc0bSNuno Antunes.\" 3. Neither the name of The DragonFly Project nor the names of its
1894a4cc0bSNuno Antunes.\"    contributors may be used to endorse or promote products derived
1994a4cc0bSNuno Antunes.\"    from this software without specific, prior written permission.
2094a4cc0bSNuno Antunes.\"
2194a4cc0bSNuno Antunes.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2294a4cc0bSNuno Antunes.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2394a4cc0bSNuno Antunes.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2494a4cc0bSNuno Antunes.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
2594a4cc0bSNuno Antunes.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2694a4cc0bSNuno Antunes.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2794a4cc0bSNuno Antunes.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2894a4cc0bSNuno Antunes.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2994a4cc0bSNuno Antunes.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3094a4cc0bSNuno Antunes.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3194a4cc0bSNuno Antunes.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3294a4cc0bSNuno Antunes.\" SUCH DAMAGE.
3394a4cc0bSNuno Antunes.\"
3494a4cc0bSNuno Antunes.Dd August 12, 2012
3594a4cc0bSNuno Antunes.Dt MSGPORT 9
3694a4cc0bSNuno Antunes.Os
3794a4cc0bSNuno Antunes.Sh NAME
3894a4cc0bSNuno Antunes.Nm lwkt_initport_thread ,
3994a4cc0bSNuno Antunes.Nm lwkt_initport_spin ,
4094a4cc0bSNuno Antunes.Nm lwkt_initport_serialize ,
4194a4cc0bSNuno Antunes.Nm lwkt_initport_panic ,
4294a4cc0bSNuno Antunes.Nm lwkt_initport_replyonly_null ,
4394a4cc0bSNuno Antunes.Nm lwkt_initport_replyonly ,
4494a4cc0bSNuno Antunes.Nm lwkt_initport_putonly ,
4594a4cc0bSNuno Antunes.Nm lwkt_sendmsg ,
4694a4cc0bSNuno Antunes.Nm lwkt_domsg ,
4794a4cc0bSNuno Antunes.Nm lwkt_forwardmsg ,
4894a4cc0bSNuno Antunes.Nm lwkt_abortmsg ,
4994a4cc0bSNuno Antunes.Nm lwkt_initmsg ,
5094a4cc0bSNuno Antunes.Nm lwkt_initmsg_abortable ,
5194a4cc0bSNuno Antunes.Nm lwkt_beginmsg ,
5294a4cc0bSNuno Antunes.Nm lwkt_replymsg ,
5394a4cc0bSNuno Antunes.Nm lwkt_getport ,
5494a4cc0bSNuno Antunes.Nm lwkt_waitport ,
5594a4cc0bSNuno Antunes.Nm lwkt_waitmsg ,
5694a4cc0bSNuno Antunes.Nm lwkt_checkmsg ,
5794a4cc0bSNuno Antunes.Nm lwkt_dropmsg
5894a4cc0bSNuno Antunes.Nd LWKT message passing interface
5994a4cc0bSNuno Antunes.Sh SYNOPSIS
6094a4cc0bSNuno Antunes.In sys/msgport.h
6194a4cc0bSNuno Antunes.Ft void
6294a4cc0bSNuno Antunes.Fn lwkt_initport_thread "lwkt_port_t port" "struct thread *td"
6394a4cc0bSNuno Antunes.Ft void
6494a4cc0bSNuno Antunes.Fn lwkt_initport_spin "lwkt_port_t port"
6594a4cc0bSNuno Antunes.Ft void
6694a4cc0bSNuno Antunes.Fn lwkt_initport_serialize "lwkt_port_t port" "struct lwkt_serialize *slz"
6794a4cc0bSNuno Antunes.Ft void
6894a4cc0bSNuno Antunes.Fn lwkt_initport_panic "lwkt_port_t port"
6994a4cc0bSNuno Antunes.Ft void
7094a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly_null "lwkt_port_t port"
7194a4cc0bSNuno Antunes.Ft void
7294a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly "lwkt_port_t port" "void (*rportfn)(lwkt_port_t, lwkt_msg_t)"
7394a4cc0bSNuno Antunes.Ft void
7494a4cc0bSNuno Antunes.Fn lwkt_initport_putonly "lwkt_port_t port" "int (*pportfn)(lwkt_port_t, lwkt_msg_t)"
7594a4cc0bSNuno Antunes.Ft void
7694a4cc0bSNuno Antunes.Fn lwkt_sendmsg "lwkt_port_t port" "lwkt_msg_t msg"
7794a4cc0bSNuno Antunes.Ft int
7894a4cc0bSNuno Antunes.Fn lwkt_domsg "lwkt_port_t port" "lwkt_msg_t msg" "int flags"
7994a4cc0bSNuno Antunes.Ft int
8094a4cc0bSNuno Antunes.Fn lwkt_forwardmsg "lwkt_port_t port" "lwkt_msg_t msg"
8194a4cc0bSNuno Antunes.Ft void
8294a4cc0bSNuno Antunes.Fn lwkt_abortmsg "lwkt_msg_t msg"
8394a4cc0bSNuno Antunes.In sys/msgport2.h
8494a4cc0bSNuno Antunes.Ft void
8594a4cc0bSNuno Antunes.Fn lwkt_initmsg "lwkt_msg_t msg" "lwkt_port_t rport" "int flags"
8694a4cc0bSNuno Antunes.Ft void
8794a4cc0bSNuno Antunes.Fn lwkt_initmsg_abortable "lwkt_msg_t msg" "lwkt_port_t rport" "int flags" "void (*abortfn)(lwkt_msg_t)"
8894a4cc0bSNuno Antunes.Ft int
8994a4cc0bSNuno Antunes.Fn lwkt_beginmsg "lwkt_port_t port" "lwkt_msg_t msg"
9094a4cc0bSNuno Antunes.Ft void
9194a4cc0bSNuno Antunes.Fn lwkt_replymsg "lwkt_msg_t msg" "int error"
9294a4cc0bSNuno Antunes.Ft void *
9394a4cc0bSNuno Antunes.Fn lwkt_getport "lwkt_port_t port"
9494a4cc0bSNuno Antunes.Ft void *
9594a4cc0bSNuno Antunes.Fn lwkt_waitport "lwkt_port_t port" "int flags"
9694a4cc0bSNuno Antunes.Ft int
9794a4cc0bSNuno Antunes.Fn lwkt_waitmsg "lwkt_msg_t msg" "int flags"
9894a4cc0bSNuno Antunes.Ft int
9994a4cc0bSNuno Antunes.Fn lwkt_checkmsg "lwkt_msg_t msg"
10094a4cc0bSNuno Antunes.Ft void
10194a4cc0bSNuno Antunes.Fn lwkt_dropmsg "lwkt_msg_t msg"
10294a4cc0bSNuno Antunes.Sh DESCRIPTION
103*c6e8b6c1SSascha WildnerLight weight kernel threads in
104*c6e8b6c1SSascha Wildner.Dx
105*c6e8b6c1SSascha Wildnermay use a message passing interface to communicate with each other.
10694a4cc0bSNuno AntunesMessages are sent to message ports.
10794a4cc0bSNuno AntunesAll light weight kernel threads have a built-in message port, but you may create
10894a4cc0bSNuno Antunesadditional ports if necessary.
10994a4cc0bSNuno AntunesThe following types of message ports are available:
11094a4cc0bSNuno Antunes.Bl -bullet
11194a4cc0bSNuno Antunes.It
11294a4cc0bSNuno Antunesthread ports
11394a4cc0bSNuno Antunes.It
11494a4cc0bSNuno Antunesspin ports
11594a4cc0bSNuno Antunes.It
11694a4cc0bSNuno Antunesserializer ports
11794a4cc0bSNuno Antunes.El
11894a4cc0bSNuno Antunes.Pp
11994a4cc0bSNuno AntunesPorts of type 'thread' are owned by a single light weight kernel thread.
12094a4cc0bSNuno AntunesWhen a message is sent to a port of type 'thread', only the owner of that port
12194a4cc0bSNuno Antunesis allowed to retrieve the message from it.
12294a4cc0bSNuno AntunesWhen a message is sent to a port of type 'spin' or to a port of
12394a4cc0bSNuno Antunestype 'serializer', multiple threads are allowed to check that port for new
12494a4cc0bSNuno Antunesmessages and compete to retrieve them.
12594a4cc0bSNuno AntunesYou define the port type when you initialize the port.
12694a4cc0bSNuno AntunesBy default, the built-in port of every light weight kernel thread is
12794a4cc0bSNuno Antunesautomatically initialized to type 'thread'.
12894a4cc0bSNuno Antunes.Pp
12994a4cc0bSNuno AntunesWhen a message is sent, the receiver should normally send back a reply.
13094a4cc0bSNuno AntunesThe reply is sent to the reply port that is registered on the original message.
13194a4cc0bSNuno AntunesMessages can be replied to synchronously or asynchronously.
13294a4cc0bSNuno AntunesThe sender may request a synchronous or asynchronous reply to the message,
13394a4cc0bSNuno Antuneshowever the target port will ultimately decide how the message will be treated.
13494a4cc0bSNuno Antunes.Sh MESSAGE FUNCTIONS
13594a4cc0bSNuno AntunesMessages must be initialized before being used.
13694a4cc0bSNuno AntunesThe
13794a4cc0bSNuno Antunes.Fn lwkt_initmsg
13894a4cc0bSNuno Antunesfunction initializes a message.
13994a4cc0bSNuno AntunesThe
14094a4cc0bSNuno Antunes.Fa rport
14194a4cc0bSNuno Antunesargument identifies the reply port which will be used for asynchronous replies.
14294a4cc0bSNuno AntunesThe
14394a4cc0bSNuno Antunes.Fa flags
14494a4cc0bSNuno Antunesargument sets any required flags for this message.
14594a4cc0bSNuno AntunesFlags passed this way will simply be or'ed to any already existing flags on the
14694a4cc0bSNuno Antunesmessage.
14794a4cc0bSNuno Antunes.Pp
14894a4cc0bSNuno AntunesThe
14994a4cc0bSNuno Antunes.Fn lwkt_initmsg_abortable
15094a4cc0bSNuno Antunesfunction is similar to
15194a4cc0bSNuno Antunes.Fn lwkt_initmsg
15294a4cc0bSNuno Antunesbut it takes an additional parameter
15394a4cc0bSNuno Antunes.Fa abortfn
15494a4cc0bSNuno Antuneswhich defines the abort function for this message.
15594a4cc0bSNuno Antunes.Pp
15694a4cc0bSNuno AntunesThe
15794a4cc0bSNuno Antunes.Fn lwkt_sendmsg
15894a4cc0bSNuno Antunesfunction requests an asynchronous reply, sends the message and returns
15994a4cc0bSNuno Antunesimmediately.
16094a4cc0bSNuno AntunesUnder normal circumstances, users of this function may always expect the reply
16194a4cc0bSNuno Antunesto be queued to the reply port registered on the message.
16294a4cc0bSNuno AntunesThe
16394a4cc0bSNuno Antunes.Fa port
16494a4cc0bSNuno Antunesargument defines the target port to which the
16594a4cc0bSNuno Antunes.Fa msg
16694a4cc0bSNuno Antunesmessage will be sent to.
16794a4cc0bSNuno Antunes.Pp
16894a4cc0bSNuno AntunesThe
16994a4cc0bSNuno Antunes.Fn lwkt_domsg
17094a4cc0bSNuno Antunesfunction requests a synchronous reply, sends the message and does not return
17194a4cc0bSNuno Antunesuntil the message has been replied to.
17294a4cc0bSNuno AntunesIf the target port supports synchronous reply, this function will return that
17394a4cc0bSNuno Antunesreply immediately.
17494a4cc0bSNuno AntunesIf not, and this is the most common case, this function will block and wait for the
17594a4cc0bSNuno Antunesreply to arrive and then return it.
17694a4cc0bSNuno AntunesThe
17794a4cc0bSNuno Antunes.Fa port
17894a4cc0bSNuno Antunesargument defines the target port to which the
17994a4cc0bSNuno Antunes.Fa msg
18094a4cc0bSNuno Antunesmessage will be sent to.
18194a4cc0bSNuno Antunes.Pp
18294a4cc0bSNuno AntunesThe
18394a4cc0bSNuno Antunes.Fn lwkt_replymsg
18494a4cc0bSNuno Antunesfunction replies to a message that was processed asynchronously by the target
18594a4cc0bSNuno Antunesport.
18694a4cc0bSNuno AntunesThis function is used by the thread on the receiving side.
18794a4cc0bSNuno AntunesThe
18894a4cc0bSNuno Antunes.Fa msg
18994a4cc0bSNuno Antunesargument is the message being replied to and the
19094a4cc0bSNuno Antunes.Fa error
19194a4cc0bSNuno Antunesargument is the actual response to send back.
19294a4cc0bSNuno Antunes.Pp
19394a4cc0bSNuno AntunesThe
19494a4cc0bSNuno Antunes.Fn lwkt_forwardmsg
19594a4cc0bSNuno Antunessimply forwards a message to another port.
19694a4cc0bSNuno AntunesThe
19794a4cc0bSNuno Antunes.Fa port
19894a4cc0bSNuno Antunesargument defines the target port to which the
19994a4cc0bSNuno Antunes.Fa msg
20094a4cc0bSNuno Antunesmessage will be sent to.
20194a4cc0bSNuno Antunes.Pp
20294a4cc0bSNuno AntunesIf a message has been initialized as abortable, you can use the
20394a4cc0bSNuno Antunes.Fn lwkt_abortmsg
20494a4cc0bSNuno Antunesfunction to try to abort it.
20594a4cc0bSNuno AntunesThe
20694a4cc0bSNuno Antunes.Fa abortfn
20794a4cc0bSNuno Antunespassed upon the initialisation with
20894a4cc0bSNuno Antunes.Fn lwkt_initmsg_abortable
20994a4cc0bSNuno Antuneswill be called by this function.
21094a4cc0bSNuno Antunes.Pp
21194a4cc0bSNuno AntunesThe
21294a4cc0bSNuno Antunes.Fn lwkt_dropmsg
21394a4cc0bSNuno Antuneswill dequeue the specified message from the target port it was sent to and makes
21494a4cc0bSNuno Antunesit look like it was never sent.
21594a4cc0bSNuno Antunes.Sh PORT FUNCTIONS
21694a4cc0bSNuno AntunesThe
21794a4cc0bSNuno Antunes.Fn lwkt_initport_thread
21894a4cc0bSNuno Antunesinitializes the specified
21994a4cc0bSNuno Antunes.Fa port
22094a4cc0bSNuno Antuneswith the default 'thread' port type handlers.
22194a4cc0bSNuno AntunesThe
22294a4cc0bSNuno Antunes.Fa td
22394a4cc0bSNuno Antunesargument defines the owner thread of the port and only that thread is allowed to
22494a4cc0bSNuno Antunesreceive messages on it.
22594a4cc0bSNuno Antunes.Pp
22694a4cc0bSNuno AntunesThe
22794a4cc0bSNuno Antunes.Fn lwkt_initport_spin
22894a4cc0bSNuno Antunesinitializes the specified
22994a4cc0bSNuno Antunes.Fa port
23094a4cc0bSNuno Antuneswith the default 'spin' port type handlers.
23194a4cc0bSNuno AntunesIt will also initialize the embedded spinlock within the
23294a4cc0bSNuno Antuneslwkt_port structure which will protect subsequent port access.
23394a4cc0bSNuno Antunes.Pp
23494a4cc0bSNuno AntunesThe
23594a4cc0bSNuno Antunes.Fn lwkt_initport_serialize
23694a4cc0bSNuno Antunesfunction initializes the specified
23794a4cc0bSNuno Antunes.Fa port
23894a4cc0bSNuno Antuneswith the default 'serializer' port type handlers.
23994a4cc0bSNuno AntunesThe subsequent port access will be protected by the passed
24094a4cc0bSNuno Antunes.Fa slz
24194a4cc0bSNuno Antunesserializer lock.
24294a4cc0bSNuno Antunes.Pp
24394a4cc0bSNuno AntunesThe
24494a4cc0bSNuno Antunes.Fn lwkt_getport
24594a4cc0bSNuno Antunesfunction checks the specified
24694a4cc0bSNuno Antunes.Fa port
24794a4cc0bSNuno Antunesfor available messages, dequeues the first one and returns it.
24894a4cc0bSNuno AntunesIf no messages are available then
24994a4cc0bSNuno Antunes.Dv NULL
25094a4cc0bSNuno Antunesis returned instead.
25194a4cc0bSNuno AntunesThis function is used by threads on the receiving side.
25294a4cc0bSNuno Antunes.Pp
25394a4cc0bSNuno AntunesThe
25494a4cc0bSNuno Antunes.Fn lwkt_waitport
25594a4cc0bSNuno Antunesfunction checks the specified
25694a4cc0bSNuno Antunes.Fa port
25794a4cc0bSNuno Antunesfor available messages, dequeues the first one and returns it.
25894a4cc0bSNuno AntunesIf no messages are available then the caller thread will sleep until a message
25994a4cc0bSNuno Antunesarrives on the specified port.
26094a4cc0bSNuno AntunesThe
26194a4cc0bSNuno Antunes.Fa flags
26294a4cc0bSNuno Antunesargument defines the flags used for the sleep.
26394a4cc0bSNuno AntunesThis function is used by threads on the receiving side.
26494a4cc0bSNuno Antunes.Sh SPECIAL PORT INITIALIZERS
26594a4cc0bSNuno AntunesThe
26694a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly
26794a4cc0bSNuno Antunesfunction initializes a
26894a4cc0bSNuno Antunes.Fa port
26994a4cc0bSNuno Antuneswhich is used only as reply port and may have a custom reply port handler.
27094a4cc0bSNuno AntunesThe reply port handler is specified with the
27194a4cc0bSNuno Antunes.Fa rportfn
27294a4cc0bSNuno Antunesargument.
27394a4cc0bSNuno AntunesAll the other handlers will panic the system if they are called.
27494a4cc0bSNuno AntunesThis initializer is normally used on ports for freeing resources after the
27594a4cc0bSNuno Antunesmessages have fulfilled their purpose.
27694a4cc0bSNuno Antunes.Pp
27794a4cc0bSNuno AntunesThe
27894a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly_null
27994a4cc0bSNuno Antunesfunction initializes a
28094a4cc0bSNuno Antunes.Fa port
28194a4cc0bSNuno Antuneswhich is used only as reply port.
28294a4cc0bSNuno AntunesThe reply port handler will simply mark the message as being done and will not
28394a4cc0bSNuno Antunesattempt to queue it.
28494a4cc0bSNuno AntunesAll the other handlers will panic the system if they are called.
28594a4cc0bSNuno Antunes.Pp
28694a4cc0bSNuno AntunesThe
28794a4cc0bSNuno Antunes.Fn lwkt_initport_putonly
28894a4cc0bSNuno Antunesfunction initializes a
28994a4cc0bSNuno Antunes.Fa port
29094a4cc0bSNuno Antuneswhich is used only as target port.
29194a4cc0bSNuno AntunesThe putport handler is specified with the
29294a4cc0bSNuno Antunes.Fa pportfn
29394a4cc0bSNuno Antunesargument.
29494a4cc0bSNuno AntunesAll the other handlers will panic the system if they are called.
29594a4cc0bSNuno Antunes.Pp
29694a4cc0bSNuno AntunesThe
29794a4cc0bSNuno Antunes.Fn lwkt_initport_panic
29894a4cc0bSNuno Antunesfunction initializes a
29994a4cc0bSNuno Antunes.Fa port
30094a4cc0bSNuno Antuneswhich will panic the system if any of its handlers are called.
30194a4cc0bSNuno AntunesThis function is sometimes used to initialize a reply-only port which does not
302*c6e8b6c1SSascha Wildnerexpect the messages to be replied to, e.g.\& when the messages should be
303*c6e8b6c1SSascha Wildnerconsumed by the receiving thread and never replied back.
30494a4cc0bSNuno Antunes.Sh INTERNAL MESSAGE FUNCTIONS
30594a4cc0bSNuno AntunesThe following functions are used only by the infrastructure, you should not
30694a4cc0bSNuno Antunesneed to use them directly unless in very rare cases.
30794a4cc0bSNuno Antunes.Pp
30894a4cc0bSNuno AntunesThe
30994a4cc0bSNuno Antunes.Fn lwkt_beginmsg
31094a4cc0bSNuno Antunesfunction simply calls the target port's putport handler.
31194a4cc0bSNuno AntunesThis function is only called by the
31294a4cc0bSNuno Antunes.Fn lwkt_sendmsg
31394a4cc0bSNuno Antunesand
31494a4cc0bSNuno Antunes.Fn lwkt_replymsg
31594a4cc0bSNuno Antunesfunctions.
31694a4cc0bSNuno AntunesThe putport handler returns
31794a4cc0bSNuno Antunes.Er EASYNC
31894a4cc0bSNuno Antunesfor messages processed asynchronously or any other value for messages processed
31994a4cc0bSNuno Antunessynchronously.
32094a4cc0bSNuno AntunesThat return value of the putport handler is propagated by this function.
32194a4cc0bSNuno AntunesThe
32294a4cc0bSNuno Antunes.Fa port
32394a4cc0bSNuno Antunesargument defines the target port to which the
32494a4cc0bSNuno Antunes.Fa msg
32594a4cc0bSNuno Antunesmessage will be sent to.
32694a4cc0bSNuno Antunes.Pp
32794a4cc0bSNuno AntunesThe
32894a4cc0bSNuno Antunes.Fn lwkt_waitmsg
32994a4cc0bSNuno Antunesfunction puts the caller to sleep until the specified
33094a4cc0bSNuno Antunes.Fa msg
33194a4cc0bSNuno Antunesmessage has been replied to.
33294a4cc0bSNuno AntunesThe
33394a4cc0bSNuno Antunes.Fa flags
33494a4cc0bSNuno Antunesargument defines the flags used for the sleep.
33594a4cc0bSNuno Antunes.Sh FILES
33694a4cc0bSNuno AntunesThe LWKT msgport implementation resides in
33794a4cc0bSNuno Antunes.Pa sys/kern/lwkt_msgport.c .
33894a4cc0bSNuno Antunes.Sh EXAMPLES
33994a4cc0bSNuno Antunes.Bd -literal
34094a4cc0bSNuno Antunes/*
34194a4cc0bSNuno Antunes * Example 1: per CPU threads.
34294a4cc0bSNuno Antunes *
34394a4cc0bSNuno Antunes */
34494a4cc0bSNuno Antunes
34594a4cc0bSNuno Antunes#include <sys/thread.h>
34694a4cc0bSNuno Antunes#include <sys/msgport.h>
34794a4cc0bSNuno Antunes#include <sys/msgport2.h>
34894a4cc0bSNuno Antunes
34994a4cc0bSNuno Antunesstatic void my_service_loop(void *dummy);
35094a4cc0bSNuno Antuneslwkt_port_t my_service_portfn(int cpu);
35194a4cc0bSNuno Antunesvoid my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
35294a4cc0bSNuno Antunesint my_service_domsg(lwkt_msg_t lmsg, int cpu);
35394a4cc0bSNuno Antunes
35494a4cc0bSNuno Antunes/* Array of per-CPU target ports */
35594a4cc0bSNuno Antunesstruct lwkt_port *my_service_ports[MAXCPU];
35694a4cc0bSNuno Antunes
35794a4cc0bSNuno Antunes/*
35894a4cc0bSNuno Antunes * Create per-cpu threads for handling msg processing.  Remember that built-in
35994a4cc0bSNuno Antunes * lwkt ports are automatically initialized to type 'thread' so we don't need
36094a4cc0bSNuno Antunes * to initialize them explicitly.
36194a4cc0bSNuno Antunes */
36294a4cc0bSNuno Antunesstatic void
36394a4cc0bSNuno Antunesmy_per_cpu_service_init(void)
36494a4cc0bSNuno Antunes{
36594a4cc0bSNuno Antunes	int i;
36694a4cc0bSNuno Antunes	thread_t td;
36794a4cc0bSNuno Antunes
36894a4cc0bSNuno Antunes	for (i = 0; i < ncpus; ++i) {
36994a4cc0bSNuno Antunes		lwkt_create(my_service_loop, NULL, &td,
37094a4cc0bSNuno Antunes			    NULL, 0, i, "myservice_cpu %d", i);
37194a4cc0bSNuno Antunes		my_service_ports[i] = &td->td_msgport;
37294a4cc0bSNuno Antunes	}
37394a4cc0bSNuno Antunes}
37494a4cc0bSNuno Antunes
37594a4cc0bSNuno Antunes/*
37694a4cc0bSNuno Antunes * This is the routine executed by the service threads on each CPU.
37794a4cc0bSNuno Antunes */
37894a4cc0bSNuno Antunesstatic void
37994a4cc0bSNuno Antunesmy_service_loop(void *dummy __unused)
38094a4cc0bSNuno Antunes{
38194a4cc0bSNuno Antunes	lwkt_msg_t msg;
38294a4cc0bSNuno Antunes	thread_t td = curthread;
38394a4cc0bSNuno Antunes	int cpu = curthread->td_gd->gd_cpuid;
38494a4cc0bSNuno Antunes
38594a4cc0bSNuno Antunes	while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
38694a4cc0bSNuno Antunes		/* Do some work in the receiver thread context. */
38794a4cc0bSNuno Antunes		kprintf("Received message on CPU %d.\en", cpu);
38894a4cc0bSNuno Antunes
38994a4cc0bSNuno Antunes		/* And finally reply to the message. */
39094a4cc0bSNuno Antunes		lwkt_replymsg(msg, 0);
39194a4cc0bSNuno Antunes	}
39294a4cc0bSNuno Antunes}
39394a4cc0bSNuno Antunes
39494a4cc0bSNuno Antunes/*
39594a4cc0bSNuno Antunes * Given a CPU id, return our respective service port.
39694a4cc0bSNuno Antunes */
39794a4cc0bSNuno Antunes__inline lwkt_port_t
39894a4cc0bSNuno Antunesmy_service_portfn(int cpu)
39994a4cc0bSNuno Antunes{
40094a4cc0bSNuno Antunes	return my_service_ports[cpu];
40194a4cc0bSNuno Antunes}
40294a4cc0bSNuno Antunes
40394a4cc0bSNuno Antunes/*
40494a4cc0bSNuno Antunes * Send an asynchronous message to the service thread on a specific CPU.
40594a4cc0bSNuno Antunes */
40694a4cc0bSNuno Antunesvoid
40794a4cc0bSNuno Antunesmy_service_sendmsg(lwkt_msg_t lmsg, int cpu)
40894a4cc0bSNuno Antunes{
40994a4cc0bSNuno Antunes	KKASSERT(cpu < ncpus);
41094a4cc0bSNuno Antunes	lwkt_sendmsg(my_service_portfn(cpu), lmsg);
41194a4cc0bSNuno Antunes}
41294a4cc0bSNuno Antunes
41394a4cc0bSNuno Antunes/*
41494a4cc0bSNuno Antunes * Send a synchronous message to the service thread on a specific CPU.
41594a4cc0bSNuno Antunes */
41694a4cc0bSNuno Antunesint
41794a4cc0bSNuno Antunesmy_service_domsg(lwkt_msg_t lmsg, int cpu)
41894a4cc0bSNuno Antunes{
41994a4cc0bSNuno Antunes	KKASSERT(cpu < ncpus);
42094a4cc0bSNuno Antunes	return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
42194a4cc0bSNuno Antunes}
42294a4cc0bSNuno Antunes
42394a4cc0bSNuno Antunes/*
42494a4cc0bSNuno Antunes * Example use case. Initialize the service threads and send each one a
42594a4cc0bSNuno Antunes * message.
42694a4cc0bSNuno Antunes */
42794a4cc0bSNuno Antunesstatic void
42894a4cc0bSNuno Antunesmod_load(void)
42994a4cc0bSNuno Antunes{
43094a4cc0bSNuno Antunes	lwkt_msg	lmsg;
43194a4cc0bSNuno Antunes	lwkt_port_t	builtin_port = &curthread->td_msgport;
43294a4cc0bSNuno Antunes	int		i;
43394a4cc0bSNuno Antunes
43494a4cc0bSNuno Antunes	my_per_cpu_service_init();
43594a4cc0bSNuno Antunes	for (i=0; i<ncpus; ++i) {
43694a4cc0bSNuno Antunes		kprintf("Sending msg to CPU %d.\en", i);
43794a4cc0bSNuno Antunes		lwkt_initmsg(&lmsg, builtin_port, 0);
43894a4cc0bSNuno Antunes		my_service_domsg(&lmsg, i);
43994a4cc0bSNuno Antunes	}
44094a4cc0bSNuno Antunes}
44194a4cc0bSNuno Antunes
44294a4cc0bSNuno Antunes/*
44394a4cc0bSNuno Antunes * Example 2: Dynamic allocated message passing with automatic free.
44494a4cc0bSNuno Antunes *
44594a4cc0bSNuno Antunes * This scenario is used when resources need to be freed after the message
44694a4cc0bSNuno Antunes * has been replied to. Features:
44794a4cc0bSNuno Antunes * - An argument is passed within the message.
44894a4cc0bSNuno Antunes * - Messages are allocated with kmalloc(). Replying to the msg, kfree()s it.
44994a4cc0bSNuno Antunes */
45094a4cc0bSNuno Antunes
45194a4cc0bSNuno Antunes#include <sys/thread.h>
45294a4cc0bSNuno Antunes#include <sys/msgport.h>
45394a4cc0bSNuno Antunes#include <sys/msgport2.h>
45494a4cc0bSNuno Antunes
45594a4cc0bSNuno Antunesvoid my_service_queue(void *arg);
45694a4cc0bSNuno Antunes
45794a4cc0bSNuno Antuneslwkt_port my_autofree_rport;
45894a4cc0bSNuno Antuneslwkt_port_t my_service_port;
45994a4cc0bSNuno Antunes
46094a4cc0bSNuno Antunes/*
46194a4cc0bSNuno Antunes * Use this function to send messages with a void * argument to our
46294a4cc0bSNuno Antunes * service thread.
46394a4cc0bSNuno Antunes */
46494a4cc0bSNuno Antunesvoid
46594a4cc0bSNuno Antunesmy_service_queue(void *arg)
46694a4cc0bSNuno Antunes{
46794a4cc0bSNuno Antunes	lwkt_msg_t msg;
46894a4cc0bSNuno Antunes
46994a4cc0bSNuno Antunes	msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
47094a4cc0bSNuno Antunes
47194a4cc0bSNuno Antunes	/* Set reply port to autofree. */
47294a4cc0bSNuno Antunes	lwkt_initmsg(msg, &my_autofree_rport, 0);
47394a4cc0bSNuno Antunes
47494a4cc0bSNuno Antunes	/* Attach the argument to the message. */
47594a4cc0bSNuno Antunes	msg->u.ms_resultp = arg;
47694a4cc0bSNuno Antunes
47794a4cc0bSNuno Antunes	/* Send it. */
47894a4cc0bSNuno Antunes	lwkt_sendmsg(my_service_port, msg);
47994a4cc0bSNuno Antunes}
48094a4cc0bSNuno Antunes
48194a4cc0bSNuno Antunes/*
48294a4cc0bSNuno Antunes * This is the routine executed by our service thread.
48394a4cc0bSNuno Antunes */
48494a4cc0bSNuno Antunesstatic void
48594a4cc0bSNuno Antunesmy_service_loop(void *dummy __unused)
48694a4cc0bSNuno Antunes{
48794a4cc0bSNuno Antunes	lwkt_msg_t msg;
48894a4cc0bSNuno Antunes	thread_t td = curthread;
48994a4cc0bSNuno Antunes
49094a4cc0bSNuno Antunes	while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
49194a4cc0bSNuno Antunes		/*
49294a4cc0bSNuno Antunes		 * Do some work in the receiver thread context.  In this
49394a4cc0bSNuno Antunes		 * example, the sender wrote his name in the argument he
49494a4cc0bSNuno Antunes		 * sent us.  We print it here.
49594a4cc0bSNuno Antunes		 */
49694a4cc0bSNuno Antunes		char *arg = msg->u.ms_resultp;
49794a4cc0bSNuno Antunes		kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm, arg);
49894a4cc0bSNuno Antunes
49994a4cc0bSNuno Antunes		/* And finally reply to the message. */
50094a4cc0bSNuno Antunes		lwkt_replymsg(msg, 0);
50194a4cc0bSNuno Antunes	}
50294a4cc0bSNuno Antunes}
50394a4cc0bSNuno Antunes
50494a4cc0bSNuno Antunesstatic void
50594a4cc0bSNuno Antunesmy_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
50694a4cc0bSNuno Antunes{
50794a4cc0bSNuno Antunes	kfree(msg->u.ms_resultp, M_TEMP);
50894a4cc0bSNuno Antunes	kfree(msg, M_TEMP);
50994a4cc0bSNuno Antunes}
51094a4cc0bSNuno Antunes
51194a4cc0bSNuno Antunesstatic void
51294a4cc0bSNuno Antunesmy_service_init(void)
51394a4cc0bSNuno Antunes{
51494a4cc0bSNuno Antunes	thread_t tdp;
51594a4cc0bSNuno Antunes
51694a4cc0bSNuno Antunes	/* Initialize our auto free reply port. */
51794a4cc0bSNuno Antunes	lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
51894a4cc0bSNuno Antunes
51994a4cc0bSNuno Antunes	/* Create our service thread on CPU 0. */
52094a4cc0bSNuno Antunes	lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
52194a4cc0bSNuno Antunes	my_service_port = &tdp->td_msgport;
52294a4cc0bSNuno Antunes}
52394a4cc0bSNuno Antunes
52494a4cc0bSNuno Antunes/*
52594a4cc0bSNuno Antunes * Example use case. Initialize the service and send the current thread name
52694a4cc0bSNuno Antunes * to the service thread.
52794a4cc0bSNuno Antunes */
52894a4cc0bSNuno Antunesstatic void
52994a4cc0bSNuno Antunesmod_load(void)
53094a4cc0bSNuno Antunes{
53194a4cc0bSNuno Antunes	void *arg;
53294a4cc0bSNuno Antunes	int len;
53394a4cc0bSNuno Antunes
53494a4cc0bSNuno Antunes	my_service_init();
53594a4cc0bSNuno Antunes	len = strlen(curthread->td_comm);
53694a4cc0bSNuno Antunes	arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
53794a4cc0bSNuno Antunes	bcopy(curthread->td_comm, arg, len + 1);
53894a4cc0bSNuno Antunes	kprintf("%s: Sending message.\en", curthread->td_comm);
53994a4cc0bSNuno Antunes	my_service_queue(arg);
54094a4cc0bSNuno Antunes}
54194a4cc0bSNuno Antunes.Ed
54294a4cc0bSNuno Antunes.Sh NOTES
54394a4cc0bSNuno AntunesAll the default putport handlers (used when a message is sent) currently
544*c6e8b6c1SSascha Wildnerimplement asynchronous putports only, i.e.\& all *_putport() handlers return
54594a4cc0bSNuno Antunes.Er EASYNC .
54694a4cc0bSNuno AntunesYou can still have synchronous putport handlers (which are run in the sender's
54794a4cc0bSNuno Antunescontext) but you have to implement the function yourself and then override the
54894a4cc0bSNuno Antunesdefault.
54994a4cc0bSNuno Antunes.Pp
55094a4cc0bSNuno AntunesPort handler functions can be overridden with custom functions if required.
55194a4cc0bSNuno AntunesYou can override the default putport handler by either using the
55294a4cc0bSNuno Antunes.Fn lwkt_initport_putonly
55394a4cc0bSNuno Antunesinitializer, or by manipulating the mp_putport handler pointer directly on the
55494a4cc0bSNuno Antuneslwkt_port structure.
55594a4cc0bSNuno Antunes.Pp
55694a4cc0bSNuno AntunesThere is one such case where the putport handler is overridden in
55794a4cc0bSNuno Antunes.Pa sys/kern/netisr.c .
55894a4cc0bSNuno AntunesIn that case, the putport handler is overridden to detect a loopback message
55994a4cc0bSNuno Antunes(when the target port belongs to the sending thread).
56094a4cc0bSNuno AntunesThis special putport handler turns the sent message into a direct function call
56194a4cc0bSNuno Antunesinstead of queueing it to the port.
56294a4cc0bSNuno Antunes.Pp
56394a4cc0bSNuno AntunesThe
56494a4cc0bSNuno Antunes.Fn lwkt_replymsg
565*c6e8b6c1SSascha Wildnerfunction works differently depending on the original message request.
566*c6e8b6c1SSascha WildnerIf the
56794a4cc0bSNuno Antunesmessage was originally an asynchronous request, the reply will be queued to the
568*c6e8b6c1SSascha Wildnersender's reply port.
569*c6e8b6c1SSascha WildnerIf the message was originally a synchronous request, then
57094a4cc0bSNuno Antunesthis function will just write the error response on the message and wake up the
57194a4cc0bSNuno Antuneswaiter without queueing the message to the reply port.
57294a4cc0bSNuno AntunesThere is no need to queue in the synchronous request case because the original
57394a4cc0bSNuno Antunessender had blocked waiting on this specific message with
57494a4cc0bSNuno Antunes.Fn lwkt_domsg .
57594a4cc0bSNuno Antunes.Pp
57694a4cc0bSNuno AntunesAs is the case with putport handler, the replyport handler can also be
57794a4cc0bSNuno Antunesoverridden.
57894a4cc0bSNuno AntunesYou override the default replyport handler by using the
57994a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly
58094a4cc0bSNuno Antunesor the
58194a4cc0bSNuno Antunes.Fn lwkt_initport_replyonly_null
58294a4cc0bSNuno Antunesport initializers, or by manipulating the mp_replyport handler pointer directly
58394a4cc0bSNuno Antuneson the lwkt_port structure.
58494a4cc0bSNuno Antunes.Pp
58594a4cc0bSNuno AntunesThe sent message structure is reused for replies.
58694a4cc0bSNuno AntunesWhen a message is replied to, the error response is written on the message
58794a4cc0bSNuno Antuneswhich is subsequently sent to the reply port.
58894a4cc0bSNuno Antunes.Sh SEE ALSO
58994a4cc0bSNuno Antunes.Xr serializer 9 ,
59094a4cc0bSNuno Antunes.Xr spinlock 9
59194a4cc0bSNuno Antunes.Sh HISTORY
59294a4cc0bSNuno AntunesThe LWKT msgport interface first appeared in
59394a4cc0bSNuno Antunes.Dx 1.0 .
59494a4cc0bSNuno Antunes.Sh AUTHORS
59594a4cc0bSNuno Antunes.An -nosplit
59694a4cc0bSNuno AntunesThe
59794a4cc0bSNuno Antunes.Nm msgport
59894a4cc0bSNuno Antunesmessage passing interface implementation was written by
59994a4cc0bSNuno Antunes.An Matthew Dillon .
60094a4cc0bSNuno AntunesThis manual page was written by
60194a4cc0bSNuno Antunes.An Nuno Antunes .
602