Annotation of XNU/osfmk/ipc/ipc_object.h, revision 1.1

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_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.