|
|
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.