Commit | Line | Data |
---|---|---|
ece04fd0 MD |
1 | /* |
2 | * SYS/MSGPORT.H | |
3 | * | |
4 | * Implements LWKT messages and ports. | |
5 | * | |
b44419cb | 6 | * $DragonFly: src/sys/sys/msgport.h,v 1.17 2004/04/20 01:52:24 dillon Exp $ |
ece04fd0 MD |
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 | |
05220613 MD |
15 | #ifndef _SYS_STDINT_H_ |
16 | #include <sys/stdint.h> | |
17 | #endif | |
ece04fd0 MD |
18 | |
19 | struct lwkt_msg; | |
20 | struct lwkt_port; | |
335dda38 | 21 | struct thread; |
ece04fd0 MD |
22 | |
23 | typedef struct lwkt_msg *lwkt_msg_t; | |
24 | typedef struct lwkt_port *lwkt_port_t; | |
25 | ||
335dda38 MD |
26 | typedef TAILQ_HEAD(lwkt_msg_queue, lwkt_msg) lwkt_msg_queue; |
27 | ||
b44419cb MD |
28 | /* |
29 | * LWKT command message operator type. This type holds a message's | |
30 | * 'command'. The command format is opaque to the LWKT messaging system, | |
31 | * meaning that it is specific to whatever convention the API chooses. | |
32 | * By convention lwkt_cmd_t is passed by value and is expected to | |
33 | * efficiently fit into a machine register. | |
34 | */ | |
35 | typedef union lwkt_cmd { | |
36 | int cm_op; | |
37 | int (*cm_func)(lwkt_msg_t msg); | |
38 | } lwkt_cmd_t; | |
39 | ||
ece04fd0 MD |
40 | /* |
41 | * The standard message and port structure for communications between | |
42 | * threads. See kern/lwkt_msgport.c for documentation on how messages and | |
43 | * ports work. | |
a64ba182 | 44 | * |
e7906ee5 MD |
45 | * For the most part a message may only be manipulated by whomever currently |
46 | * owns it, which generally means the originating port if the message has | |
47 | * not been sent yet or has been replied, and the target port if the message | |
48 | * has been sent and/or is undergoing processing. | |
49 | * | |
50 | * The one exception to this rule is an abort. Aborts must be initiated | |
51 | * by the originator and may 'chase' the target (especially if a message | |
52 | * is being forwarded), potentially even 'chase' the message all the way | |
53 | * back to the originator if it races against the target replying the | |
54 | * message. The ms_abort_port field is the only field that may be modified | |
55 | * by the originator or intermediate target (when the abort is chasing | |
56 | * a forwarding or reply op). An abort may cause a reply to be delayed | |
57 | * until the abort catches up to it. | |
58 | * | |
b44419cb MD |
59 | * Messages which support an abort will have MSGF_ABORTABLE set, indicating |
60 | * that the ms_abort field has been initialized. An abort will cause a | |
61 | * message to be requeued to the target port so the target sees the same | |
62 | * message twice: once during initial processing of the message, and a | |
63 | * second time to process the abort request. lwkt_getport() will detect | |
64 | * the requeued abort and will copy ms_abort into ms_cmd before returning | |
65 | * the requeued message the second time. This makes target processing a | |
66 | * whole lot less complex. | |
e7906ee5 | 67 | * |
a64ba182 | 68 | * NOTE! 64-bit-align this structure. |
ece04fd0 MD |
69 | */ |
70 | typedef struct lwkt_msg { | |
e7906ee5 | 71 | TAILQ_ENTRY(lwkt_msg) ms_node; /* link node (see note above) */ |
4fd10eb6 | 72 | union { |
c7114eea | 73 | struct lwkt_msg *ms_next; /* chaining / cache */ |
245e4f17 | 74 | union sysunion *ms_sysunnext; /* chaining / cache */ |
c7114eea | 75 | struct lwkt_msg *ms_umsg; /* user message (UVA address) */ |
4fd10eb6 | 76 | } opaque; |
df2244e3 | 77 | lwkt_port_t ms_target_port; /* current target or relay port */ |
e7906ee5 MD |
78 | lwkt_port_t ms_reply_port; /* async replies returned here */ |
79 | lwkt_port_t ms_abort_port; /* abort chasing port */ | |
b44419cb MD |
80 | lwkt_cmd_t ms_cmd; /* message command operator */ |
81 | lwkt_cmd_t ms_abort; /* message abort operator */ | |
df2244e3 MD |
82 | int ms_flags; /* message flags */ |
83 | #define ms_copyout_start ms_msgsize | |
f6bf3af1 | 84 | int ms_msgsize; /* size of message */ |
df2244e3 | 85 | int ms_error; /* positive error code or 0 */ |
a64ba182 | 86 | union { |
df2244e3 | 87 | void *ms_resultp; /* misc pointer data or result */ |
90b9818c MD |
88 | int ms_result; /* standard 'int'eger result */ |
89 | long ms_lresult; /* long result */ | |
90 | int ms_fds[2]; /* two int bit results */ | |
05220613 MD |
91 | __int32_t ms_result32; /* 32 bit result */ |
92 | __int64_t ms_result64; /* 64 bit result */ | |
93 | __off_t ms_offset; /* off_t result */ | |
a64ba182 | 94 | } u; |
245e4f17 | 95 | #define ms_copyout_end ms_pad[0] |
a64ba182 | 96 | int ms_pad[2]; /* future use */ |
ece04fd0 MD |
97 | } lwkt_msg; |
98 | ||
245e4f17 MD |
99 | #define ms_copyout_size (offsetof(struct lwkt_msg, ms_copyout_end) - offsetof(struct lwkt_msg, ms_copyout_start)) |
100 | ||
ece04fd0 | 101 | #define MSGF_DONE 0x0001 /* asynch message is complete */ |
e7906ee5 | 102 | #define MSGF_REPLY1 0x0002 /* asynch message has been returned */ |
ece04fd0 MD |
103 | #define MSGF_QUEUED 0x0004 /* message has been queued sanitychk */ |
104 | #define MSGF_ASYNC 0x0008 /* sync/async hint */ | |
b44419cb | 105 | #define MSGF_ABORTED 0x0010 /* indicate pending abort */ |
e7906ee5 MD |
106 | #define MSGF_PCATCH 0x0020 /* catch proc signal while waiting */ |
107 | #define MSGF_REPLY2 0x0040 /* reply processed by rport cpu */ | |
b44419cb MD |
108 | #define MSGF_ABORTABLE 0x0080 /* message supports abort */ |
109 | #define MSGF_RETRIEVED 0x0100 /* message retrieved on target */ | |
ece04fd0 | 110 | |
335dda38 MD |
111 | #define MSG_CMD_CDEV 0x00010000 |
112 | #define MSG_CMD_VFS 0x00020000 | |
113 | #define MSG_CMD_SYSCALL 0x00030000 | |
114 | #define MSG_SUBCMD_MASK 0x0000FFFF | |
115 | ||
9eeaa8a9 JH |
116 | #ifdef _KERNEL |
117 | #ifdef MALLOC_DECLARE | |
118 | MALLOC_DECLARE(M_LWKTMSG); | |
119 | #endif | |
120 | #endif | |
121 | ||
ece04fd0 MD |
122 | typedef struct lwkt_port { |
123 | lwkt_msg_queue mp_msgq; | |
124 | int mp_flags; | |
245e4f17 | 125 | int mp_refs; /* references to port structure */ |
335dda38 | 126 | struct thread *mp_td; |
df2244e3 MD |
127 | int (*mp_putport)(lwkt_port_t, lwkt_msg_t); |
128 | void * (*mp_waitport)(lwkt_port_t, lwkt_msg_t); | |
129 | void (*mp_replyport)(lwkt_port_t, lwkt_msg_t); | |
130 | void (*mp_abortport)(lwkt_port_t, lwkt_msg_t); | |
ece04fd0 MD |
131 | } lwkt_port; |
132 | ||
133 | #define MSGPORTF_WAITING 0x0001 | |
134 | ||
df2244e3 MD |
135 | /* |
136 | * These functions are good for userland as well as the kernel. The | |
137 | * messaging function support for userland is provided by the kernel's | |
138 | * kern/lwkt_msgport.c. The port functions are provided by userland. | |
139 | */ | |
984ccc17 MD |
140 | void lwkt_initport(lwkt_port_t, struct thread *); |
141 | void lwkt_sendmsg(lwkt_port_t, lwkt_msg_t); | |
142 | int lwkt_domsg(lwkt_port_t, lwkt_msg_t); | |
e7906ee5 MD |
143 | int lwkt_forwardmsg(lwkt_port_t, lwkt_msg_t); |
144 | void lwkt_abortmsg(lwkt_msg_t); | |
984ccc17 MD |
145 | void *lwkt_getport(lwkt_port_t); |
146 | ||
147 | int lwkt_default_putport(lwkt_port_t port, lwkt_msg_t msg); | |
148 | void *lwkt_default_waitport(lwkt_port_t port, lwkt_msg_t msg); | |
149 | void lwkt_default_replyport(lwkt_port_t port, lwkt_msg_t msg); | |
150 | void lwkt_default_abortport(lwkt_port_t port, lwkt_msg_t msg); | |
ece04fd0 | 151 | |
ece04fd0 | 152 | #endif |