|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * @OSF_COPYRIGHT@
24: */
25: /*
26: * Mach Operating System
27: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
28: * All Rights Reserved.
29: *
30: * Permission to use, copy, modify and distribute this software and its
31: * documentation is hereby granted, provided that both the copyright
32: * notice and this permission notice appear in all copies of the
33: * software, derivative works or modified versions, and any portions
34: * thereof, and that both notices appear in supporting documentation.
35: *
36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39: *
40: * Carnegie Mellon requests users of this software to return to
41: *
42: * Software Distribution Coordinator or [email protected]
43: * School of Computer Science
44: * Carnegie Mellon University
45: * Pittsburgh PA 15213-3890
46: *
47: * any improvements or extensions that they make and grant Carnegie Mellon
48: * the rights to redistribute these changes.
49: */
50: /*
51: */
52: /*
53: * File: ipc/ipc_object.h
54: * Author: Rich Draves
55: * Date: 1989
56: *
57: * Definitions for IPC objects, for which tasks have capabilities.
58: */
59:
60: #ifndef _IPC_IPC_OBJECT_H_
61: #define _IPC_IPC_OBJECT_H_
62:
63: #include <dipc.h>
64: #include <mach_rt.h>
65: #include <cpus.h>
66: #include <mach_kdb.h>
67:
68: #include <mach/kern_return.h>
69: #include <mach/message.h>
70: #include <kern/lock.h>
71: #include <kern/macro_help.h>
72: #include <kern/thread_pool.h>
73: #include <kern/zalloc.h>
74: #include <ipc/ipc_types.h>
75:
76: typedef natural_t ipc_object_refs_t; /* for ipc/ipc_object.h */
77: typedef natural_t ipc_object_bits_t;
78: typedef natural_t ipc_object_type_t;
79:
80: /*
81: * There is no lock in the ipc_object; it is in the enclosing kernel
82: * data structure (rpc_common_data) used by both ipc_port and ipc_pset.
83: * The ipc_object is used to both tag and reference count these two data
84: * structures, and (Noto Bene!) pointers to either of these or the
85: * ipc_object at the head of these are freely cast back and forth; hence
86: * the ipc_object MUST BE FIRST in the ipc_common_data.
87: *
88: * If the RPC implementation enabled user-mode code to use kernel-level
89: * data structures (as ours used to), this peculiar structuring would
90: * avoid having anything in user code depend on the kernel configuration
91: * (with which lock size varies).
92: */
93: struct ipc_object {
94: ipc_object_refs_t io_references;
95: ipc_object_bits_t io_bits;
96: port_name_t io_receiver_name;
97: struct thread_pool io_thread_pool;
98: #if DIPC && NCPUS == 1
99: usimple_lock_data_t io_lock_data;
100: #else
101: decl_mutex_data(, io_lock_data)
102: #endif
103: };
104:
105: /*
106: * Legacy defines. Should use IPC_OBJECT_NULL, etc...
107: */
108: #define IO_NULL ((ipc_object_t) 0)
109: #define IO_DEAD ((ipc_object_t) -1)
110: #define IO_VALID(io) (((io) != IO_NULL) && ((io) != IO_DEAD))
111:
112: /*
113: * IPC steals the high-order bits from the kotype to use
114: * for its own purposes. This allows IPC to record facts
115: * about ports that aren't otherwise obvious from the
116: * existing port fields. In particular, IPC can optionally
117: * mark a port for no more senders detection. Any change
118: * to IO_BITS_PORT_INFO must be coordinated with bitfield
119: * definitions in ipc_port.h.
120: */
121: #define IO_BITS_PORT_INFO 0x0000f000 /* stupid port tricks */
122: #define IO_BITS_KOTYPE 0x00000fff /* used by the object */
123: #define IO_BITS_OTYPE 0x7fff0000 /* determines a zone */
124: #define IO_BITS_ACTIVE 0x80000000 /* is object alive? */
125:
126: #define io_active(io) ((io)->io_bits & IO_BITS_ACTIVE)
127:
128: #define io_otype(io) (((io)->io_bits & IO_BITS_OTYPE) >> 16)
129: #define io_kotype(io) ((io)->io_bits & IO_BITS_KOTYPE)
130:
131: #define io_makebits(active, otype, kotype) \
132: (((active) ? IO_BITS_ACTIVE : 0) | ((otype) << 16) | (kotype))
133:
134: /*
135: * Object types: ports, port sets, kernel-loaded ports
136: */
137: #define IOT_PORT 0
138: #define IOT_PORT_SET 1
139: #define IOT_NUMBER 2 /* number of types used */
140:
141: extern zone_t ipc_object_zones[IOT_NUMBER];
142:
143: #define io_alloc(otype) \
144: ((ipc_object_t) zalloc(ipc_object_zones[(otype)]))
145:
146: #if DIPC || MACH_ASSERT
147: /*
148: * DIPC must intercept the call to deallocate the IPC
149: * object in case the object in question is a port with
150: * a dipc_port extension.
151: */
152: extern void io_free(
153: unsigned int otype,
154: ipc_object_t object);
155:
156: #else /* DIPC || MACH_ASSERT */
157: #define io_free(otype, io) \
158: zfree(ipc_object_zones[(otype)], (vm_offset_t) (io))
159: #endif /* DIPC || MACH_ASSERT */
160:
161: /*
162: * Here we depend on the ipc_object being first within the ipc_common_data,
163: * which is first within the rpc_common_data, which in turn must be first
164: * within any kernel data structure needing to lock an ipc_object
165: * (ipc_port and ipc_pset).
166: */
167: #if DIPC && NCPUS == 1
168:
169: #define io_lock_init(io) \
170: usimple_lock_init(&(io)-io_lock_data, ETAP_IPC_OBJECT)
171: #define io_lock(io) \
172: usimple_lock(&(io)->io_lock_data)
173: #define io_lock_try(io) \
174: usimple_lock_try(&(io)->io_lock_data)
175: #define io_unlock(io) \
176: usimple_unlock(&(io)->io_lock_data)
177:
178: #else /* DIPC && NCPUS == 1 */
179:
180: #define io_lock_init(io) \
181: mutex_init(&(io)->io_lock_data, ETAP_IPC_OBJECT)
182: #define io_lock(io) \
183: mutex_lock(&(io)->io_lock_data)
184: #define io_lock_try(io) \
185: mutex_try(&(io)->io_lock_data)
186: #define io_unlock(io) \
187: mutex_unlock(&(io)->io_lock_data)
188:
189: #endif /* DIPC && NCPUS == 1 */
190:
191: #if NCPUS > 1
192: #define _VOLATILE_ volatile
193: #else /* NCPUS > 1 */
194: #define _VOLATILE_
195: #endif /* NCPUS > 1 */
196:
197: #define io_check_unlock(io) \
198: MACRO_BEGIN \
199: _VOLATILE_ ipc_object_refs_t _refs = (io)->io_references; \
200: \
201: io_unlock(io); \
202: if (_refs == 0) \
203: io_free(io_otype(io), io); \
204: MACRO_END
205:
206: /* Sanity check the ref count. If it is 0, we may be doubly zfreeing.
207: * If it is larger than max int, it has been corrupted, probably by being
208: * modified into an address (this is architecture dependent, but it's
209: * safe to assume there cannot really be max int references).
210: *
211: * NOTE: The 0 test alone will not catch double zfreeing of ipc_port
212: * structs, because the io_references field is the first word of the struct,
213: * and zfree modifies that to point to the next free zone element.
214: */
215: #define IO_MAX_REFERENCES \
216: (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1)))
217:
218: #define io_reference(io) \
219: MACRO_BEGIN \
220: assert((io)->io_references < IO_MAX_REFERENCES); \
221: (io)->io_references++; \
222: MACRO_END
223:
224: #define io_release(io) \
225: MACRO_BEGIN \
226: assert((io)->io_references > 0 && \
227: (io)->io_references <= IO_MAX_REFERENCES); \
228: (io)->io_references--; \
229: MACRO_END
230:
231: /*
232: * Exported interfaces
233: */
234:
235: /* Take a reference to an object */
236: extern void ipc_object_reference(
237: ipc_object_t object);
238:
239: /* Release a reference to an object */
240: extern void ipc_object_release(
241: ipc_object_t object);
242:
243: /* Look up an object in a space */
244: extern kern_return_t ipc_object_translate(
245: ipc_space_t space,
246: mach_port_name_t name,
247: mach_port_right_t right,
248: ipc_object_t *objectp);
249:
250: /* Allocate a dead-name entry */
251: extern kern_return_t
252: ipc_object_alloc_dead(
253: ipc_space_t space,
254: mach_port_name_t *namep);
255:
256: /* Allocate a dead-name entry, with a specific name */
257: extern kern_return_t ipc_object_alloc_dead_name(
258: ipc_space_t space,
259: mach_port_name_t name);
260:
261: /* Allocate an object */
262: extern kern_return_t ipc_object_alloc(
263: ipc_space_t space,
264: ipc_object_type_t otype,
265: mach_port_type_t type,
266: mach_port_urefs_t urefs,
267: mach_port_name_t *namep,
268: ipc_object_t *objectp);
269:
270: /* Allocate an object, with a specific name */
271: extern kern_return_t ipc_object_alloc_name(
272: ipc_space_t space,
273: ipc_object_type_t otype,
274: mach_port_type_t type,
275: mach_port_urefs_t urefs,
276: mach_port_name_t name,
277: ipc_object_t *objectp);
278:
279: /* Convert a send type name to a received type name */
280: extern mach_msg_type_name_t ipc_object_copyin_type(
281: mach_msg_type_name_t msgt_name);
282:
283: /* Copyin a capability from a space */
284: extern kern_return_t ipc_object_copyin(
285: ipc_space_t space,
286: mach_port_name_t name,
287: mach_msg_type_name_t msgt_name,
288: ipc_object_t *objectp);
289:
290: /* Copyin a naked capability from the kernel */
291: extern void ipc_object_copyin_from_kernel(
292: ipc_object_t object,
293: mach_msg_type_name_t msgt_name);
294:
295: /* Destroy a naked capability */
296: extern void ipc_object_destroy(
297: ipc_object_t object,
298: mach_msg_type_name_t msgt_name);
299:
300: /* Copyout a capability, placing it into a space */
301: extern kern_return_t ipc_object_copyout(
302: ipc_space_t space,
303: ipc_object_t object,
304: mach_msg_type_name_t msgt_name,
305: boolean_t overflow,
306: mach_port_name_t *namep);
307:
308: /* Copyout a capability with a name, placing it into a space */
309: extern kern_return_t ipc_object_copyout_name(
310: ipc_space_t space,
311: ipc_object_t object,
312: mach_msg_type_name_t msgt_name,
313: boolean_t overflow,
314: mach_port_name_t name);
315:
316: /* Translate/consume the destination right of a message */
317: extern void ipc_object_copyout_dest(
318: ipc_space_t space,
319: ipc_object_t object,
320: mach_msg_type_name_t msgt_name,
321: mach_port_name_t *namep);
322:
323: /* Rename an entry in a space */
324: extern kern_return_t ipc_object_rename(
325: ipc_space_t space,
326: mach_port_name_t oname,
327: mach_port_name_t nname);
328:
329: #if MACH_RT
330: /* Determine if an object is real-time */
331: extern boolean_t ipc_object_is_rt(
332: ipc_object_t object);
333: #endif /* MACH_RT */
334:
335: #if MACH_KDB
336: /* Pretty-print an ipc object */
337:
338: extern void ipc_object_print(
339: ipc_object_t object);
340:
341: #endif /* MACH_KDB */
342:
343: #endif /* _IPC_IPC_OBJECT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.