FreeBSD/Linux Kernel Cross Reference
sys/ipc/ipc_port.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: ipc_port.h,v $
29 * Revision 2.14 92/04/06 01:16:28 rpd
30 * Fixed ip_msgcount overflow problem by changing it
31 * and ip_qlimit to be mach_port_msgcount_t.
32 * Added ipc_port_lock_mqueue.
33 * [92/04/06 rpd]
34 *
35 * Revision 2.13 92/03/10 16:26:18 jsb
36 * Merged in norma branch changes as of NORMA_MK7:
37 * Removed token-related fields. Added fields for receive-right migration
38 * and xmm support. Added ip_nsproxy* macros for no-senders support.
39 * [92/03/09 13:14:35 jsb]
40 *
41 * Revision 2.12 91/12/14 14:28:26 jsb
42 * NORMA_IPC: replaced dummy port struct fields with real names.
43 *
44 * Revision 2.11 91/11/14 16:56:20 rpd
45 * Added ipc_fields.h hack, with fields in struct ipc_port to match.
46 * Added IP_NORMA_IS_PROXY macro.
47 * [91/11/00 jsb]
48 *
49 * Revision 2.10 91/10/09 16:10:01 af
50 * Added (unconditional) ipc_port_print declaration.
51 * [91/09/02 rpd]
52 *
53 * Revision 2.9 91/08/28 11:13:50 jsb
54 * Added ip_seqno and ipc_port_set_seqno.
55 * [91/08/09 rpd]
56 * Renamed clport (now ip_norma) fields in struct ipc_port.
57 * [91/08/14 19:31:55 jsb]
58 *
59 * Revision 2.8 91/08/03 18:18:37 jsb
60 * Fixed include. Added clport fields directly to struct ipc_port.
61 * [91/07/17 14:06:25 jsb]
62 *
63 * Revision 2.7 91/06/17 15:46:26 jsb
64 * Renamed NORMA conditionals.
65 * [91/06/17 10:44:06 jsb]
66 *
67 * Revision 2.6 91/05/14 16:35:34 mrt
68 * Correcting copyright
69 *
70 * Revision 2.5 91/02/05 17:23:10 mrt
71 * Changed to new Mach copyright
72 * [91/02/01 15:50:04 mrt]
73 *
74 * Revision 2.4 90/11/05 14:29:39 rpd
75 * Added ipc_port_reference, ipc_port_release.
76 * [90/10/29 rpd]
77 *
78 * Revision 2.3 90/09/28 16:55:18 jsb
79 * Added NORMA_IPC support.
80 * [90/09/28 14:03:58 jsb]
81 *
82 * Revision 2.2 90/06/02 14:51:13 rpd
83 * Created for new IPC.
84 * [90/03/26 21:01:25 rpd]
85 *
86 */
87 /*
88 * File: ipc/ipc_port.h
89 * Author: Rich Draves
90 * Date: 1989
91 *
92 * Definitions for ports.
93 */
94
95 #ifndef _IPC_IPC_PORT_H_
96 #define _IPC_IPC_PORT_H_
97
98 #include <mach_ipc_compat.h>
99 #include <norma_ipc.h>
100
101 #include <mach/boolean.h>
102 #include <mach/kern_return.h>
103 #include <mach/port.h>
104 #include <kern/lock.h>
105 #include <kern/macro_help.h>
106 #include <kern/ipc_kobject.h>
107 #include <ipc/ipc_object.h>
108 #include <ipc/ipc_mqueue.h>
109 #include <ipc/ipc_table.h>
110 #include <ipc/ipc_thread.h>
111
112 /*
113 * A receive right (port) can be in four states:
114 * 1) dead (not active, ip_timestamp has death time)
115 * 2) in a space (ip_receiver_name != 0, ip_receiver points
116 * to the space but doesn't hold a ref for it)
117 * 3) in transit (ip_receiver_name == 0, ip_destination points
118 * to the destination port and holds a ref for it)
119 * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL)
120 *
121 * If the port is active, and ip_receiver points to some space,
122 * then ip_receiver_name != 0, and that space holds receive rights.
123 * If the port is not active, then ip_timestamp contains a timestamp
124 * taken when the port was destroyed.
125 */
126
127 typedef unsigned int ipc_port_timestamp_t;
128
129 typedef struct ipc_port {
130 struct ipc_object ip_object;
131
132 union {
133 struct ipc_space *receiver;
134 struct ipc_port *destination;
135 ipc_port_timestamp_t timestamp;
136 } data;
137 mach_port_t ip_receiver_name;
138
139 ipc_kobject_t ip_kobject;
140
141 mach_port_mscount_t ip_mscount;
142 mach_port_rights_t ip_srights;
143 mach_port_rights_t ip_sorights;
144
145 struct ipc_port *ip_nsrequest;
146 struct ipc_port *ip_pdrequest;
147 struct ipc_port_request *ip_dnrequests;
148
149 struct ipc_pset *ip_pset;
150 mach_port_seqno_t ip_seqno; /* locked by message queue */
151 mach_port_msgcount_t ip_msgcount;
152 mach_port_msgcount_t ip_qlimit;
153 struct ipc_mqueue ip_messages;
154 struct ipc_thread_queue ip_blocked;
155
156 #if NORMA_IPC
157 unsigned long ip_norma_uid;
158 unsigned long ip_norma_dest_node;
159 long ip_norma_stransit;
160 long ip_norma_sotransit;
161 long ip_norma_xmm_object_refs;
162 boolean_t ip_norma_is_proxy;
163 boolean_t ip_norma_is_special;
164 struct ipc_port *ip_norma_atrium;
165 struct ipc_port *ip_norma_queue_next;
166 struct ipc_port *ip_norma_xmm_object;
167 struct ipc_port *ip_norma_next;
168 long ip_norma_spare1;
169 long ip_norma_spare2;
170 long ip_norma_spare3;
171 long ip_norma_spare4;
172 #endif NORMA_IPC
173 } *ipc_port_t;
174
175 #define ip_references ip_object.io_references
176 #define ip_bits ip_object.io_bits
177 #define ip_receiver data.receiver
178 #define ip_destination data.destination
179 #define ip_timestamp data.timestamp
180
181 #define IP_NULL ((ipc_port_t) IO_NULL)
182 #define IP_DEAD ((ipc_port_t) IO_DEAD)
183
184 #define IP_VALID(port) IO_VALID(&(port)->ip_object)
185
186 #define ip_active(port) io_active(&(port)->ip_object)
187 #define ip_lock_init(port) io_lock_init(&(port)->ip_object)
188 #define ip_lock(port) io_lock(&(port)->ip_object)
189 #define ip_lock_try(port) io_lock_try(&(port)->ip_object)
190 #define ip_unlock(port) io_unlock(&(port)->ip_object)
191 #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object)
192 #define ip_reference(port) io_reference(&(port)->ip_object)
193 #define ip_release(port) io_release(&(port)->ip_object)
194
195 #define ip_alloc() ((ipc_port_t) io_alloc(IOT_PORT))
196 #define ip_free(port) io_free(IOT_PORT, &(port)->ip_object)
197
198 #define ip_kotype(port) io_kotype(&(port)->ip_object)
199
200 typedef ipc_table_index_t ipc_port_request_index_t;
201
202 typedef struct ipc_port_request {
203 union {
204 struct ipc_port *port;
205 ipc_port_request_index_t index;
206 } notify;
207
208 union {
209 mach_port_t name;
210 struct ipc_table_size *size;
211 } name;
212 } *ipc_port_request_t;
213
214 #define ipr_next notify.index
215 #define ipr_size name.size
216
217 #define ipr_soright notify.port
218 #define ipr_name name.name
219
220 #define IPR_NULL ((ipc_port_request_t) 0)
221
222 #if MACH_IPC_COMPAT
223 /*
224 * For backwards compatibility, the ip_pdrequest field can hold a
225 * send right instead of a send-once right. This is indicated by
226 * the low bit of the pointer. This works because the zone package
227 * guarantees that the two low bits of port pointers are zero.
228 */
229
230 #define ip_pdsendp(soright) ((unsigned int)(soright) & 1)
231 #define ip_pdsend(soright) ((ipc_port_t)((unsigned int)(soright) &~ 1))
232 #define ip_pdsendm(sright) ((ipc_port_t)((unsigned int)(sright) | 1))
233
234 /*
235 * For backwards compatibility, the ipr_soright field can hold
236 * a space pointer. This is indicated by the low bit of the pointer.
237 * This works because the zone package guarantees that the two low
238 * bits of port and space pointers are zero.
239 */
240
241 #define ipr_spacep(soright) ((unsigned int)(soright) & 1)
242 #define ipr_space(soright) ((ipc_space_t)((unsigned int)(soright) &~ 1))
243 #define ipr_spacem(space) ((ipc_port_t)((unsigned int)(space) | 1))
244 #endif MACH_IPC_COMPAT
245
246 /*
247 * Taking the ipc_port_multiple lock grants the privilege
248 * to lock multiple ports at once. No ports must locked
249 * when it is taken.
250 */
251
252 decl_simple_lock_data(extern, ipc_port_multiple_lock_data)
253
254 #define ipc_port_multiple_lock_init() \
255 simple_lock_init(&ipc_port_multiple_lock_data)
256
257 #define ipc_port_multiple_lock() \
258 simple_lock(&ipc_port_multiple_lock_data)
259
260 #define ipc_port_multiple_unlock() \
261 simple_unlock(&ipc_port_multiple_lock_data)
262
263 /*
264 * The port timestamp facility provides timestamps
265 * for port destruction. It is used to serialize
266 * mach_port_names with port death.
267 */
268
269 decl_simple_lock_data(extern, ipc_port_timestamp_lock_data)
270 extern ipc_port_timestamp_t ipc_port_timestamp_data;
271
272 #define ipc_port_timestamp_lock_init() \
273 simple_lock_init(&ipc_port_timestamp_lock_data)
274
275 #define ipc_port_timestamp_lock() \
276 simple_lock(&ipc_port_timestamp_lock_data)
277
278 #define ipc_port_timestamp_unlock() \
279 simple_unlock(&ipc_port_timestamp_lock_data)
280
281 extern ipc_port_timestamp_t
282 ipc_port_timestamp();
283
284 /*
285 * Compares two timestamps, and returns TRUE if one
286 * happened before two. Note that this formulation
287 * works when the timestamp wraps around at 2^32,
288 * as long as one and two aren't too far apart.
289 */
290
291 #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0)
292
293 #define ipc_port_translate_receive(space, name, portp) \
294 ipc_object_translate((space), (name), \
295 MACH_PORT_RIGHT_RECEIVE, \
296 (ipc_object_t *) (portp))
297
298 #define ipc_port_translate_send(space, name, portp) \
299 ipc_object_translate((space), (name), \
300 MACH_PORT_RIGHT_SEND, \
301 (ipc_object_t *) (portp))
302
303 extern kern_return_t
304 ipc_port_dnrequest(/* ipc_port_t, mach_port_t, ipc_port_t,
305 ipc_port_request_index_t * */);
306
307 extern kern_return_t
308 ipc_port_dngrow(/* ipc_port_t */);
309
310 extern ipc_port_t
311 ipc_port_dncancel(/* ipc_port_t, mach_port_t, ipc_port_request_index_t */);
312
313 #define ipc_port_dnrename(port, index, oname, nname) \
314 MACRO_BEGIN \
315 ipc_port_request_t ipr, table; \
316 \
317 assert(ip_active(port)); \
318 \
319 table = port->ip_dnrequests; \
320 assert(table != IPR_NULL); \
321 \
322 ipr = &table[index]; \
323 assert(ipr->ipr_name == oname); \
324 \
325 ipr->ipr_name = nname; \
326 MACRO_END
327
328 extern void
329 ipc_port_pdrequest(/* ipc_port_t, ipc_port_t, ipc_port_t * */);
330
331 extern void
332 ipc_port_nsrequest(/* ipc_port_t, mach_port_mscount_t,
333 ipc_port_t, ipc_port_t * */);
334
335 extern void
336 ipc_port_set_qlimit(/* ipc_port_t, mach_port_msgcount_t */);
337
338 #define ipc_port_set_mscount(port, mscount) \
339 MACRO_BEGIN \
340 assert(ip_active(port)); \
341 \
342 (port)->ip_mscount = (mscount); \
343 MACRO_END
344
345 extern struct ipc_mqueue *
346 ipc_port_lock_mqueue(/* ipc_port_t */);
347
348 extern void
349 ipc_port_set_seqno(/* ipc_port_t, mach_port_seqno_t */);
350
351 extern void
352 ipc_port_clear_receiver(/* ipc_port_t */);
353
354 extern void
355 ipc_port_init(/* ipc_port_t, ipc_space_t, mach_port_t */);
356
357 extern kern_return_t
358 ipc_port_alloc(/* ipc_space_t, mach_port_t *, ipc_port_t * */);
359
360 extern kern_return_t
361 ipc_port_alloc_name(/* ipc_space_t, mach_port_t, ipc_port_t * */);
362
363 extern void
364 ipc_port_destroy(/* ipc_port_t */);
365
366 extern boolean_t
367 ipc_port_check_circularity(/* ipc_port_t, ipc_port_t */);
368
369 extern ipc_port_t
370 ipc_port_lookup_notify(/* ipc_space_t, mach_port_t */);
371
372 extern ipc_port_t
373 ipc_port_make_send(/* ipc_port_t */);
374
375 extern ipc_port_t
376 ipc_port_copy_send(/* ipc_port_t */);
377
378 extern mach_port_t
379 ipc_port_copyout_send(/* ipc_port_t, ipc_space_t */);
380
381 extern void
382 ipc_port_release_send(/* ipc_port_t */);
383
384 extern ipc_port_t
385 ipc_port_make_sonce(/* ipc_port_t */);
386
387 extern void
388 ipc_port_release_sonce(/* ipc_port_t */);
389
390 extern void
391 ipc_port_release_receive(/* ipc_port_t */);
392
393 extern ipc_port_t
394 ipc_port_alloc_special(/* ipc_space_t */);
395
396 extern void
397 ipc_port_dealloc_special(/* ipc_port_t */);
398
399 #define ipc_port_alloc_kernel() \
400 ipc_port_alloc_special(ipc_space_kernel)
401 #define ipc_port_dealloc_kernel(port) \
402 ipc_port_dealloc_special((port), ipc_space_kernel)
403
404 #define ipc_port_alloc_reply() \
405 ipc_port_alloc_special(ipc_space_reply)
406 #define ipc_port_dealloc_reply(port) \
407 ipc_port_dealloc_special((port), ipc_space_reply)
408
409 #define ipc_port_reference(port) \
410 ipc_object_reference(&(port)->ip_object)
411
412 #define ipc_port_release(port) \
413 ipc_object_release(&(port)->ip_object)
414
415 #if MACH_IPC_COMPAT
416
417 extern kern_return_t
418 ipc_port_alloc_compat(/* ipc_space_t, mach_port_t *, ipc_port_t * */);
419
420 extern mach_port_t
421 ipc_port_copyout_send_compat(/* ipc_port_t, ipc_space_t */);
422
423 extern mach_port_t
424 ipc_port_copyout_receiver(/* ipc_port_t, ipc_space_t */);
425
426 #endif MACH_IPC_COMPAT
427
428 extern void
429 ipc_port_print(/* ipc_port_t */);
430
431 #if NORMA_IPC
432
433 #define IP_NORMA_IS_PROXY(port) ((port)->ip_norma_is_proxy)
434
435 /*
436 * A proxy never has a real nsrequest, but is always has a fake
437 * nsrequest so that the norma ipc system is notified when there
438 * are no send rights for a proxy. A fake nsrequest is indicated by
439 * the low bit of the pointer. This works because the zone package
440 * guarantees that the two low bits of port pointers are zero.
441 */
442
443 #define ip_nsproxyp(nsrequest) ((unsigned int)(nsrequest) & 1)
444 #define ip_nsproxy(nsrequest) ((ipc_port_t)((unsigned int)(nsrequest) &~ 1))
445 #define ip_nsproxym(proxy) ((ipc_port_t)((unsigned int)(proxy) | 1))
446
447 #endif NORMA_IPC
448
449 #endif _IPC_IPC_PORT_H_
Cache object: c40697a15d78c117be0ed61f82bef829
|