3ac530566cef76ea02ff058deb67eb91b60abfe2
[dragonfly.git] / sys / sys / msgport.h
1 /*
2  * SYS/MSGPORT.H
3  *
4  *      Implements LWKT messages and ports.
5  * 
6  * $DragonFly: src/sys/sys/msgport.h,v 1.16 2004/04/15 00:50:05 dillon Exp $
7  */
8
9 #ifndef _SYS_MSGPORT_H_
10 #define _SYS_MSGPORT_H_
11
12 #ifndef _SYS_QUEUE_H_
13 #include <sys/queue.h>          /* TAILQ_* macros */
14 #endif
15 #ifndef _SYS_STDINT_H_
16 #include <sys/stdint.h>
17 #endif
18
19 struct lwkt_msg;
20 struct lwkt_port;
21 struct thread;
22
23 typedef struct lwkt_msg         *lwkt_msg_t;
24 typedef struct lwkt_port        *lwkt_port_t;
25
26 typedef TAILQ_HEAD(lwkt_msg_queue, lwkt_msg) lwkt_msg_queue;
27
28 /*
29  * The standard message and port structure for communications between
30  * threads.  See kern/lwkt_msgport.c for documentation on how messages and
31  * ports work.
32  *
33  * For the most part a message may only be manipulated by whomever currently
34  * owns it, which generally means the originating port if the message has
35  * not been sent yet or has been replied, and the target port if the message
36  * has been sent and/or is undergoing processing.
37  *
38  * The one exception to this rule is an abort.  Aborts must be initiated
39  * by the originator and may 'chase' the target (especially if a message
40  * is being forwarded), potentially even 'chase' the message all the way
41  * back to the originator if it races against the target replying the
42  * message.  The ms_abort_port field is the only field that may be modified
43  * by the originator or intermediate target (when the abort is chasing
44  * a forwarding or reply op).  An abort may cause a reply to be delayed
45  * until the abort catches up to it.
46  *
47  * Finally, note that an abort can requeue a message to its current target
48  * port after the message has been pulled off of it, so you CANNOT use
49  * ms_node for your own purposes after you have pulled a message request
50  * off its port.
51  *
52  * NOTE! 64-bit-align this structure.
53  */
54 typedef struct lwkt_msg {
55     TAILQ_ENTRY(lwkt_msg) ms_node;      /* link node (see note above) */
56     union {
57         struct lwkt_msg *ms_next;       /* chaining / cache */
58         union sysunion  *ms_sysunnext;  /* chaining / cache */
59         struct lwkt_msg *ms_umsg;       /* user message (UVA address) */
60     } opaque;
61     lwkt_port_t ms_target_port;         /* current target or relay port */
62     lwkt_port_t ms_reply_port;          /* async replies returned here */
63     lwkt_port_t ms_abort_port;          /* abort chasing port */
64     int         ms_cmd;                 /* message command */
65     int         ms_flags;               /* message flags */
66 #define ms_copyout_start        ms_msgsize
67     int         ms_msgsize;             /* size of message */
68     int         ms_error;               /* positive error code or 0 */
69     union {
70         void    *ms_resultp;            /* misc pointer data or result */
71         int     ms_result;              /* standard 'int'eger result */
72         long    ms_lresult;             /* long result */
73         int     ms_fds[2];              /* two int bit results */
74         __int32_t ms_result32;          /* 32 bit result */
75         __int64_t ms_result64;          /* 64 bit result */
76         __off_t ms_offset;              /* off_t result */
77     } u;
78 #define ms_copyout_end  ms_pad[0]
79     int         ms_pad[2];              /* future use */
80 } lwkt_msg;
81
82 #define ms_copyout_size (offsetof(struct lwkt_msg, ms_copyout_end) - offsetof(struct lwkt_msg, ms_copyout_start))
83
84 #define MSGF_DONE       0x0001          /* asynch message is complete */
85 #define MSGF_REPLY1     0x0002          /* asynch message has been returned */
86 #define MSGF_QUEUED     0x0004          /* message has been queued sanitychk */
87 #define MSGF_ASYNC      0x0008          /* sync/async hint */
88 #define MSGF_ABORTED    0x0010          /* message was aborted flag */
89 #define MSGF_PCATCH     0x0020          /* catch proc signal while waiting */
90 #define MSGF_REPLY2     0x0040          /* reply processed by rport cpu */
91
92 #define MSG_CMD_CDEV    0x00010000
93 #define MSG_CMD_VFS     0x00020000
94 #define MSG_CMD_SYSCALL 0x00030000
95 #define MSG_CMD_NETMSG  0x00040000
96 #define MSG_SUBCMD_MASK 0x0000FFFF
97
98 #ifdef _KERNEL
99 #ifdef MALLOC_DECLARE
100 MALLOC_DECLARE(M_LWKTMSG);
101 #endif
102 #endif
103
104 typedef struct lwkt_port {
105     lwkt_msg_queue      mp_msgq;
106     int                 mp_flags;
107     int                 mp_refs;        /* references to port structure */
108     struct thread       *mp_td;
109     int                 (*mp_putport)(lwkt_port_t, lwkt_msg_t);
110     void *              (*mp_waitport)(lwkt_port_t, lwkt_msg_t);
111     void                (*mp_replyport)(lwkt_port_t, lwkt_msg_t);
112     void                (*mp_abortport)(lwkt_port_t, lwkt_msg_t);
113 } lwkt_port;
114
115 #define MSGPORTF_WAITING        0x0001
116
117 /*
118  * These functions are good for userland as well as the kernel.  The 
119  * messaging function support for userland is provided by the kernel's
120  * kern/lwkt_msgport.c.  The port functions are provided by userland.
121  */
122 void lwkt_initport(lwkt_port_t, struct thread *);
123 void lwkt_sendmsg(lwkt_port_t, lwkt_msg_t);
124 int lwkt_domsg(lwkt_port_t, lwkt_msg_t);
125 int lwkt_forwardmsg(lwkt_port_t, lwkt_msg_t);
126 void lwkt_abortmsg(lwkt_msg_t);
127 void *lwkt_getport(lwkt_port_t);
128
129 int lwkt_default_putport(lwkt_port_t port, lwkt_msg_t msg);
130 void *lwkt_default_waitport(lwkt_port_t port, lwkt_msg_t msg);
131 void lwkt_default_replyport(lwkt_port_t port, lwkt_msg_t msg);
132 void lwkt_default_abortport(lwkt_port_t port, lwkt_msg_t msg);
133
134 #endif